How to handle recurring payments that require 3D secure scan in Stripe?

874 Views Asked by At

I am trying to integrate subscriptions into a platform. Each customer has 2 subscriptions, one is the main plan subscription and the other is a usage based subscription. The products they contain have different time ranges so they can not be included inside the same subscription. The plan subscription has products with standard pricing, and the overages subscription has products with graduated pricing scheme. This is just some background on how we are trying to use Stripe.

We first collect customer's payment details and set them up for future usage using this guide: https://stripe.com/docs/payments/save-and-reuse?platform=web&locale=en-GB. In the end we attach the payment method to the customer and set it up as the default payment method.

After collecting payment information, when the user clicks subscribe we create those 2 stripe subscriptions we need like so:

const [planSubscription, overagesSubscription] = await Promise.all([
      stripe.subscriptions.create({
        customer: customer.id,
        off_session: true,
        items: [
          {
            price: planConfig.main_plan_price,
          },
        ],
      }),
      stripe.subscriptions.create({
        customer: customer.id,
        off_session: true,
        items: [
          {
            price: planConfig.events_overage_price,
          },
          {
            price: planConfig.domains_overage_price,
          },
        ],
      }),
    ]);

This creates the 2 subscriptions, however when the payment is attempted afterwards by Stripe it fails with a 3D secure error, so the subscription's status changes to incomplete or past_due. This happens with real cards as well.

Is there any way to save 3DS information and reuse it when stripe attempts payments on payment intents created by this subscription?

We also have Radar rules on stripe to trigger 3DS on all cards that support 3DS, but that is not getting triggered either when a user adds a card on Stripe checkout. Any idea what might be related to this as well?

1

There are 1 best solutions below

1
Pompey On

It is ultimately up to the issuing bank to decide when 3DS is requested. Performing 3DS properly on the first payment makes it much less likely that the bank will request 3DS again, but they always might. So it is important to be able to handle 3DS on recurring payments, even if you handled it on the first payment.

To handle 3DS on subscriptions, you should listen for invoice.payment_action_required or payment_intent.action_required events[1]. Once you get that event, you can present the user with a 3DS dialogue on your page[2] or you can send them to the payment's hosted invoice page[3] to complete the 3DS auth.

That all being said, if you are seeing this in test mode, it is likely because of the test card that you are using[4]:

  • 4000002500003155 - Ask for 3DS until the first setup is performed properly
  • 4000002500003155 - Always ask for 3DS (you are likely using this one)

[1] https://stripe.com/docs/billing/subscriptions/overview#requires-action

[2] https://stripe.com/docs/payments/3d-secure#when-to-use-3d-secure

[3] https://stripe.com/docs/invoicing/hosted-invoice-page

[4] https://stripe.com/docs/testing#regulatory-cards