How subscriptions work

How subscriptions work

Learn how subscriptions work within Stripe.

With subscriptions, customers make recurring payments for access to a product. A subscription might not seem much different from a one-time purchase of a t-shirt or water bottle. But to manage subscription payments you need to retain more information about your customers, so you can charge them automatically in the future and maintain appropriate access to your product.

Subscription objects

These are the core API objects used to build and manage subscriptions:

  • Customers are your buyers. Information like names, email addresses, and payment methods (credit cards, debit cards, etc.) is stored on the Customer object.
  • Products are what you sell.
  • Prices represent how much and how often you charge for a product. You can define multiple prices for a product so you can charge different amounts based on currency or interval (monthly, yearly, etc.).
  • Subscriptions represent your Customers’ access to a product and require a customer and payment method to be created. The status of a subscription indicates when to provision access to your service for a customer.
  • Invoices are generated when it’s time to bill a customer for a subscription. Invoices have line items, tax rates, and the total amount owed by a customer.
  • Payment Intents represent the state of all attempts to pay an invoice.

Integration example

See our Pasha photo hosting demo for an example integration. This demo is used to illustrate how Stripe’s objects are used in a subscriptions integration. If you’re ready to build your own integration, see our fixed-price guide.

Landing page

On the frontend, the landing page collects an email address first. In your application, there might be other customer-specific information you want to collect like a username or address. After the customer clicks the signup button, the information collected on the landing page is sent to the backend. From there, a new customer is created and the pricing page is displayed on the frontend.

Pricing page

The pricing page displays the different subscription options. This information is based on the products and prices you create when you first set up your integration, you don’t create new ones every time customers sign up. Your pricing page displays the prices you created, and your customers choose the option they want. In the Pasha example, as soon as a customer selects an option, a payment form is displayed.


The payment form collects a name and card information. This form is hosted by Stripe and is one of the key features that allows you to collect payments and remain PCI compliant. After clicking the Subscribe button:

  1. The payment method is saved to the customer and set as the default payment method. This is required for subsequent payments.
  2. A new subscription is created, with the customer and price IDs.
  3. An invoice is generated for the initial subscription cycle.
  4. The invoice is paid using the saved payment method.


After a successful payment, a confirmation page is displayed. At this point it’s safe to provision the product for the customer. This generally means:

  1. Verifying the status of the subscription is active.
  2. Granting the customer access to the products and features they subscribed to.

How payments work with subscriptions

The payment process differs across payment methods and geographical locations. Payments can also fail initially (customer enters the wrong card number, insufficient funds, etc.) so there are a few payment outcomes you need to understand.

The lifecycle of every payment is tracked with a PaymentIntent. Every time payment is due for a subscription, an invoice and PaymentIntent are generated. The PaymentIntent ID is attached to the invoice and you can access it from the Invoice and Subscription objects. The state of the PaymentIntent affects the state of the invoice and the subscription. Here’s how the different outcomes of a payment map to the different statuses:

Payment outcome PaymentIntent status Invoice status Subscription status
Success succeeded paid active
Fails due to card error requires_payment_method open incomplete
Fails due to authentication requires_action open incomplete

The following sections explain these statuses and the actions to take for each.


When the payment succeeds, the subscription is active and the status of the PaymentIntent is succeeded. The payment is complete and you should provision access to your product.

Response Subscription PaymentIntent
{ "id": "sub_1ELI8bClCIKljWvsvK36TXlC", "object": "subscription", "status": "active", ... "latest_invoice": { "id": "in_EmGqfJMYy3Nt9M", "status": "paid", ... "payment_intent": { "status": "succeeded", ... } } }
active succeeded

Requires payment method

If payment fails because of a card error such as a decline, the status of the PaymentIntent is requires_payment_method and the subscription is incomplete.

Response Subscription PaymentIntent
{ "id": "sub_1ELI8bClCIKljWvsvK36TXlC", "object": "subscription", "status": "incomplete", ... "latest_invoice": { "id": "in_EmGqfJMYy3Nt9M", "status": "open", ... "payment_intent": { "status": "requires_payment_method", ... } } }
incomplete requires_payment_method

