How subscriptions work
With Subscriptions, customers make recurring payments for access to a product. Subscriptions require you to retain more information about your customers than one-time purchases do because you need to charge them in the future.
Subscription objects
Use the following core API resources to build and manage subscriptions:
Resource | Definition |
---|---|
Product | What your business offers — whether that’s a good or a service. |
Price | How much and how often to charge for products, including how much the product costs, what currency to use, and the interval if the price is for subscriptions. |
Customer | Stripe Customer objects allow you to perform recurring charges for the same customer, and to track multiple charges. If you create subscriptions, the customer ID is passed to the subscription object. |
PaymentMethod | Your customer’s payment instruments–how they pay for your service. For example, you may store a credit card on the customer object for recurring use. Typically used with the Payment Intents or Setup Intents APIs. |
Subscription | The product details associated with the plan that your customer subscribes to, which allow you to charge the customer on a recurring basis. |
Invoice | A statement of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices. You can also manually create one-off invoices. |
PaymentIntent | A way to build dynamic payment flows. A Payment Intent tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods. Invoices create payment intents automatically. |
Integration example
See our sample on GitHub demo for an example integration. This demo illustrates how to use Stripe’s objects in a subscriptions integration. If you’re ready to build your own integration, see our integration guide.
Landing page
On your frontend, the landing page collects the email address first. Your application might have other customer-specific information you want to collect like a username or address. Clicking the signup button sends the information collected on the landing page to your backend. This process creates a customer and displays the pricing page on your frontend.
Pricing page
The pricing page displays your different subscription options based on the products and prices you create when you first set up your integration, meaning you don’t need to 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, when a customer selects an option, it displays a payment form.
Payment
The payment form collects a name and card information. Stripe hosts this form if you use Checkout. It’s one of the key features that allows you to collect payments and remain PCI compliant. Clicking Subscribe:
- Creates a new subscription with your customer and price IDs.
- Generates an invoice for your initial subscription cycle.
- Collects payment details and pays your invoice.
- Sets the payment method as the default payment method for the subscription, which is a requirement for subsequent payments.
Provisioning
A confirmation page displays after a successful payment. At this point, it’s safe to provision the product for the customer. This generally means:
- Verifying the status of the subscription is
active
. - Granting the customer access to the products and features they subscribed to.
How payments work with subscriptions
To simplify the handling of failed payments and to create subscriptions before attempting payment, pass payment_behavior=default_incomplete when creating a subscription. If your subscription requires payment, it’s created with status incomplete
, otherwise your subscription immediately becomes active
. Activate an incomplete subscription by paying the first invoice. Pass the payment intent identifier from the invoice to your user interface to collect payment information and confirm the payment intent using Elements, the Android SDK, or the iOS SDK.
Payment status
The payment process differs across payment methods and geographical locations. Payments can also fail initially (for example, a customer enters the wrong card number, has insufficient funds, and more), so various payment outcomes are possible.
A PaymentIntent tracks the lifecycle of every payment. Whenever a payment is due for a subscription, Stripe generates an invoice and a PaymentIntent. The PaymentIntent ID attaches 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 because of a card error | requires_payment_method | open | incomplete |
Fails because of authentication | requires_action | open | incomplete |
The following sections explain these statuses and the actions to take for each.
Succeeded
When your payment succeeds, the subscription is active
and the status of the PaymentIntent is succeeded
. With your payment complete, provision access to your product.
Response | Subscription | PaymentIntent |
---|---|---|
| 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 |
---|---|---|
| incomplete | requires_payment_method |
To resolve these scenarios:
- Notify the customer.
- Collect new payment information and confirm the payment intent.
- Update the default payment method on the subscription.
You can see an example of this in the fixed-price guide.
Requires action
Some payment methods require authentication to complete the payment process. When this happens, the status of your PaymentIntent is requires_action
and 3D Secure (3DS) completes the authentication process. Whether or not a payment method requires authentication is based on your Radar rules and the issuing bank for the card.
Regulations in Europe often require 3D Secure. See Strong Customer Authentication 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 see the Billing SCA Migration guide.
Response | Subscription | PaymentIntent |
---|---|---|
| incomplete | requires_action |
To handle these scenarios:
- Notify your customer that they must authenticate.
- Complete authentication using stripe.ConfirmCardPayment.
You can see an example of this in the 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 send a dunning email to customers for overdue payments to increase recovery chances. 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 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 in your billing settings.
When your 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, usage-based billing, invoices with coupons, or applied customer credit balances often result in non-payment invoices. This means you don’t immediately charge your customer when you create the subscription.
Even though you don’t charge customers for the first invoice, authenticating and authorizing their card is often beneficial as it 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
You can use SetupIntents to:
- Collect payment information.
- Authenticate your customer’s card to claim exemptions later.
- Authorize your customer’s card without charging it.
Authenticating payments allows your customer to grant permissions to charge their card. Strong Customer Authentication requires this, and 3DS is a common way to complete it. Collecting payment method information and authorizing it ensures that you can successfully charge the payment method.
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.
Stripe automatically creates SetupIntents for subscriptions that don’t require an initial payment. The authentication and authorization process also completes at this point, if required. If both succeed or aren’t required, no action is necessary, 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 your 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 your customer with their card issuer. When this happens, the status
of the SetupIntent is set to requires_action
.
To resolve these scenarios, call confirmCardSetup on your frontend so that your customer can complete the authentication flow manually. The code example below expands the pending_setup_intent
to complete the flow.
After completing this flow, authorization executes 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 fail.
To resolve these scenarios, collect a new payment method, then update the default payment method for your customer or the subscription. The code example below expands the pending_setup_intent
to complete the flow.
The subscription lifecycle
A successful subscription flow looks like this:
- The subscription is created with status
incomplete
. - An invoice is created with status
open
for the subscription. - This first invoice is paid.
subscription.status
is set toactive
andinvoice.status
is set topaid
.
At this point, it’s safe to provision your product for your customer. Subscriptions that start with a trial don’t require payment and have the trialing
status. The subscription moves to active
after the trial is over.
Customers have about 23 hours to make a successful payment. The subscriptions remains in status incomplete
and the invoice is open
during this time. If your customer pays the invoice, the subscription updates to active
and the invoice to paid
. If they don’t make a payment, the subscription updates to incomplete_expired
and the invoice becomes void
. This window exists because your customer usually makes the first payment for a subscription while 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 updates 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 leave it past_due
.
For unpaid subscriptions, the latest invoice remains open but payments aren’t attempted. The subscription continues to generate invoices each billing cycle and remains 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, then pay the draft invoices. Pay the most recent invoice before its due date to update the status of the subscription 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. If the most recent invoice gets paid the subscription status returns to active
.
Voiding an invoice generated by a subscription
If the subscription is incomplete
and you void the first invoice that’s generated, the subscription updates to incomplete_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 it meets one of these conditions:
- If the invoice is in a
paid
oruncollectible
state, the subscription state is set toactive
. - 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 tocanceled
,unpaid
, orpast_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 topast_due
. - If the invoice is in none of these states, the same steps execute 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 is successful. It’s safe to provision your product for your customer. |
incomplete | Payment failed when you created your subscription. A successful payment needs to be made within 23 hours to activate your 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 don’t 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. Behaves the same as an active subscription with regards to invoice creation. The subscription’s next state is based on your subscription settings. Pay the most recent invoice before its due date to update the status of the subscription to active . |
canceled | The subscription has been canceled. During cancellation, automatic collection for all unpaid invoices is disabled (auto_advance=false ). This is a terminal state that can not be updated. |
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. Pay the most recent invoice before its due date to update the status of the subscription to active . |
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, then subscribing them to a plan with automatic payment, causes Stripe to send the following events—though this exact order isn’t guaranteed:
- A
customer.created
event is sent, indicating that a customer record is successfully created. - A
customer.subscription.created
event is sent, indicating the subscription is created.
- The
invoice.created
andinvoice.finalized
events are sent, indicating that this invoice was issued for the first billing period. payment_intent.created
andpayment_intent.succeeded
events are sent, indicating that the customer’s payment method is successfully charged.- An
invoice.paid
event is sent, indicating that the invoice is successfully paid.
If a payment requires customer authentication:
- An
invoice.payment_action_required
event is sent, indicating the invoice requires customer authentication. - A
customer.subscription.updated
event is sent with the subscription status set toactive
, indicating the subscription was successfully started after the payment was confirmed.
After your first invoice, the following cycle of events repeats every billing period:
- 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. - When the subscription period elapses, an
invoice.created
event is sent, indicating the creation of a draft invoice. - About one hour after the invoice is created, it is finalized (changes are no longer permitted), and an
invoice.finalized
event is sent. - A payment is attempted, and
payment_intent.created
andpayment_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 your 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 is 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:
- The subscription generates a new invoice in
draft
state. - About one hour after creation, the invoice finalizes (changes are no longer permitted).
- The status is set to
open
and Stripe automatically attempts to pay it using the default payment method. - If payment succeeds, the status updates to
paid
. - If payment fails, the invoice remains
open
and the subscription becomespast_due
.
In this flow, Stripe doesn’t notify your customer about the invoice. Payment is automatically attempted on the invoice shortly after it’s generated. However, if customer emails are enabled, we send an email receipt.
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.
Smart retries
After creating a subscription, 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:
Setting | Description |
---|---|
Cancel the subscription | The subscription changes to a canceled state after the maximum number of days defined in the retry schedule. |
Mark the subscription as unpaid | The subscription changes to an unpaid state after the maximum number of days defined in the retry schedule. Invoices continue to be generated and stay in a draft state. |
Leave the subscription as-is | The subscription remains in a past_due state after the maximum number of days defined in the retry schedule. Invoices continue to be generated and charge customer based on retry settings. |
After the final payment attempt, we make no further payment attempts until you add a new payment method to the customer. Changing your subscription settings only affects future retries. After a payment attempt on an invoice, its next_payment_attempt value is set using the current subscription settings in your Dashboard.
Emails
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 we send the
invoice.upcoming
event. - A failed payment notification prompting customers to update their payment information. Learn more about how to manage failed payments.
- An expiring card notification when one of your customers’ cards is due to expire.
You can customize your URL to update a card and your 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 take additional action on the subscription 30, 60, or 90 days after an invoice becomes past due. The options are:
Setting | Description |
---|---|
Cancel the subscription | The subscription changes to a canceled state after the maximum number of days defined in the retry schedule. |
Mark the subscription as unpaid | The subscription changes to an unpaid state after the maximum number of days defined in the retry schedule. Invoices continue to be generated and stay in a draft state. |
Leave the subscription as-is | The subscription remains in a past_due state after the maximum number of days defined in the retry schedule. Invoices continue to be generated into an open state. |
Learn more about subscription statuses.
Payments requiring 3D Secure
For payments that require 3D Secure, Stripe can send a confirmation email to your 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:
Setting | Description |
---|---|
Cancel the subscription | The subscription changes to a canceled state after the maximum number of days defined in the retry schedule. |
Mark the subscription as unpaid | The subscription changes to an unpaid state after the maximum number of days defined in the retry schedule. Invoices continue to be generated and stay in a draft state. |
Leave the subscription as-is | The subscription remains in a past_due state after the maximum number of days defined in the retry schedule. Invoices continue to be generated and charge customer based on retry settings. |
Trials
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. Learn more about these requirements and settings on the trials page.
Changing subscriptions
Stripe supports changing existing subscriptions without having to cancel and recreate them. Some of the most significant changes you might make are upgrading or downgrading the subscription price, canceling, or pausing an active subscription. Learn more about how to modify existing subscriptions in the Change subscriptions page.