Stripe's Smart Retries is a managed service that automatically retries failed subscription invoices. It's good. It's also frequently misunderstood — engineers who turn it on assume it handles dunning end-to-end. It doesn't. Here's what it does, what it doesn't, and where the gap matters.
When a subscription invoice's payment fails, Smart Retries (if enabled) automatically schedules retries based on decline code, card type, and historical recovery patterns Stripe has aggregated across its network. The defaults retry up to 4 times over a configurable window (typically 1–4 weeks), and you can customise the schedule in your Billing settings.
What's good about it:
For a typical B2B SaaS with reasonable card hygiene, Smart Retries alone recovers 30–50% of monthly failed charges.
This is the biggest gap. When a card fails, Stripe's Smart Retries silently retries — it doesn't tell the customer their card failed unless you've configured Stripe's customer emails (which look generic and end up in spam) or built your own. For decline codes like expired_card or do_not_honor where the customer has to do something on their end, retries alone never recover the charge.
The single highest-recovery action for an expired card is to send the customer a unique link to a Stripe-hosted card-update page. Smart Retries doesn't trigger this; you have to build it (or use a tool like DunningKit, Churn Buster, Stunning, or roll your own with Stripe's Customer Portal).
Stripe's dashboard shows you "Failed" invoices. It does not break them down by:
Without this breakdown, it's hard to prioritise: do you build a card-update flow, or focus on customer-side fraud-flag escalation, or scrap dunning entirely and move to net-30 invoicing for big customers?
Smart Retries handles insufficient_funds, generic_decline, and a few common codes well. For lesser codes — card_velocity_exceeded, currency_not_supported, service_not_allowed, fraudulent, incorrect_cvc — the automatic retry timing is more conservative and less effective. Some of these codes need different remediation entirely (e.g. fraudulent needs a fraud-team review, not a retry).
| Decline code | Smart Retries alone | + customer-facing flow |
|---|---|---|
insufficient_funds | ~70% | ~75% (small uplift) |
expired_card | ~5% | ~85% (huge uplift; needs card-update email) |
do_not_honor | ~30% | ~50% (some uplift; customer contacts their issuer) |
generic_decline | ~25% | ~40% |
card_velocity_exceeded | ~10% (Smart Retries waits days) | ~55% (delay 24h, then retry once) |
fraudulent | ~5% | ~30% (manual review case-by-case) |
Numbers are aggregate estimates from across the dunning-tool category; your mileage will vary based on plan tier, customer geography, and card issuer mix.
If you're under $10k MRR, Smart Retries alone is probably fine. The absolute dollars at stake aren't worth a recovery service.
If you're between $10k and $100k MRR, the gap matters. Roughly $300–$3,000/month of recoverable revenue is sitting in the long-tail decline codes that Smart Retries doesn't address well. A $99/mo recovery tool earns its keep at $300+/month of additional recovery, which is the typical case at this MRR range.
Above $100k MRR, you're either already running a dedicated recovery tool or you should be — every percentage point of recovery is meaningful and the engineering cost of a homegrown solution exceeds buying.
DunningKit's open-source CLI can take a Stripe failed-charges CSV and produce the recoverability breakdown above for your specific data — no signup, no integration, just pip install dunningkit.