To resolve these scenarios:

  • Notify the customer, collect new payment information, and create a new payment method
  • Attach the payment method to the customer
  • Update the default payment method
  • Pay the invoice using the new payment method

You can see an example of this in our fixed-price guide.

Requires action

Some payment methods require authentication to complete the payment process. When this happens, the status of the PaymentIntent is requires_action and 3D Secure is used to complete the authentication process. Whether or not a payment method requires authentication is based on your Radar rules and the card’s issuing bank.

Regulations in Europe often require 3D Secure. Read our Strong Customer Authentication guide to determine whether handling this status is important for your business. If you have an existing billing integration and want to add support for this flow, also take a look at the Billing SCA Migration guide.

Response Subscription PaymentIntent
{ "id": "sub_1ELI8bClCIKljWvsvK36TXlC", "object": "subscription", "status": "incomplete", ... "latest_invoice": { "id": "in_EmGqfJMYy3Nt9M", "status": "open", ... "payment_intent": { "status": "requires_action", "client_secret": "pi_91_secret_W9", "next_action": { "type": "use_stripe_sdk", ... }, ... } } }
incomplete requires_action

To handle these scenarios:

You can see an example of this in our fixed-price guide.

Recurring charges

Stripe handles recurring charges for you automatically. This includes:

  • Automatically invoicing customers and attempting payments when new billing cycles start.
  • When payments fail, Stripe retries them using the Smart Retries feature. This automatically re-attempts payment when cards are declined according to your Dashboard settings.

You can also enable email reminders for overdue payments to increase recovery chances. And for payments that require 3D Secure, you can configure your billing settings to send a hosted link to customers so they can complete the flow.

Build your own handling for recurring charge failures

If you don’t want to use Stripe’s tooling to manage failures, you can build your own. If a payment fails or if it requires customer authentication, the subscription’s status is set to past_due and the PaymentIntent status is either requires_payment_method or requires_action.

To manage these scenarios, set up a webhook endpoint and listen to the customer.subscription.updated event so that you’re notified when subscriptions enter a past_due state:

{ "id": "sub_E8uXk63MAbZbto", "object": "subscription", ... "status": "past_due", "latest_invoice": "in_1EMLu1ClCIKljWvsfTjRFAxa" }

For these subscriptions, you need to get your customers back into your application to collect a different payment method so they can complete the payment. You can use an email or a mobile push notification. Stripe provides built-in reminder emails to handle this case, which you can configure on your billing settings page.

When the customer is back in your application, reuse either your payment failure flow or customer action flow depending on the status of the associated PaymentIntent. After the payment succeeds, the status of the subscription is active and the invoice is paid.

Handle non-payment invoices

Subscriptions that include free trials, metered billing, or invoices with coupons or applied customer credit balances often result in non-payment invoices. This means the customer isn’t immediately charged when the subscription is created.

Even though customers aren’t charged for the first invoice, authenticating and authorizing their card is often beneficial. This can increase the chance that the first non-zero payment completes successfully. Payments made this way are known as off-session payments. To manage these scenarios, Stripe created SetupIntents.

Using SetupIntents

SetupIntents can be used to:

  • Collect payment information
  • Authenticate the customer’s card to claim exemptions later
  • Authorize the customer’s card without charging it

Authenticating payments allows the customer to grant permissions to charge their card. This is required for Strong Customer Authentication, and is often performed through 3DS. Collecting payment method information and authorizing it ensures the payment method can be successfully charged.

In off-session scenarios, SetupIntents enable you to charge customers for their first non-zero payment without having to bring them back to your website or app for authentication. This reduces the friction on your customers.

