Failed subscription payments in Stripe: retries and access
What happens when a subscription renewal fails in Stripe: Smart Retries, failed-payment emails, what to do with access during past_due, and how to test it.
Leer en español →
When a subscription renewal fails in Stripe, the invoice stays open, the subscription usually moves to past_due, and Stripe retries the charge on the schedule you set. If you turn on Smart Retries and failed-payment emails, Stripe recovers many of these on its own. Your app has three jobs: tell the customer, make it easy for them to update their card, and decide what access they keep until the payment succeeds or the retries run out.
This guide explains the settings to choose, the events your app should react to, a sensible access policy and how to rehearse the whole thing in a sandbox.
Why do renewal payments fail?
Most failures aren't fraud or unhappy customers. Typical causes are an expired or replaced card, insufficient funds on the renewal day, the bank asking for authentication, or the issuer declining a recurring charge it doesn't recognise. Some of these fix themselves on a later attempt; others won't succeed until the customer gives you a new card.
Stripe separates the two. For hard decline codes such as lost_card, stolen_card, incorrect_number or authentication_required, scheduled retries keep counting but don't actually charge anything until a new payment method is attached. Stripe also won't retry when there is no payment method at all.
How do you set up automatic retries?
In the Dashboard, go to Billing > Revenue recovery > Retries.
- Turn on Smart Retries. Stripe picks the times to retry based on signals from its network. You choose how many attempts and over what window: 1 week, 2 weeks, 3 weeks, 1 month or 2 months. Stripe's recommended default is 8 tries within 2 weeks.
- Or use a custom schedule. You can set up to three retries, each a number of days after the previous one. Only do this if you have a reason, such as paydays for your customers.
- Choose what happens when retries run out. The options are to cancel the subscription, mark it
unpaid, leave itpast_due, or pause it if it's eligible.
That last choice decides what your app sees. "Cancel" ends the subscription and sends customer.subscription.deleted. "Mark as unpaid" keeps the subscription but stops attempting payment, which suits products where you want the customer to come back and settle the balance. Changing these settings only affects future retries, not ones already scheduled.
Which customer emails should you turn on?
In the revenue recovery email settings you can have Stripe send:
- Failed payment emails, sent after each failed attempt, with a link to update the payment method.
- Expiring card emails, sent a month before the default card expires. These prevent the most avoidable failure.
- Payment confirmation emails, for payments that need the customer to authenticate (3D Secure).
The link in these emails can point to a Stripe-hosted page or to your own billing page. If you already use the customer portal, send people there. Our customer portal guide shows how to link straight to the "update card" flow.
One testing trap: in a sandbox, Stripe only sends these emails to addresses on your verified email domain or to team members, so a test customer at a random address never receives one.
What should your app do when a payment fails?
Listen for these events in your webhook handler:
| Event | What it tells you | What to do |
|---|---|---|
invoice.payment_failed | An attempt failed; attempt_count says which one | Show a banner, optionally send your own in-app notice |
customer.subscription.updated | Status changed, often to past_due | Update your stored status |
invoice.payment_action_required | The bank wants the customer to authenticate | Prompt them to confirm the payment |
invoice.paid | A retry or a new card worked | Clear the banner, confirm status is active |
customer.subscription.deleted | Retries ran out and you chose cancel | Remove access |
If you use Stripe's automations feature, note that the next retry date (next_payment_attempt) appears on invoice.updated events rather than on invoice.payment_failed.
When the customer adds a new card, where does it go?
Stripe retries using the first payment method it finds, in this order: the subscription's default payment method, then the customer's default. If the subscription has its own default and you only update the customer's, Stripe keeps retrying the old card. Update the same field that failed, or clear the subscription-level default. The customer portal's update flow handles this for you.
How much access should a customer keep while past_due?
There is no single right answer, but decide it on purpose and write it down. A common, customer-friendly policy:
- During retries (
past_due): keep full access and show a persistent banner with an "Update card" button. - After retries fail (
unpaidorcanceled): remove paid features, keep the account and the data, and show how to resubscribe. - Never delete data on payment failure. People who fix their card a week later expect to find their work.
Stripe's docs recommend revoking access when a subscription becomes canceled or unpaid. Whatever you choose, enforce it on the server, from the status your webhook stored. We cover that in limiting features by plan. If the stored status is drifting from Stripe, the problem is upstream, in the subscription webhook setup.
How do you test failed payments before launch?
- In a sandbox, subscribe a test customer with a normal test card, attached to a test clock.
- Replace the card with one of Stripe's test cards that declines on charge.
- Advance the clock past the renewal date. You should see
invoice.payment_failedand apast_duestatus. - Advance again to watch the retries, then update to a working card and confirm
invoice.paidarrives and access is restored. - Repeat, but let the retries run out, and confirm your app reacts to the final state you chose.
Quick answers
Does Stripe charge extra for Smart Retries? Revenue recovery features are part of Stripe Billing. Check current Billing pricing for your account.
Should I email customers myself as well? Stripe's emails are usually enough. An in-app banner adds a lot, because the customer sees it while they're using the product.
What about the very first payment of a subscription? If it fails, the subscription stays incomplete, and if nobody pays within 23 hours it becomes incomplete_expired. Don't grant access to incomplete subscriptions.
Can I retry manually? Yes. You can pay an open invoice from the Dashboard or the API once the customer has a working payment method.
Losing customers to failed cards?
If renewals fail quietly or customers lose access when they shouldn't, the fix is usually in the retry settings, the webhook handler and the access check together. Our Stripe payments service covers all three. You can also start with the free app health check, read Stripe's retry documentation, or get in touch.


