The PaymentIntents Lifecycle
Tags: stripe, tutorial, webdev, stripefundamentals
Published: 2021-11-15 16:47:59

_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](https://twitter.com/paul_asjes) will explain how the PaymentIntents lifecycle works and how it affects your payments._

_If you haven’t read the [previous installment](https://dev.to/stripe/fundamentals-of-the-paymentintents-and-paymentmethods-apis-3646) of this series, you should check that out first to get a grasp on what these APIs actually do._

## Previous articles in this series
- [Fundamentals of the PaymentIntents and PaymentMethods APIs](https://dev.to/stripe/fundamentals-of-the-paymentintents-and-paymentmethods-apis-3646)

{% link https://dev.to/stripe/fundamentals-of-the-paymentintents-and-paymentmethods-apis-3646 %}

---

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](https://stripe.com/docs/payments/intents) 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](https://dev.to/stripe/fundamentals-of-the-paymentintents-and-paymentmethods-apis-3646), 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](https://paper-attachments.dropbox.com/s_3A9E8C52EB99000F249DD8F231C764E3985699AD2C6AEB0D48DAA24E5A18EC0F_1636713281761_image.png)


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


![Simple PaymentIntent Lifecycle - requires_payment_method](https://paper-attachments.dropbox.com/s_3A9E8C52EB99000F249DD8F231C764E3985699AD2C6AEB0D48DAA24E5A18EC0F_1636713487519_image.png)


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](https://paper-attachments.dropbox.com/s_3A9E8C52EB99000F249DD8F231C764E3985699AD2C6AEB0D48DAA24E5A18EC0F_1636713503421_image.png)


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](https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)💡 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](https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)

![Simple PaymentIntent Lifecycle - completed](https://paper-attachments.dropbox.com/s_3A9E8C52EB99000F249DD8F231C764E3985699AD2C6AEB0D48DAA24E5A18EC0F_1636713541968_image.png)


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

![divider](https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)💡 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](https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)

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

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](https://paper-attachments.dropbox.com/s_3A9E8C52EB99000F249DD8F231C764E3985699AD2C6AEB0D48DAA24E5A18EC0F_1636979218961_image.png)


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


![Complex PaymentIntent Lifecycle - requires_action](https://paper-attachments.dropbox.com/s_3A9E8C52EB99000F249DD8F231C764E3985699AD2C6AEB0D48DAA24E5A18EC0F_1636979237001_image.png)


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](https://stripe.com/docs/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](https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)💡 If you’re integrating with Checkout or Payment Links, then 3DS is automatically handled for you.
![divider](https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)

## 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](https://stripe.com/docs/payments/capture-later). 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](https://res.cloudinary.com/practicaldev/image/fetch/s--31Nrl8Cz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzuq6iubf4348lohitil.png)

## 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](https://stripe.com/docs/payments/quickstart) walks through the many supported languages for client and server-side code.

You can learn more about integrating PaymentIntents in this [Stripe Developers video](https://www.youtube.com/watch?v=WG4ehXSEpz4).

{% youtube WG4ehXSEpz4 %}

## Related resources:
* [The Payment Intents API](https://stripe.com/docs/payments/payment-intents)
* [Strong Customer Authentication readiness](https://stripe.com/docs/strong-customer-authentication)
* [Stripe Checkout](https://stripe.com/docs/payments/checkout)
* [Share a payment link](https://stripe.com/docs/payments/payment-links)
* [Custom payment flow](https://stripe.com/docs/payments/quickstart)

## 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](https://twitter.com/stripedev)
💬 [Join the official Discord server](https://stripe.com/go/developer-chat)
📺 Subscribe to our [Youtube channel](https://www.youtube.com/stripedevelopers)
📧 [Sign up for the Dev Digest](https://go.stripe.global/dev-digest)