SetupIntents are automatically created for subscriptions that don’t require an initial payment. If authentication and authorization are required, they’re executed as well. If both succeed, or if they aren’t needed, no action is required, and the subscription.pending_setup_intent field is null. If either step fails, Stripe recommends using the SetupIntent on your frontend to resolve the issue while the customer is on-session. The next two sections explain in detail how to manage scenarios where authentication or authorization fail.

Managing authentication failures Client-side

Authentication failures occur when Stripe is unable to authenticate the customer with their card issuer. When this happens, the status of the SetupIntent is set to requires_action.

To resolve these scenarios, your frontend should call confirmCardSetup so that the customer can complete the authentication flow manually. Note that the code example below expands the pending_setup_intent to complete the flow.

const {pending_setup_intent} = subscription; if (pending_setup_intent) { const {client_secret, status} = subscription.pending_setup_intent; if (status === "requires_action") { stripe.confirmCardSetup(client_secret).then(function(result) { if (result.error) { // Display error.message in your UI. } else { // The setup has succeeded. Display a success message. } }); } }
const {pending_setup_intent} = subscription; if (pending_setup_intent) { const {client_secret, status} = subscription.pending_setup_intent; if (status === "requires_action") { const {setupIntent, error} = await stripe.confirmCardSetup(client_secret); if (error) { // Display error.message in your UI. } else { // The setup has succeeded. Display a success message. } } }

After completing this flow, authorization is executed if it’s required. If authorization succeeds, or if it’s not required, pending_setup_intent is updated to null upon completion.

Managing authorization failures Client-side

Payment authorization failures occur when Stripe can’t verify that a card can be charged. When this happens, the status of the SetupIntent is set to requires_payment_method. This generally means that subsequent charges with that card will fail.

To resolve these scenarios, follow the steps from Outcome 3: Payment fails to collect a new payment method and then update the customer or subscription’s default payment method. Note that the code example below expands the pending_setup_intent to complete the flow.

const {pending_setup_intent, latest_invoice} = subscription; if (pending_setup_intent) { const {client_secret, status} = subscription.pending_setup_intent; if (status === "requires_action") { stripe.confirmCardSetup(client_secret).then(function(result) { if (result.error) { // Display error.message in your UI. } else { // The setup has succeeded. Display a success message. } }); } else if (status === "requires_payment_method") { // Collect new payment method } }
const {pending_setup_intent, latest_invoice} = subscription; if (pending_setup_intent) { const {client_secret, status} = subscription.pending_setup_intent; if (status === "requires_action") { const {setupIntent, error} = await stripe.confirmCardSetup(client_secret); if (error) { // Display error.message in your UI. } else { // The setup has succeeded. Display a success message. } } else if (status === "requires_payment_method") { // Collect new payment method } }

The subscription lifecycle

A successful subscription flow looks like this:

  1. Subscription is created
  2. An invoice is created for the subscription and then paid
  3. subscription.status is set to active and invoice.status is set to paid

At this point, it’s safe to provision your product for your customer. Subscriptions that start with a trial have the trialing status and then move to active once the trial is over.

If payment fails, the subscription and invoice are still created but they have different statuses:

  • subscription.status is incomplete
  • invoice.status is open

Subscription expiration workflow

When the initial payment fails, customers have about 23 hours to make a successful payment. If payment is made, the subscription is updated to active and the invoice is paid. If no payment is made, the subscription is updated to incomplete_expired and the invoice becomes void. This window exists because the first payment for a subscription is usually made with the customer on-session. If the customer returns to your application after 23 hours, create a new subscription for them.

The subscription’s status remains active as long as automatic payments succeed. If automatic payment fails, the subscription is updated to past_due and Stripe attempts to recover payment based on your retry rules. If payment recovery fails, you can set the subscription status to canceled, unpaid, or you can leave it active.

For unpaid subscriptions, the latest invoice remains open but payments aren’t attempted. Invoices continue to be generated each billing cycle and remain in draft state. To reactivate the subscription, you need to:

  • Collect new payment information
  • Turn automatic collection back on by setting auto advance to true on draft invoices
  • Finalize and then pay the draft invoices (make sure to pay the most recent invoice before its due date to update the subscription’s status to active)

Setting past_due subscriptions to unpaid is the default behavior because it gives you the most options for reactivating subscriptions.

Canceling subscriptions disables creating new invoices for the subscription, and stops automatic collection of all invoices from the subscription by setting auto_advance to false. It also deletes the subscription. If your customer wants to resubscribe, you need to collect new payment information from them and create a new subscription.

If you leave the subscription in place, the most recent unpaid invoice remains open, new invoices are generated, and payments on new invoices are attempted. Use this behavior if you want to continue attempts to bill your customers every month, even when previous invoice payments have failed.

Voiding an invoice generated by a subscription

If the subscription is incomplete and you void the first invoice that’s generated, the subscription is updated to expired. If you void the most recent invoice for an active subscription and it’s not the first one, the following logic is applied to each invoice (from most recent to oldest) until one of the conditions is met:

  • If the invoice is in a paid or uncollectible state, the subscription state is set to active.
  • If the collection_method is set to charge_automatically on the invoice, and Stripe stopped dunning on the invoice because of retry limits, the subscription state is set to canceled , unpaid, or past_due based on your automatic collection settings.
  • If the collection_method is set to send_invoice, and the invoice is past its due date, the state of the subscription is set to past_due.
  • If the invoice is in none of these states, the same steps are executed on the next most recent invoice.

If no invoices match any of the above criteria, the subscription state is set to active.

Subscription statuses

Status Description
trialing The subscription is currently in a trial period and it’s safe to provision your product for your customer. The subscription transitions automatically to active when the first payment is made.
active The subscription is in good standing and the most recent payment was successful. It's safe to provision your product for your customer.
incomplete Payment failed when the subscription was created. A successful payment needs to be made within 23 hours to activate the subscription. See the payments section for details on resolving subscriptions with this status.
incomplete_expired The initial payment on the subscription failed and no successful payment was made within 23 hours of creating the subscription. These subscriptions do not bill customers. This status exists so you can track customers that failed to activate their subscriptions.
past_due Payment on the latest invoice either failed or wasn't attempted.
canceled The subscription has been canceled. During cancellation, automatic collection for all unpaid invoices is disabled (auto_advance=false).
unpaid The latest invoice hasn't been paid but the subscription remains in place. The latest invoice remains open and invoices continue to be generated but payments aren't attempted.

Subscription events

Events are triggered every time a subscription is created or changed. Some events are sent immediately when a subscription is created, while others recur on regular billing intervals. Creating a customer with a valid payment method, and subscribing them to a plan with automatic payment, causes Stripe to send the following events—though the exact order is not guaranteed:

  1. A customer.created event is sent, indicating that a customer record was successfully created.
  2. A customer.subscription.created event is sent, indicating the subscription was created.
  3. The invoice.created and invoice.finalized events are sent, indicating that this invoice was issued for the first billing period.
  4. payment_intent.created and payment_intent.succeeded events are sent, indicating that the customer’s payment method was successfully charged.
  5. An invoice.paid event is sent, indicating that the invoice was successfully paid.

If a payment requires customer authentication:

  1. An invoice.payment_action_required event is sent, indicating the invoice requires customer authentication.
  2. A customer.subscription.updated event is sent with the subscription status set to active, indicating the subscription was successfully started after the payment was confirmed.

After the first invoice, the following cycle of events repeats every billing period:

  1. A few days prior to renewal, an invoice.upcoming event is sent. The number of days is based on the number set for Upcoming renewal events in the Dashboard. You can still add extra invoices items if needed.
  2. When the subscription period elapses, an invoice.created event is sent, indicating the creation of a draft invoice.
  3. About an hour after the invoice is created, it is finalized (changes are no longer permitted), and an invoice.finalized event is sent.
  4. A payment is attempted and payment_intent.created and payment_intent.succeeded events are sent to indicate that the payment was successful.

You might want to take specific actions in response to certain events, such as:

  • Emailing the customer when a payment fails
  • Extending the length of time that a customer can use your service
  • Terminating access when a subscription is canceled

Stripe recommends that you listen for events with webhooks.

Other events

You might need to handle other events depending on how you use subscriptions and invoices.

Event Description
customer.subscription.trial_will_end This event is sent three days before the trial period ends. If the trial is less than three days, this event isn't triggered.
invoice.updated This event is often sent when a payment succeeds or fails. If payment is successful the paid attribute is set to true and the status is paid. If payment fails, paid is set to false and the status remains open. Payment failures also trigger a invoice.payment_failed event.
customer.subscription.updated This event is triggered whenever a subscription is changed. For example, adding a coupon, applying a discount, adding an invoice item, and changing plans all trigger this event.

Invoice lifecycle

The invoices overview provides a more detailed explanation of how invoices work, but for invoices generated by subscriptions, the basic lifecycle looks like this:

  1. The subscription generates a new invoice in draft state.
  2. About an hour after creation, the invoice is finalized (changes are no longer permitted).
  3. The status is set to open and Stripe automatically attempts to pay it using the default payment method.
  4. If payment succeeds, the status is updated to paid.
  5. If payment fails, the invoice remains open and the subscription becomes past_due.

In this flow, Stripe doesn’t notify the customer about the invoice. Payment is automatically attempted on the invoice shortly after it’s generated. However, if customer emails are enabled, an email receipt is sent.

Subscription settings and recovery

Your subscription settings determine how Stripe responds when payments fail or when subscriptions become past due. The settings for automatic payment and manual payment are configured independently.

Automatic payment

After a subscription is created, payment failure is the most important event that can happen. Failures occur for many reasons:

  • Lack of a payment method on the customer
  • The payment method is expired
  • The payment is declined

You can configure Stripe to retry failed payments. Smart Retries use Stripe’s machine learning to pick the optimal time to retry, over a configurable time period up to one month after the initial payment fails.

You can also modify the retry schedule with custom rules. You can configure up to three retries, each with a specific number of days after the previous attempt.

If recovery fails, the subscription transitions according to your settings. The options are:

  • Cancel the subscription
  • Mark the subscription as unpaid
  • Leave the subscription as-is

For more information on these choices, see the subscription statuses.

After the final payment attempt, no further payment attempts are made until a new payment method is added to the customer. Note that changing your subscription settings only affects future retries. Once a payment attempt is made on an invoice, its next_payment_attempt value is set using the current subscription settings in your Dashboard.


Stripe can optionally send different emails to customers, using the email addresses associated with the Customer object:

  • An upcoming renewal reminder at the same time that the invoice.upcoming event is sent
  • A failed payment notification prompting customers to update their payment information
  • An expiring card notification when one of your customers’ cards is due to expire

You can customize the URL to update a card as well as the logo and colors used in the email, as outlined in the receipts documentation.

Manual payment

You can configure the due date for invoices that are set for manual payment. You can also configure up to three reminders, starting at 10 days before the due date and ending at 60 days after.

You can also choose to take additional action on the subscription 30, 60, or 90 days after an invoice becomes past due. The options are:

  • Cancel the subscription
  • Mark the subscription as unpaid
  • Leave the subscription as-is

For more information on these choices, see subscription statuses.

Payments requiring 3D Secure

For payments that require 3D Secure, Stripe can send a confirmation email to the customer at the same time as the invoice.payment_action_required event is sent. You can also configure sending up to three reminders, from one to seven days after the payment was initiated.

If a payment is still incomplete after the set number of days, you can choose to:

  • Cancel the subscription
  • Mark the subscription as unpaid
  • Leave the subscription as-is


Card networks require you to inform your customers about their trials. Stripe can manage this communication for you. In the Stripe Dashboard, you can configure the cancellation URL that’s included on both the reminder emails and on the receipt for the first invoice after a trial ends. You can also configure the statement descriptor for the first charge after a trial. You can read more about these requirements and settings on the trials page.