Credit Card Decline Codes: What They Mean and What to Do About Each One
A payment just failed. Stripe says "card_declined" and your customer has no idea. This is every decline code you'll encounter, what each one actually means, and exactly what to do about it.

Written by
Gerard Hill
Founder of Dunning Lite. 12+ years in digital marketing and SEO, former CTO, Google Partner, and two Masters in Digital Marketing. Built Dunning Lite after watching his own micro-SaaS lose hundreds in MRR to expired cards — and realizing every recovery tool on the market was built for companies 10x his size.
Executive Summary (TL;DR)
- •Decline codes are responses from the issuing bank explaining why a payment failed. They split into soft declines (retry) and hard declines (contact customer).
- •"Do Not Honor" and "Insufficient Funds" alone account for ~76% of all declines. Knowing how to handle just these two codes recovers the majority of failed revenue.
- •Never retry a hard decline (expired card, stolen card). It won't work and can trigger Mastercard penalties starting at $0.50 per violation.
- •For SaaS founders: building your response around decline types — not sending generic 'payment failed' emails — is what separates 40% recovery from 80%.
What Are Credit Card Decline Codes?
A credit card decline code is the issuing bank's way of telling you why a payment didn't go through. Instead of just saying "nope," the bank sends back a code — usually a two-digit number or a short string — that explains what happened. Insufficient funds? There's a code for that. Expired card? Code for that too. Bank just feels suspicious about a Tuesday afternoon transaction? Yep, there's a code for that (it's the wonderfully vague "Do Not Honor").
For SaaS founders running subscriptions on Stripe, these codes are the difference between recovering a failed payment and losing a customer silently. They tell you whether to retry the charge, email the customer, or stop trying altogether. Ignore them, and you're basically treating a headache and a broken leg with the same aspirin.
Where Decline Codes Come From (The Chain)
When a payment fails, the decline code travels through a chain before it reaches you:
Each layer can translate or normalize the code. The bank sends a raw ISO 8583 code, Visa or Mastercard categorizes it, and Stripe translates it into something human-readable like insufficient_funds or expired_card. By the time it reaches your webhook, it's already been interpreted — which is actually helpful, because raw bank codes are about as readable as assembly language.
Hard Declines vs. Soft Declines: The Only Classification That Matters
Every decline code on the planet falls into one of two buckets. Get this distinction right and you'll handle 90% of payment failures correctly. Get it wrong and you'll waste retries on dead cards while ignoring recoverable revenue.
Soft Declines: Retry-Worthy
A soft decline means something temporary went wrong. The card is valid, the account exists, but right now the payment can't go through. Common reasons:
- Insufficient funds — The customer doesn't have the money today. They might on Friday.
- Processing error — The bank's system hiccuped. Retry in a few hours.
- Generic decline / Do Not Honor — The bank said no without saying why. Often resolves on retry.
- Card activity limit — Too many transactions today. Try tomorrow.
Soft declines make up roughly 80% of all payment failures. Most of them can be recovered with smart retry timing — no customer email needed.
Hard Declines: Stop Retrying, Start Communicating
A hard decline means the payment method is dead. Retrying won't help — and actually makes things worse. Mastercard's excessive authorization penalties hit $0.50 per violation, and they're expanding in 2026. Not a bill you want.
- Expired card — The card's past its expiry date. New card required.
- Stolen/lost card — Flagged by the bank. Do NOT retry.
- Invalid card number — Typo or cancelled card. Needs new payment method.
- Authentication required — SCA/3D Secure needed. Customer must act.
The right response to a hard decline is always the same: contact the customer. Send them an email explaining what happened and give them a one-click link to update their payment details. If you need templates for this, check our dunning email examples.
| Soft Decline | Hard Decline | |
|---|---|---|
| Nature | Temporary | Permanent |
| Should you retry? | Yes — with smart timing | Never |
| Contact customer? | Only if retries fail | Immediately |
| % of all declines | ~80% | ~20% |
| Examples | Insufficient funds, processing error, generic decline | Expired card, stolen card, invalid number |
The Complete Decline Code Reference Table
Bookmark this. Every decline code you'll realistically encounter as a SaaS founder, what it means, and what to do about it — all in one place.
| Code | Name | Type | What It Means | What to Do |
|---|---|---|---|---|
| 05 | Do Not Honor | Soft | Bank refused without a specific reason | Retry after 24h. If it fails again, email customer. |
| 51 | Insufficient Funds | Soft | Not enough money in the account | Retry in 3-5 days (around payday: 1st or 15th). |
| 54 | Expired Card | Hard | Card is past its expiry date | Email customer immediately. Do NOT retry. |
| 41 | Lost Card | Hard | Card reported lost by cardholder | Do NOT retry. Email for new payment method. |
| 43 | Stolen Card | Hard | Card reported stolen | Do NOT retry. Email for new payment method. |
| 14 | Invalid Card Number | Hard | Card number doesn't exist or is wrong | Email customer to re-enter payment details. |
| 65 | Activity Limit Exceeded | Soft | Too many transactions in a short period | Retry next day. |
| 01 | Refer to Issuer | Soft | Bank wants to verify the transaction | Retry after 24h. Customer may need to call bank. |
| 12 | Invalid Transaction | Hard | Transaction type not supported | Check your Stripe integration. Don't retry. |
| 13 | Invalid Amount | Hard | Amount exceeds allowed limits | Verify charge amount. May need split payment. |
| 57 | Transaction Not Permitted | Hard | Card type doesn't support this transaction | Email customer. They need a different card. |
| 62 | Restricted Card | Hard | Card has geographic or merchant restrictions | Email customer. They need to call their bank. |
| 63 | Security Violation | Hard | CVV/CVC check failed | Email customer to re-enter card details. |
| 91 | Issuer Unavailable | Soft | Bank's system is temporarily down | Retry in 2-4 hours. |
| 96 | System Error | Soft | Processing network error | Retry in 2-4 hours. |
| R0/R1 | Stop Recurring | Hard | Customer asked their bank to stop this subscription | Do NOT retry. Treat as voluntary cancellation. |
The Most Common Codes — Explained in Detail
According to Visa's Global Declines Transaction Analysis, "Do Not Honor" (05) and "Insufficient Funds" (51) account for approximately 76% of all declined transactions. Handle just these two correctly and you've addressed the vast majority of your failed payments.
Do Not Honor
SoftThe most common and most frustrating code. The bank said no, but won't tell you why. It could be fraud suspicion, daily limits, account flags, or the bank's risk engine just being cautious. Retry once after 24 hours — if it fails again, email the customer. They may need to call their bank to authorize the charge.
Insufficient Funds
SoftThe customer doesn't have the money right now. The key word is 'right now' — they probably will on payday. Retry around the 1st or 15th of the month, or 3-5 days after the initial failure. This code alone accounts for 44% of all declines according to Ethoca data.
Expired Card
HardThe card's expiry date has passed. This will never resolve on its own — the customer needs to provide a new card. If you have card updater services enabled (Visa Account Updater, Mastercard ABU), many of these get prevented automatically. If not, send an email immediately with a direct link to update payment details.
Authentication Required (SCA/3DS)
HardIncreasingly common in Europe due to PSD2 regulations. The bank requires the customer to complete a 3D Secure authentication step — this can't be done automatically. Send them a Stripe-hosted payment link where they can complete the verification. Don't retry the original charge; it will fail every time.
Generic Decline
SoftStripe's catch-all when the issuer doesn't provide a specific code. Similar to 'Do Not Honor' but even less helpful. Retry once after 24 hours. If it persists, email the customer — there's likely an account issue only they can resolve with their bank.
Stripe Decline Codes: A Developer's Quick Reference
If you're on Stripe (and if you're reading this, you probably are), Stripe translates raw bank codes into its own human-readable format. You get these in the invoice.payment_failed webhook event under payment_intent.last_payment_error.decline_code.
Here are the Stripe-specific codes you'll see most often and how they map to what we've covered above:
| Stripe Code | Type | Action |
|---|---|---|
| insufficient_funds | Soft | Retry in 3-5 days |
| card_declined | Soft | Retry after 24h, then email |
| generic_decline | Soft | Retry after 24h, then email |
| do_not_honor | Soft | Retry after 24h, then email |
| expired_card | Hard | Email immediately — no retry |
| fraudulent | Hard | Do NOT retry. Review account. |
| lost_card | Hard | Do NOT retry. Email for new card. |
| stolen_card | Hard | Do NOT retry. Email for new card. |
| incorrect_cvc | Hard | Email to re-enter card details |
| incorrect_number | Hard | Email to re-enter card details |
| authentication_required | Hard | Send payment link for 3DS |
| processing_error | Soft | Retry in 2-4 hours |
| card_not_supported | Hard | Email — need different card |
| currency_not_supported | Hard | Check your Stripe currency settings |
For a step-by-step guide on handling these in your Stripe integration — including webhook setup and retry logic — read our guide to recovering failed Stripe payments. For the developer's playbook — including webhook code, retry logic, and SCA handling — see our Stripe decline codes developer guide.
What to Do When a Payment Is Declined (The Founder's Playbook)
Knowing what each code means is only half the job. The other half is responding correctly — and quickly. Here's the decision tree:
For Soft Declines → Smart Retry
Don't just retry immediately. Time it based on the code: insufficient funds → wait for payday; processing error → retry in hours; generic decline → retry next day. This approach alone can recover 15-30% of failures without the customer ever knowing there was a problem. See our smart retry timing guide for the full playbook.
For Hard Declines → Customer Email
Send an email within hours. Be specific about what happened — "your card ending in 4242 has expired" is infinitely more helpful than "your payment failed." Include a one-click link to update their payment method. Check our dunning email templates for ready-to-use examples tailored to each decline type.
For Authentication Declines → Payment Link
SCA/3D Secure declines can't be retried automatically. The customer needs to complete the authentication step themselves. Send a Stripe-hosted payment link where they can re-enter their card and complete 3DS verification. This is increasingly common for European customers under PSD2.
How Decline Codes Connect to Involuntary Churn
Here's why all of this matters for your bottom line: every unhandled decline code is a customer walking out the door without knowing they left.
Industry data tells a clear story: 20-40% of total SaaS churn is involuntary — caused entirely by failed payments. And across the subscription economy, 15-25% of recurring payments get declined on the first attempt. If your only response to that is Stripe's default retry logic, you're recovering roughly 15-22% of those failures. The rest? Gone.
The good news: SaaS companies have the highest past-due recovery rate of any industry at 53.5% (Recurly benchmarks). With a proper decline-code-aware dunning system — smart retries for soft declines, targeted emails for hard declines, card updaters for prevention — that number climbs to 70-85%.
If you want to understand the full picture of how payment failures connect to churn, read our guide to involuntary churn. To see the revenue impact on your specific numbers, try our Lost MRR Calculator.
5 Ways to Reduce Your Decline Rate
Handling decline codes after they happen is essential. But the real win is preventing declines before they happen. These five strategies can reduce your decline rate by 15-30%:
Enable Card Updaters
Visa Account Updater and Mastercard ABU automatically refresh expired card numbers before the next billing cycle. Stripe supports this natively. Enabling it prevents the single most common hard decline — expired cards — without the customer doing anything.
Use Network Tokenization
Network tokens replace raw card numbers with processor-agnostic tokens that update automatically when a card is reissued. Stripe handles this behind the scenes if you're using Payment Intents. Higher auth rates, fewer declines, better security.
Retry Based on Decline Type
Stop retrying on a fixed schedule. Insufficient funds? Retry around payday. Processing error? Retry in hours. Expired card? Don't retry at all. This single change can improve your recovery rate by 15-30%.
Send Pre-Billing Notifications
Notify customers 3 days before a charge hits. This gives them time to ensure funds are available, update an expiring card, or whitelist the charge with their bank. Simple to implement, surprisingly effective.
Offer Alternative Payment Methods
If one card fails, make it easy to try another. Support multiple cards, bank transfers, or digital wallets. The fewer barriers to payment, the higher your recovery rate. Stripe makes adding payment methods straightforward.
For a detailed comparison of tools that automate all of this, check our dunning software comparison. For the full dunning strategy — prevention, recovery, and escalation — read our complete dunning management guide.
Frequently Asked Questions
What are credit card decline codes?+
What does decline code 05 ('Do Not Honor') mean?+
What is the difference between a hard decline and a soft decline?+
Can a declined card be retried?+
Why is my card declined when I have money?+
How do decline codes affect SaaS subscription revenue?+
What is the best way to handle authentication_required declines?+
Let decline codes handle themselves
Dunning Lite reads the decline code from every failed Stripe payment and responds accordingly — smart retries for soft declines, targeted emails for hard declines, payment links for authentication failures. You connect Stripe in two clicks and go back to building your product. $29/month flat.