9
votes

I am working on the implementing Subscription*(which is SCA ready) using Stripe. I try to handle https://stripe.com/docs/billing/subscriptions/payment#handling-action-required. After the subscription is created on Stripe side, I have got the answer like in documentation above:

{
  "id": "sub_XXXXXXXXXXXXXXXXXXX",
  "object": "subscription",
  "status": "incomplete",
  ...
  "latest_invoice": {
    ...
    "payment_intent": {
      "status": "requires_action",
      ...
      "next_action": {
        "type": "use_stripe_sdk",
        ...
      },
      ...
    }
  }
}

According to the documentation https://stripe.com/docs/api/payment_intents/object#payment_intent_object-next_action-type next_action.type can have two values redirect_to_url and use_stripe_sdk

So my question is how to get next_action.type = redirect_to_url(instead of use_stripe_sdk) and how to force stripe to fill next_action.redirect_to_url(Because I want to handle it on my own in my UI)?

*There is already a similar question on SO: https://stackguides.com/questions/56490033/how-to-handle-use-stripe-sdk-through-php but my case is to create Subscription where I don't have control over PaymentIntent

2
Call confirm on the PaymentIntent from the invoice(latest_invoice.payment_intent.id) and pass return_url. That will give you an updated PaymentIntent with the redirect_to_url action.karllekko
@karllekko I try to redirect to next_action.redirect_to_url.url via set header Location url but stripe return 404 HTTP status for OPTION request(Preflight CORS request). Is it intentional?snieguu
@karllekko that used to work but it seems to no longer work :/Joris Mans
@snieguu What karllekko posted used to work (also in my code) but all of the sudden it doesn't work anymore. I have the same issue here. I contacted Stripe support to see whyJoris Mans
@snieguu I think that's intentional yes, you should do the redirect by setting window.location.href in JS insteadkarllekko

2 Answers

6
votes

In my understanding, the next_action.type will be equal to redirect_to_url only if you choose to manually handle 3D Secure authentication https://stripe.com/docs/payments/payment-intents/verifying-status#manual-3ds-auth

As per documentation:

To handle 3D Secure authentication manually, you can redirect the customer. This approach is used when you manually confirm the PaymentIntent and provide a return_url destination to indicate where the customer should be sent once authentication is complete. Manual PaymentIntent confirmation can be performed on the server or on the client with Stripe.js.

Example using Stripe.js:

stripe.confirmPaymentIntent(
  '{PAYMENT_INTENT_CLIENT_SECRET}',
  {
    payment_method: '{PAYMENT_METHOD_ID}',
    return_url: 'https://example.com/return_url'
  }
).then(function(result) {
  // Handle result.error or result.paymentIntent
});

Example using Stripe Python:

intent = stripe.PaymentIntent.confirm(
  '{PAYMENT_INTENT_ID}',
  payment_method='{PAYMENT_METHOD_ID}',
  return_url='https://example.com/return_url'
)

EDIT: as per @karllekko's comment the {PAYMENT_INTENT_ID} will in your case be latest_invoice.payment_intent.id.

1
votes

Please read https://stripe.com/docs/payments/3d-secure-iframe - it gives more details about the "return_url" flow - and describes also posibilities to customize it inside "iframe" etc

Probably this document is fairly recent - so at the time of this question (July) it was not existing yet