How to set up off session payments with Stripe and 3D secure? - stripe-payments

I have a website similar to TaskRabbit (employers hire employees). I'm trying to figure out how to set up payments to work with 3D secure - even though I'm in the United States and I don't think that many cards require it.
The payment flow is
Employers go to the Stripe hosted Customer portal to enter their payment method, and if they need authentication when entering a 3D secure card, Stripe will handle that there
Employers will bid on shifts for Employees. Since multiple bids may be needed and not all bids would be accepted by the employee, I don't have any payment processing done at this stage
Employee accepts a bid. Now using the stored payment method, an off session Payment Intent is created. PaymentIntent looks like this
curl https://api.stripe.com/v1/payment_intents
-d amount=1000
-d currency=usd
-d customer = cus_ABCDEFGHIJKLMNOP
-d automatic_payment_methods[enabled] = true
-d payment_method = pm_1MYlwuGbdc
-d confirm = true
-d transfer_data[destination] = acct_1MVqZx2eFvmfdu
-d off_session = true
-d transfer_data[amount] = 100
And this works for a few test cards in Stripe but not for this one for example:
This card requires authentication on all transactions, regardless of how the card is set up.
Right now my website is not live. How likely am I to encounter problems in the US with 3D secure? Is my payment flow going to be possible (the main thing is I don't want the employer having to go through a Checkout process)

When you collect payment method details at first, you should use the Setup Intents API to properly set up the payment method for future use. For card payments for example you will be able to have your customer go through 3D Secure if it's required.
After the SetupIntent succeeds, you will get a PaymentMethod pm_123 attached to your customer which you can use on future payments either on or off session.
Now, even if the card is set up properly, it's still possible that the bank will decline the payment. It might be because they want the cardholder to go through 3D Secure again, but it might simply be that they have insufficient funds or any other reason.
When that happens, your code should handle the payment failure and get your customer back on session to enter new payment method details. It might be a new card, or the existing one but they go through 3D Secure again. And that payment can still fail, the same as any payment.
Finally, the test card you are using was explicitly built by Stripe to always require 3DS. It's not really something most banks would do, it's just an easy card to use for forcing any transaction to require 3DS in Test mode. But ultimately, it'd work the same as any decline: you get the customer back "on session" on your website/app and you confirm that PaymentIntent client-side instead.

Related

How to add credit card using Braintree Hosted Fields with 3D Secure verification

I have a credit card addition as a separate step in the flow. That means I'm creating credit cards via Braintree Hosted Fields without running a transaction. To use vaulted credit cards for future transactions.
As I understand it right (correct me if I'm wrong), I can and should verify credit cards on their creation by running 3d Secure verification.
There are two things I'm not sure about:
Should I even run 3d Secure verification when adding a credit card?
If yes, what should be passed in the threeDSecureParams.amount (cause eventually, the amount is set between $0 and $1 by the 3D Secure processor)?
threeDSecureParams = {
cardAddChallengeRequested: true,
bin: tokenizeData.details.bin,
email: email,
nonce: tokenizeData.nonce,
amount: 1
}
P.S. As I didn't find a clear answer in the Braintree doc and by googling, while I'm waiting for Braintree support to get a reply on this, I've decided to see how you guys managed to set such flow.
I really appreciate any help/opinion.

How to handle Stripe 3D Secure when creating a PaymentMethod on the client for multiple charges on the server

In my marketplace I have a requirement to:
Have a customer enter their card details
Once card details are submitted, process multiple charges against that card on the server side
I'm using stripe.js and creating a PaymentMethod on the client side using stripe.createPaymentMethod()
The ID of the PaymentMethod is posted to the server, which then does the following via the Stripe API library for PHP:
Retrieves the PaymentMethod from Stripe using the posted ID
Creates a Customer on Stripe, specifying the 'payment_method'
Creates multiple PaymentIntents, specifying the 'payment_method', the 'customer', 'save_payment_method' as true and 'confirm' as true.
I'm now wanting to handle scenarios where Stripe requires the use of 3D Secure.
Is there any way that 3D Secure verification can take place on the client, prior to the request to the server, whilst using stripe.createPaymentMethod() ?
If not, what alternative do I have?
It seems that a user completing the 3D Secure steps returns only a PaymentIntent. I don't believe I'm able to use this to make multiple charges against the card. This is whole reason for using createPaymentMethod() on the client in the first place.
Any ideas on how to go about this?
Is there any way that 3D Secure verification can take place on the client, prior to the request to the server, whilst using stripe.createPaymentMethod() ?
The approach to handle 3D Secure authentication on the client is to either use the confirmCardPayment [0] or handleCardAction [1] methods on Stripe.js. Unless you have specific needs, you would most likely want to use confirmCardPayment and follow this guide here:
https://stripe.com/docs/payments/accept-a-payment
I should note, that both these methods only work to process one payment at a time. In your case, you have multiple payment intents, so you would need to call either of the methods once per transaction. That is, if you have three payment intents you would need to call confirmCardPayment three times, repeating the last step in the guide [2] that many times as well.
This means that it is technically possible (but unlikely) that your users may have to authenticate multiple times to process each of their payments.
Unfortunately, there are really no workarounds for this. Even if you were to setup a user's card with SetupIntents [3] and charge them off-session at a later date, there is still a risk that you would need to bring user's back on-session to authenticate each individual payment intent.
All this being said, the majority of your users probably won't run into a scenario where they would need to authenticate multiple times in a row.
The only other option would be to create a single payment intent that covers the full cost of your product/service, which would allow you to call confirmCardPayment just once.
[0] https://stripe.com/docs/js/payment_intents/confirm_card_payment
[1] https://stripe.com/docs/js/payment_intents/handle_card_action
[2] https://stripe.com/docs/payments/accept-a-payment#web-submit-payment
[3] https://stripe.com/docs/payments/save-and-reuse

Question related to stripe connect, card tokenization process and customer generate process

Before you ask for some code, understand that this question is about the implementation technique than code mongering.
OK, so in order to save a customer in stripe connect to charge them later or monthly, here is the prescribed process:
step 1. Use Stripe.js to get card details of the user such as card numbr, exp date, cvv etc. which will be sent to stripe.
step 2. Stripe returns a token corresponding to the card like: tok_xyz, now this token can be used to generate a customer in Stripe and you will get customer id.
step 3. Once you have customer id, you can charge them anytime.
Now I have two questions:
If I provide same card details in the step 1 above, will strip return same token everytime? I am asking it so that I may know how to handle the condition when a user enters same card details twice and I don't accidentally create multiple entries in the database for same card again and again.
It's documented in Stripe that after they issue card token (step 1 above) the CVV remains valid only for few minutes and if you don't make a charge in that time, later on the card will become invalid so do I need to charge the customer right away with a small amount like 0.01$ or something? or when I create customer (step 2 above), stripe takes care of that?
Thank you for any help in advance.
No, you will get a different token and tok_xxx ID value every time. However, there is a fingerprint property you can read from the token and compare to cards saved to the customer, to check for duplicates. There are some good answers on StackOverflow showing examples of that.
True, the CVC value is only held for a short amount of time. If you make a charge during that time, it can be checked by the bank. Creating a charge outside that time doesn't make the card invalid, but it will likely lead to more chance of a decline. Luckily this isn't an issue — when you create a customer object Stripe performs a $0 authorisation charge(as described in the blue box here). So as long as you either charge the token directly, or use it to create a customer object, as soon as you get it, you don't need to think about this.

Stripe token - why isn't data-amount included in the token

I've been playing with stripe recently and while i fully understand that the token hides the clients credit card details from the server. This tutorial suggests that the server should not rely on the data-amount since it can be changed by the client
Don’t Rely on the Form’s Price
A frequent mistake stems from using form data to contain the price of
the product being purchased, possibly via a hidden input. Because a
user can easily edit this input’s value, it’s unwise to depend on it.
Always fetch the price of the product from the server-side. Never rely
on the form to tell you. A simple database query is the preferred option.
Can someone explain to be why stripe does not include the data-amount value as a parameter in the token generation? Is there not a potential for a server side code to change the agreed price and overcharge the client.
The token is a placeholder of a pending charge, it does not know how much you are going to charge yet. Once you are ready to charge the card an api request will be sent to Stripe along with the token. The concern about the amount deals with relying on POST data from a form that can be manipulated by the customer.
Its up to you to set the charge amount. For example a hotel could authorize $100 to spend the night but then at check out discover that you used the minibar and then charge $150. Or the auto calculated shipping is off so when you actually purchase the shipping its $5 less and you decide to charge $5 less than your auth.
What you should be doing is calculating the amount to charge the customer, save it via a shopping cart like function in your DB (or serverside somehow) sending the checkout form to the customer then using the previously calculated amount run the auth then the charge.
Form data can easily be changed by the end user. Just open the page and right click (in chrome) and click inspect element. You can then arbitrarily change form data. So if you were using that, the user could set the price to $.01 for your $1,000.00 product.
The propose of tokenization in the PCI world is to keep sensitive data off your servers. Otherwise you would collect the PCI data yourself then send the amount off to the processor along with the PCI data. By not ever having the sensitive data touch your systems you save a ton of money and headache in PCI compliance. See this 115 page document: https://www.pcisecuritystandards.org/documents/PCI_DSS_v3-1.pdf
Hope that helps, Please comment and I'll try to help further if it doesn't.

Send Stripe Notification when Credit Card is about to expire

Is there a way in Stripe to automatically send an email to a customer when their credit card is about to expire?
Great news! There shouldn't be a need to notify the customer about expiration dates (or even replacement cards). Stripe's system automatically handles these changes with Smarter saved cards:
Now, when you save a customer with Stripe, their card will continue to work even if the physical card gets replaced by the bank. Stripe works directly with card networks so that your customers can continue using your service without interruption.
This feature started in early 2015, according to the article's date of 2015-01-21.
In the sense you're looking for the answer is likely no. If you're willing to pay for it, something like Stunning can do this for you. Otherwise I think you'd need to setup something on your system to periodically cycle through your customer database and ping Stripe about the status of any credit cards they have on file to see if any are expiring soon.
As Tyler mentioned, Stripe's Card Updater has changed the game when it comes to expired cards.
However, it won't automatically catch 100% of expiring cards. At best, maybe around 70%, as some international territories and card issuers are not yet covered.
Even so, this has made pre-dunning emails (notifying customers before their card expires) obsolete in the best case, and actively harmful in the worst case...triggering "payment problem" notifications to customers who will never actually have a payment problem. These notifications can burden support teams and cause unnecessary customer involvement & confusion.
If you decide not to send pre-dunning emails (we don't), you definitely do need to send dunning emails (when payments actually do fail) which will catch actual, expired cards missed by Card Updater, as well as other kinds of failures that couldn't have been caught by Card Updater.
This Stripe dunning checklist is useful in building the optimal system on top of Stripe.
Actually, now in stripe settings, you could set up the simple reminder email before the card expiration. It's inside Settings -> Prevent failed payments
No there is no such way. Stunning as mentioned by Dhaulagiri sure is a solution but its not free.
A simple alternative is:
When taking the card info by the users for the first time, add the
field for expiry date (stripe provides validation for it too).
Keep checking the card's expiry date at regular intervals (say
monthly or at the time of charging).
If the card is about to expire (in say a month or by the time of
next charge) handle that case to notify your customer.

Resources