简体   繁体   中英

Stripe payment intent remains incomplete with 3D Secure

I'm trying to implement 3D Secure in my web app. It works perfectly well with a SEPA debit and a card debit that doesn't need 3D Secure. However, with a card that requires 3D Secure, the payment remains in the Incomplete state in Stripe dashboard.

My product is an annual subscription.

First I create a payment intent on the server ( https://stripe.com/docs/api/payment_intents/create ) and I send the client secret in the HTTP response.

List<Object> paymentMethodTypes = new ArrayList<>();
paymentMethodTypes.add("card");
paymentMethodTypes.add("sepa_debit");
Map<String, Object> params = new HashMap<>();
params.put("amount", 2000);
params.put("currency", "eur");
params.put(
  "payment_method_types",
  paymentMethodTypes
);

PaymentIntent paymentIntent = PaymentIntent.create(params);

After that, I use stripe.confirmCardSetup on the frontend with the clientSecret and with the card element and I send the payment method to my backend.

const response = await stripe.confirmCardSetup(clientSecret, {
    payment_method: {
        card: elements.getElement(CardElement)
    }
})

await setDefaultPaymentMethod(payload?.setupIntent?.payment_method);

Then I retrieve the payment method and attach it to the customer and I finally create the subscription as shown in Stripe examples ( https://stripe.com/docs/billing/subscriptions/examples ).

PaymentMethod paymentMethod = PaymentMethod.retrieve(
    "pm_***"
  );

Map<String, Object> params = new HashMap<>();
params.put(
  "customer",
  "clg_***"
);

PaymentMethod updatedPaymentMethod = paymentMethod.attach(params);


// Create subscription

It does display the 3D Secure authentication modal on the frontend. However, at the end of the whole process (after creating the subscription on the backend), card payment that requires 3D Secure remains in Incomplete state. Can anyone point me to the right direction to implement 3D Secure correctly?

进入未完成状态的订阅

Which test card are you using to test your integration? For instance the 4000 0027 6000 3184 card will require 3DS confirmation regardless of whether the card was previously set up using a SetupIntent. You probably want to use the 4000 0025 0000 3155 card to test SetupIntents .

Saying that, SetupIntents in this scenario are usually only used for subscriptions that have a trial period. The idea being that you authenticate the card now so it can be charged at a later date without requiring 3DS authorisation. If you are creating subscriptions without a trial period, then you should create the subscription with the payment method and handle any 3DS actions if required while your user is "on-session".

If you are creating subscriptions without a customer session, remember to include off_session: true , when creating the subscription:

Example:

const subscription = await stripe.subscriptions.create({
    customer: customerId,
    off_session : true,
    items: [
        { price: priceId }, 
    ],
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM