Stripe Failed Payments: The Complete Guide
A failed payment is quiet. No refund request. No angry email. The charge just doesn't go through, and the money never shows up in your account.
That silence costs you. For most subscription businesses, failed payments eat about 9% of revenue every month. Some of it is fraud or dead cards. Most of it is recoverable — if you know what happened and act fast.
This guide covers why Stripe payments fail, how to read decline codes, how to set up retries, and where Stripe leaves you on your own.
Why do Stripe payments fail?
Most failures are not fraud. They're ordinary friction. Here are the common causes, roughly in order of frequency.
Insufficient funds. The customer's account or card limit can't cover the charge. This is the single biggest reason for recurring payment failures.
Expired card. Cards expire on a fixed schedule. If a customer signed up 18 months ago, their card has likely renewed with a new expiry date — and your saved card is now stale.
Card replaced or reissued. Banks reissue cards after fraud alerts, breaches, or account changes. The old number stops working overnight.
Issuer declined. The customer's bank blocked the charge — a fraud filter reacting to a recurring merchant, or a temporary hold. Often the bank won't tell Stripe exactly why.
3D Secure / authentication required. Regulations like SCA in Europe require the customer to confirm the payment. If they don't complete the step, the charge fails.
Incorrect card details. A typo in the number, CVC, or expiry date. More common on first charges than on renewals.
The key insight: renewals fail for different reasons than first charges. A first charge often fails because of bad data. A renewal fails because time passed — cards expire, funds run low, banks reissue. So most renewal failures are temporary and recoverable.
What are Stripe decline codes?
When a charge fails, Stripe returns a decline code that tells you why. This is your map. Handling every failure the same way wastes effort and annoys customers.
Here are the codes you'll see most, and what to do with each.
| Decline code | What it means | Recoverable? |
|---|---|---|
| insufficient_funds | Not enough money in the account | Yes — retry later |
| expired_card | Card is past its expiry date | Yes — ask for update |
| card_declined (generic) | Bank declined, no clear reason | Sometimes — retry |
| do_not_honor | Bank refused, vague catch-all | Sometimes — retry |
| lost_card / stolen_card | Card reported lost or stolen | No — need new card |
| pickup_card | Bank flagged the card | No — need new card |
| processing_error | Temporary issue on Stripe or bank side | Yes — retry soon |
| incorrect_cvc | Wrong security code | Yes — ask for update |
| authentication_required | SCA / 3D Secure needed | Yes — prompt customer |
Split failures into two buckets. Soft declines (insufficient funds, processing errors, generic declines) can be retried — the same card may work in a few days. Hard declines (lost card, stolen card, pickup card) will never succeed. Retrying them just burns your sender reputation and can trigger more fraud flags.
Pull the decline code from the charge.failed or invoice.payment_failed webhook event, under outcome.reason or failure_code.
How do I set up retries for failed payments in Stripe?
Stripe has a built-in feature called Smart Retries, part of its Billing product. Here's how to turn it on.
- Open your Stripe Dashboard.
- Go to Settings → Billing → Automatic collection (sometimes labeled "Revenue Recovery").
- Find Smart Retries and enable it.
- Set what happens when all retries fail — mark the subscription unpaid, cancel it, or leave it past due.
- Under Customer emails, turn on "Send emails when card payments fail" if you want Stripe's default notifications.
Smart Retries picks retry timing based on when charges tend to succeed, which beats fixed intervals. For many businesses, it recovers a meaningful slice of failed payments with zero manual work.
If you want manual control instead, configure a fixed retry schedule — for example, retry on day 1, 3, 5, and 7 — under the same settings.
Turn this on today if you haven't. It's the fastest win available and costs nothing beyond your existing Stripe plan.
What does Stripe not do for failed payments?
Smart Retries is a solid floor — but it's a floor, not a ceiling. Here's where Stripe stops.
Weak email recovery. Stripe's default failed-payment emails are plain and generic. You can't easily run a proper dunning sequence — several messages with different tone, timing, and copy. A single bland email recovers far less than a well-timed sequence.
No branded messaging. The default emails carry minimal branding. Customers who don't recognize the sender ignore them, and recovery depends on the customer trusting and opening the message.
Limited visibility. Stripe tells you a payment failed. It doesn't show how much revenue is at risk right now, which recovery attempts are working, or your recovery rate over time. You stitch that together yourself.
No multi-channel follow-up. Email only. No easy way to add other touchpoints when email fails.
Retries stop at the card level. Stripe retries the same card. It does little to guide the customer through updating to a new card when the old one is dead.
This is the gap. Retries handle the temporary failures. Recovery — reaching customers whose cards genuinely need updating, with messaging they'll actually open — is where most businesses leave money on the table.
That's the exact problem failed payment recovery software solves: layering smart dunning sequences on top of Stripe's retries. For smaller teams, dunning software for small SaaS makes this affordable without a billing engineer.
A simple failed-payment recovery playbook
Here's a full workflow you can run, by hand or with a tool.
- Enable Smart Retries in Stripe. This is your baseline.
- Read the decline code on every failure. Separate soft from hard declines.
- Retry soft declines on a spaced schedule — day 1, 3, 5, 7. Insufficient funds often clears after payday.
- Don't retry hard declines. Email the customer immediately asking them to update their card.
- Send a dunning sequence, not one email. A common pattern: a friendly heads-up on day 1, a reminder on day 3, a firmer note on day 5, and a final warning before cancellation on day 7.
- Make updating painless. Link straight to a hosted update page. Fewer clicks, more recoveries.
- Track your recovery rate. Measure how much of the failed revenue you win back each month. If you're not measuring, you're guessing.
Run this consistently and you'll recover a large share of that 9%. The businesses that lose the most are the ones treating every failure as final.
FAQ
How much revenue do failed payments cost? For most subscription businesses, failed payments cost around 9% of monthly recurring revenue. A good retry and dunning setup recovers a large portion of it.
Do all failed Stripe payments get retried automatically? Only if you enable Smart Retries or set a manual retry schedule. Without it, a failed charge stays failed until you act.
Should I retry a card that was declined as lost or stolen?
No. Hard declines like lost_card and stolen_card will never succeed. Retrying wastes attempts and can raise fraud flags. Ask the customer for a new card instead.
How long should I wait before retrying? Space retries over several days — for example, day 1, 3, 5, and 7. Many failures clear once the customer's account is funded or their bank hold lifts.
Is Stripe's built-in recovery enough? It's a good start for temporary failures. But its emails are generic and its reporting is thin. Adding a proper dunning sequence usually recovers noticeably more.
Stripe gets you retries. Getting the rest of your revenue back takes a real dunning sequence and clear visibility into what's working. That's what we built RecoverBill for — connect your Stripe account in about two minutes and start recovering failed payments from $19/mo. When you're ready to close the gap, see how it works.