Every month, between 3% and 9% of subscription charges processed through Stripe fail. For a SaaS company doing $100K in monthly recurring revenue, that means $3,000 to $9,000 vanishes before a single customer intentionally cancels. Most of those charges are recoverable. The question is whether you have a system to recover them.
This guide covers everything: why Stripe payments fail, what each decline code actually means, the math behind revenue loss, and the specific retry and dunning strategies that recover 30-70% of failed charges. Whether you build a recovery system yourself or use a tool like RecoverStripe, these are the mechanics you need to understand.
What Is a Failed Payment in Stripe?
A failed payment occurs when Stripe attempts to charge a customer's payment method and the charge is declined by the card network, issuing bank, or Stripe's own fraud prevention system. In Stripe's event model, this surfaces as an invoice.payment_failed webhook event.
Failed payments split into two categories:
- Hard declines — The issuing bank has permanently refused the transaction. The card is invalid, reported stolen, or the account is closed. Retrying won't help. These require the customer to provide a new payment method.
- Soft declines — The bank refused this specific attempt, but the card is still valid. Common reasons include insufficient funds, temporary holds, or the bank's fraud algorithm flagging the charge. These are recoverable through retries.
The distinction matters because your recovery strategy should be completely different for each type. Retrying a hard decline wastes API calls and can damage your merchant reputation. Failing to retry a soft decline leaves money on the table.
Why Stripe Payments Fail: Decline Codes Decoded
Stripe returns a decline_code with every failed charge. Here are the codes you'll see most often, what they actually mean, and whether retrying makes sense:
Soft Declines (Retryable)
| Decline Code | What It Means | Retry Strategy |
|---|---|---|
insufficient_funds |
The card doesn't have enough money right now | Retry after payday cycles (3-5 days) |
generic_decline |
The bank declined without a specific reason | Retry in 24-48 hours, then escalate |
processing_error |
A temporary issue at the bank or network | Retry in 2-6 hours |
card_velocity_exceeded |
Too many charges in a short period | Wait 24 hours, then retry |
do_not_honor |
The bank says no, but the card may still work | Retry in 48-72 hours |
try_again_later |
Temporary issue on the bank side | Retry in 4-8 hours |
Hard Declines (Do Not Retry)
| Decline Code | What It Means | Action |
|---|---|---|
expired_card |
The card's expiration date has passed | Ask customer to update card |
stolen_card |
The card has been reported stolen | Do not retry; contact customer |
lost_card |
The card has been reported lost | Do not retry; contact customer |
card_not_supported |
The card type isn't accepted | Ask for a different payment method |
fraudulent |
The bank suspects fraud on this card | Do not retry; verify account |
Key insight: The single most common decline code is
insufficient_funds, which accounts for roughly 35-45% of all failed subscription charges. It is also one of the most recoverable — the customer's card works fine, they just didn't have enough money at the exact moment Stripe tried to charge them.
The Revenue Impact: Why This Matters More Than You Think
Failed payments cause involuntary churn — customers who leave not because they wanted to, but because their payment didn't go through and nobody fixed it. This is distinct from voluntary churn (cancellations) and it's often the larger source of customer loss.
Here's how the math works for a typical SaaS company:
- Average failure rate: 5-7% of charges per billing cycle
- Default recovery rate without intervention: Stripe's built-in retry recovers ~15-25%
- Net loss: 4-6% of MRR walks out the door every month
On $50K MRR, that's $2,000-$3,000 per month. Over a year, the compound loss — because each lost customer's future payments are also gone — adds up to $36,000-$54,000. For many startups, that's the difference between default-alive and default-dead.
Revenue lost to failed payments compounds because you lose not just this month's charge, but every future month of that customer's subscription. A customer paying $100/month who churns involuntarily in January costs you $100 in January, $200 by February, $300 by March — $1,200 by year's end. Multiply that across dozens of failed payments per month and the number gets painful fast.
Stripe's Built-In Retry Logic (And Why It's Not Enough)
Stripe does retry failed subscription payments automatically through its Smart Retries feature. It uses machine learning to pick retry times based on patterns it sees across its entire network. That sounds great in theory.
In practice, there are three problems:
- No visibility or control. You can't see when Stripe will retry, why it chose that time, or adjust the strategy. It's a complete black box. If Stripe's algorithm doesn't work well for your specific customer base, you have no lever to pull.
- Limited dunning support. Stripe can send basic dunning emails, but they're generic, not customizable per decline reason, and they don't adapt tone over time. You can't send a warm "heads up, your card was declined" on day one and a more urgent "your account will be paused" on day seven.
- Recovery rate ceiling. Most companies report that Stripe's built-in retries recover 15-25% of failed charges. That's better than nothing, but it leaves 75-85% of the recoverable revenue on the table. A dedicated recovery system with smart retry timing and dunning emails typically recovers 30-70%.
Stripe's Smart Retries are a reasonable baseline. They are not a recovery strategy.
Smart Retry Timing: When to Retry Based on Decline Code
The biggest leverage in payment recovery is retrying at the right time. "Right time" varies by decline code because the underlying cause is different.
Insufficient Funds: Align with Pay Cycles
When a card is declined for insufficient funds, the customer's account balance is temporarily too low. The most effective retry windows align with common payroll deposit dates:
- First retry: 3 days after failure (catches weekly pay deposits)
- Second retry: 5 days after failure (catches bi-weekly pay deposits)
- Third retry: First of the following month (catches monthly pay deposits)
This single strategy — aligning retries with pay cycles for insufficient_funds declines — can recover an additional 15-25% of failed charges that would otherwise be lost.
Generic Declines: Give the Bank Time
When the bank returns generic_decline, it often means their fraud detection algorithm flagged the charge. After a cooling-off period, the same charge frequently goes through:
- First retry: 24 hours later
- Second retry: 72 hours later
- Third retry: 7 days later
Processing Errors: Retry Quickly
A processing_error is almost always transient — a hiccup at the bank, the card network, or Stripe itself. These recover at very high rates with fast retries:
- First retry: 2 hours later
- Second retry: 6 hours later
- Third retry: 24 hours later
Expired Cards: Don't Retry, Notify
An expired card will never work no matter how many times you retry. Instead, immediately send the customer a notification asking them to update their payment method. Provide a direct link to your billing portal or card update page — every extra click you add reduces the update rate.
Pro tip: Time your retry attempts for off-peak hours (early morning or late evening in the customer's timezone). Banks process fewer transactions during these windows, which means lower fraud-detection sensitivity and higher approval rates. Some recovery tools report a 5-12% improvement just from optimizing retry timing within the day.
Dunning Emails: The Human Side of Recovery
Smart retries handle the technical side. Dunning emails handle the human side. Even when retries succeed, sending a notification lets the customer know something happened and builds trust. When retries fail, dunning emails are your only path to getting the customer to update their payment method.
An effective dunning sequence uses three emails with escalating urgency:
Email 1: The Gentle Nudge (Day 0)
Sent immediately when the payment fails. Tone: friendly, no-pressure. The goal is to inform, not alarm.
- Subject: "Quick heads up about your payment"
- Mention the specific issue ("your card ending in 4242 was declined")
- Reassure that their account is still active
- Include a one-click link to update their payment method
Email 2: The Clear Ask (Day 3)
Sent if the payment still hasn't gone through after the first retry attempts. Tone: direct and helpful.
- Subject: "Action needed: update your payment method"
- Remind them what they'll lose access to (feature-specific, not generic)
- Provide the update link prominently
- Mention that you've been retrying automatically
Email 3: The Final Notice (Day 7)
Sent before the subscription is cancelled. Tone: urgent but respectful.
- Subject: "Your [Product] subscription will be cancelled tomorrow"
- State a specific deadline
- Make the update link the most prominent element
- Express genuine desire to keep them as a customer
This three-step sequence is standard because it works. The key principles: escalating urgency, specific deadlines, and making the update action as frictionless as possible.
Manual Recovery vs. Automated Recovery
You can manage payment recovery manually. Some founders do it with spreadsheets, Stripe dashboard filters, and personal emails. Here's what that looks like at different scales:
| Customers | Failed Payments/Month | Manual Time | Practical? |
|---|---|---|---|
| 100 | 5-9 | 1-2 hours | Manageable |
| 500 | 25-45 | 5-10 hours | Painful |
| 1,000 | 50-90 | 15-25 hours | Unsustainable |
| 5,000 | 250-450 | 60+ hours | Impossible |
The breakpoint is usually around 200-300 customers. Below that, manual recovery is annoying but doable. Above that, you either automate or you accept the revenue loss.
Automated recovery tools work by:
- Listening to webhooks — detecting failed payments the moment they happen
- Classifying the decline — reading the decline code to determine the right strategy
- Scheduling smart retries — timing retries based on the decline reason, not a fixed schedule
- Sending dunning emails — delivering the right message at the right time
- Tracking outcomes — measuring recovery rate, revenue recovered, and identifying patterns
How RecoverStripe Automates This
RecoverStripe connects to your Stripe account via OAuth and sets up webhook listeners for payment events. When a charge fails, it:
- Reads the decline code and classifies it as a hard or soft decline
- For soft declines, schedules retries at optimal intervals based on the specific decline reason
- For hard declines, immediately triggers a dunning email asking the customer to update their payment method
- Runs a 3-step dunning sequence in parallel with retries, escalating from friendly to urgent
- Tracks every recovery attempt and outcome on a dashboard that shows your recovery rate, revenue saved, and trends over time
Setup takes about two minutes: connect your Stripe account, and RecoverStripe starts monitoring. There's no code to write, no webhooks to configure, and no emails to set up.
Measuring Your Recovery Rate
If you want to benchmark your current situation, here are the numbers to pull from your Stripe dashboard:
- Failed charge count: In Stripe Dashboard, go to Payments > filter by status "Failed" for the last 30 days
- Total charge count: Total successful + failed charges in the same period
- Failure rate: Failed / Total. If this is above 5%, you have a problem worth solving
- Recovery rate: Of the failed charges, how many eventually succeeded (through Stripe's retries or manual intervention)?
Benchmarks to compare against:
- Good: Less than 3% failure rate, more than 50% recovery rate
- Average: 3-7% failure rate, 20-35% recovery rate
- Needs work: Over 7% failure rate, under 20% recovery rate
Key Takeaways
Failed payment recovery isn't complicated, but it does require deliberate systems. The core principles:
- Classify every decline by code — your response should differ for
insufficient_fundsvs.expired_cardvs.processing_error - Retry soft declines at intervals matched to the decline reason, not on a fixed schedule
- Send dunning emails that escalate in urgency and always include a direct link to update payment
- Measure your failure rate and recovery rate monthly — you can't improve what you don't track
- Automate once you pass ~200 customers, because manual recovery doesn't scale
The SaaS companies that treat failed payment recovery as a core business process — rather than an occasional annoyance — consistently retain 2-5% more of their MRR each month. Over a year, that compounds into a meaningful difference in revenue trajectory.