3Ds authentication with Stripe
I’ve been working with Stripe for a good few years now and I thought that I’ve seen it all especially when it comes to cards and elements implementation.
Well, I haven’t just recently I’ve stumbled upon the cases of these types of authentication with Stripe elements.
“3D Secure (3DS) is an authentication protocol that adds an additional security layer to card transactions. By verifying that the person making a purchase is the legitimate cardholder, 3DS helps protect both your business and your customers from fraudulent activity.”
Having an implementation of Stripe Elements I thought I’ve covered those cases, but that wasn’t it, when I tried with a few of the stripes test cards which requires such confirmation…well it did not went good…
After some further research I’ve found out that in order to prompt such confirmation an additional code should be added in my case to the functionality where I was saving card’s data.
Previously I was creating new payment method:
stripe.createPaymentMethod({
type: 'card',
card: cardElement,
billing_details: {
name: cardHolderName
}
})If the request is successful taking the payment_method from the response and attaching it, to the customer and that was about it.
But now I needed to confirm the payment method while creating it, so now I need to use:
stripe.confirmCardSetup(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {name: cardHolderName},
},
})Now it uses confirmCardSetup method to confirm the card if required and then to create the payment method from it.
client_secret is coming from a SetupIntent object which you can create in two ways:
Creating it directly from a user
$intent = $user->createSetupIntent([
'payment_method_types' => ['card', 'cashapp'],
]);or you call the Stripe API directly:
$stripe = new StripeClient(<your-stripe-secret-here>);
$intent = $stripe->setupIntents->create([
'payment_method_types' => [
'card', 'cashapp'
]
]);in both cases you will receive a SetupIntent object:
{
"id": "seti_1Mm8s8LkdIwHu7ix0OXBfTRG",
"object": "setup_intent",
"application": null,
"cancellation_reason": null,
"client_secret": "seti_1Mm8s8LkdIwHu7ix0OXBfTRG_secret_NXDICkPqPeiBTAFqWmkbff09lRmSVXe",
"created": 1678942624,
"customer": null,
"description": null,
"flow_directions": null,
"last_setup_error": null,
"latest_attempt": null,
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"on_behalf_of": null,
"payment_method": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "requires_payment_method",
"usage": "off_session"
}It provides the same information with the addition of a pop-up(in testing environment):

which emulates the 3DS confirmation.
A few words on the cards with which you can test with
You can find them here , let’s dig in:
4000 0025 0000 3155 — requires confirmation for
of-sessionpayments unless you set it up allon-sessionpayments require confirmation4000 0027 6000 3184 — always require confirmation for
off-sessionandon-sessionpayments4000 0038 0000 0446 — already set up for
of-sessionpaymentsone-timepayments andon-sessionpayment require confirmation4000 0082 6000 3178 — require confirmation but fails with
insufficient-fundsalways
I had some mishaps with them cards (always read the description carefully before start testing!) in the end I had more success with the third one because I had more of-session payments
On session and of session payments
From what I was told by one of Stripe’s support agents, on session payments are those when the client is in your checkout flow of session payments are when payments are initiated automatically.
on-session— Subscription Creation, Update, Downgrade from your website interfaceof-session— the payments for subscription renewal
Better and more detailed explanation about it you can read here
So that was my take on the topic, one more thing: There is always more things to learn for any topic
Conclusion
The 3DS auth is strong way of protecting people with payments in internet, more commonly used by bank institutions across the EU it's still something worth your while.
Share this post