(SCA) Strong Customer Authentication with Stripe — PSD2 | 3DS2 (paymentIntents process)

According integration needs an important update as part of the second Payment Services Directive(PSD2).

3DS2 Secure is like the project manager of online payments. For extra fraud protection, 3D Secure requires customers to complete an additional verification step with the card issuer when paying.


Specific types of low-risk payments may be exempted. But at the end the cardholder’s bank ultimately decide.

A new step in the payment flow

Key-feature: 3D Secure 2. New authentication standard to provide added security to online payments

Different choices, based on your needs. One-time payment?
Automatic or manual confirmation?

let me explain:-
Payments < 30$
If transaction < $30 will be considered ‘low value’ and may be exempted.

Fixed-amount subscriptions
In this user can recurring payments, with same amount & with same business.

Merchant initiated transaction
payments made with saved cards when the customer is not present in the checkout flow. Fall outside the scope of SCA. Similar to requesting an exemption.

Trusted beneficiaries
When completing authentication for a payments, customer may have the options to whitelist a business.

additional payment steps

In this step user have to enters card details and submits the form.

Stripe detects whether auth is needed. In such a case,3DS2 will be used to proceed.

3D Secure 2 (3DS2)
Additional payment steps

In additional payment steps authentication have multiple types. eg. Pin/Password, fingerprint/face.

Implementation of Stripe 3DS2 System

First need to create PaymentIntent objects. you can read more about the different payment flows available via the payment Intents API here :-

# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://dashboard.stripe.com/apikeys
Stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
intent = Stripe::PaymentIntent.create({
amount: 1099,
currency: 'usd',
payment_method_types: ['card'],

Confirm the paymentIntent from the server

intent = Stripe::PaymentIntent.confirm(
return_url: 'https://example.com/return_url',

Check the paymentIntent status
402 HTTP status code means request failed,meaning that the payment was unsuccessful.
200 HTTP status code means payment completed.

Testing the 3D Secure Flow
Use a Stripe test card with any CVC, postal code, and future expiration date to trigger 3DS authentication challenge flows while in test mode.

When you build an integration with your test API keys, the authentication process displays a mock authentication page. In that page, you can either authorize or cancel the payment. Authorizing the payment simulates successful authentication and redirects you to the specified return URL. Clicking on the Failure button simulates an unsuccessful attempt at authentication.

Miracale happens here.