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
- 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. You can use Elements, the Android SDK, or the iOS SDK.
The payment process differs across payment methods and geographical locations. Payments can also fail initially (for example, a customer may enter the wrong card number or have insufficient funds), 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|
|Fails because of a card error|
|Fails because of authentication|
The following sections explain these statuses and the actions to take for each.
When your payment succeeds, the status of the PaymentIntent is
succeeded, and the subscription becomes
active. For payment methods with longer processing periods, subscriptions are immediately activated. In these cases, the status of the PaymentIntent may be
processing for an
active subscription until the payment succeeds.
With your subscription now activated, provision access to your product. Read the guide to learn more about the subscription lifecycle and best practices for provisioning.
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
To resolve these scenarios:
Learn how to handle payment failures for subscriptions.
Some payment methods require customer authentication with 3D Secure (3DS) to complete the payment process. If you use the Payment Intents API, the value of
requires_action when a customer needs to authenticate a payment. 3DS completes the authentication process. Whether a payment method requires authentication depends 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.
To handle these scenarios:
- Monitor for the
invoice.payment_action_required event notification with webhooks. This indicates that authentication is required.
- Notify your customer that they must authenticate.
- Retrieve the client secret for the payment intent and pass it in a call to stripe.ConfirmCardPayment. This displays an authentication modal to your customers, attempts payment, then closes the modal and returns context to your application.
- Monitor the
invoice.paid event on your webhook endpoint to verify that the payment succeeded. Users can leave your application before
confirmCardPayment() finishes. Verifying whether the payment succeeded allows you to correctly provision your product.
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
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
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
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.
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
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.