Skip to content

The Recovery Ledger · 2026-07-11 · 6 min

Stripe decline codes, explained for recovery (not just debugging)

Decline codes usually get read by engineers debugging checkout. Read them as a revenue operator instead: each code tells you whether a retry can work and what the recovery email should say.

expired_card

Retries: pointless the number fails forever. Recovery: guaranteed possible; the customer has a newer card. Email should say exactly that ('your card on file expired') with the update link. Better: warn before expiry and skip the failure.

insufficient_funds

Retries: often work Smart Retries time them around paydays. Recovery email: gentle, no-blame, 'the invoice link retries whenever you're ready.' Most of these self-heal; the email is there for the ones that don't.

do_not_honor

The bank's 'no, and we won't say why.' Retries sometimes work (it can be a temporary risk flag). Email: generic-decline copy suggesting the customer try the card again or use another and to call the bank if it persists. Never guess at the reason in your copy.

card_declined / generic_decline

The catch-all. Treat like do_not_honor: one retry cycle, then human email with the hosted invoice link. If the same customer hits this repeatedly across months, the card is effectively dead say so kindly.

Why per-code copy is worth it

One-size dunning copy reads wrong for somebody: 'your bank declined the charge' insults the expired-card customer; 'your card expired' confuses the insufficient-funds one. Recoupe generates a variant per decline reason automatically (AI-drafted, cached, fully editable), so every email matches reality.

See your failures broken down by decline code free audit →

Recoupe recovers the revenue your processor's retries leave behind $29/mo, honest attribution.

Run my free failed-payment audit →