DEV Community

Paul Asjes for Stripe

Posted on • Updated on

The PaymentIntents Lifecycle

Stripe tries to make payments as easy as can be, but sometimes it can be a bit overwhelming with all the industry terms and APIs available to you. This Stripe Payment Fundamentals series is a fortnightly blog where we tackle a fundamental topic each time and explain them in simple terms.

This week, Paul Asjes will explain how the PaymentIntents lifecycle works and how it affects your payments.

If you haven’t read the previous installment of this series, you should check that out first to get a grasp on what these APIs actually do.

Previous articles in this series


What do we mean by “lifecycles”? What do the various PaymentIntent statuses mean? What is 3DS and why does it matter? These are all questions we’re going to address in this edition of Stripe Payment Fundamentals, starting with the PaymentIntent lifecycle.

What does “lifecycle” mean?

In the context of PaymentIntents, the lifecycle is the list of states that the PaymentIntent can be in and how it progresses through these states. Since PaymentIntents act as the source of truth of your payment, understanding these states will help you identify issues like payment churn in your application.

Let’s first list out all the possible statuses a PaymentIntent can have:

  • requires_payment_method
  • requires_confirmation
  • requires_action
  • processing
  • requires_capture
  • succeeded
  • canceled

We’ll get to what these each mean individually, but first let’s examine what the lifecycle looks like for the most basic form of payment.

Simple PaymentIntent Lifecycle

That’s delightfully simple, let’s examine what it means.

Simple PaymentIntent Lifecycle - requires_payment_method

A PaymentIntent was created, it has the beginning state of requires_payment_method indicating that a PaymentMethod is needed before it can progress.

Simple PaymentIntent Lifecycle - processing

A PaymentMethod is attached to the PaymentIntent and the PaymentIntent is confirmed (for more information on confirmation, see the last edition of this series [link]). The payment details, amount, and currency are submitted and we’re awaiting the outcome as indicated by the state processing.

divider💡 When creating card payments it’s unlikely you’ll catch a PaymentIntent in the processing state, as card transactions tend to be handled within seconds. Other PaymentMethods can take up to a few days to complete.
divider

Simple PaymentIntent Lifecycle - completed

The payment has completed and we’ve transitioned to the success end state of succeeded.

divider💡 Once a PaymentIntent has reached an end state (succeeded or canceled) its state can no longer change and only its metadata property can be edited.
divider

This is the flow we’d expect for a payment involving a card that doesn’t require any authentication. It can in fact be done in a single API call:

curl https://api.stripe.com/v1/payment_intents \
  -u sk_test_xxxxxxxxxxxx: \
  -d amount=1000 \
  -d currency=usd \
  -d "payment_method_types[]"=card 
  -d payment_method=pm_xxxxxxxxxxxx
  -d confirm=true
Enter fullscreen mode Exit fullscreen mode

This API call creates the PaymentIntent with an amount and currency, immediately specifies a PaymentMethod, and instructs the API to confirm the payment, all in one request.

Here’s a slightly more complex flow:

Complex PaymentIntent Lifecycle

This is almost identical to our earlier flow, but adds a new requires_action state.

Complex PaymentIntent Lifecycle - requires_action

Any state that begins with requires indicates that the PaymentIntent will not progress to a different state unless some action is taken. requires_action is no different here. Our PaymentIntent enters this state if the payment requires authentication before it can be processed. When working with cards, the most common type of authentication is 3D Secure (3DS).

3DS and SCA

You can think of 3DS as two form authentication (2FA) for your credit card. It occurs when you attempt to make a payment but the issuing bank wants to ensure that it’s really you who’s making the request.

In September 2019 the European Union put the Strong Customer Authentication (SCA) ruling into effect. In practice this means that European cards that are enrolled now have mandatory 3DS checks before a payment can be completed. If said check can’t be completed, either due to the integration not supporting this flow or the customer failing the authentication check, the payment is declined by the issuing bank.

As a response to this, Stripe developed the PaymentIntents API, intended to abstract the complexity of SCA and other authentication laws away from your integration. Even if you don’t regularly do business in the EU, it’s highly recommended you build your Stripe integration with 3DS in mind. This has the benefit of ensuring your integration is ready if new laws similar to SCA are enforced within the regions of your customers.

divider💡 If you’re integrating with Checkout or Payment Links, then 3DS is automatically handled for you.
divider

But what do all the statuses mean?

Now that we’ve established some concepts, let’s go through the list again with a simple explanation for each status.

  • requires_payment_method - The PaymentIntent needs an attached PaymentMethod before it can progress.
  • requires_confirmation - A PaymentMethod was attached and the PaymentIntent needs to be confirmed.
  • requires_action - After confirming, further action is required. Likely a 3DS check.
  • processing - The payment is being processed, this status will automatically transfer to a new state without requiring your input.
  • requires_capture - A special state only seen if your PaymentIntent is in manual confirmation mode. The PaymentIntent needs to be instructed to capture the funds.
  • succeeded - The payment has succeeded. This is an end state.
  • canceled - The payment was canceled. This is an end state.

Note that the only end states are when the payment succeeds or is explicitly cancelled by you. In the case of a payment being declined, the PaymentIntent will automatically detach the PaymentMethod and transition back to the requires_payment_method status.

When examining the payments on your account, seeing what state abandoned payments are left in can help you identify issues with your checkout experience. For instance, a large amount of PaymentIntents in the requires_action status can indicate that your users are churning when confronted with 3DS. Same scenario but with requires_payment_method can mean that there’s a problem with your integration where PaymentMethods aren’t being created and attached correctly.


https://stripe.com/docs/payments/quickstart

Build an integration using the integration builder

Now that you’ve learned about the PaymentIntents lifecycle, learn how to build your own integration.

Stripe’s quick start integration builder walks through the many supported languages for client and server-side code.

You can learn more about integrating PaymentIntents in this Stripe Developers video.

Related resources:

Next up: Payment Element vs Checkout vs Payment Links

In our next post in the Stripe Payment Fundamentals series, we’ll introduce the different Stripe products available to you for collecting payments and when you should choose one over the other.

In the meanwhile, you can stay up to date with Stripe in a few ways:

📣 Follow us on Twitter
💬 Join the official Discord server
📺 Subscribe to our Youtube channel
📧 Sign up for the Dev Digest

Top comments (2)

Collapse
 
paulasjes profile image
Paul Asjes

PaymentIntents don't ever expire, they sit in their status forever until something prompts them to move to a new status.

Collapse
 
cski profile image
Patryk Cieszkowski

requires_capture - A special state only seen if your PaymentIntent is in manual confirmation mode. The PaymentIntent needs to be instructed to capture the funds.

don't you mean manual capture mode?