# Subscription payment decline codes guide for Stripe

{% hint style="info" %}
**TL;DR:** When a subscription payment fails, your processor returns a decline code that tells you why. The problem: codes are inconsistent across networks and processors, and the most common one — "Do Not Honor" — tells you almost nothing. This guide maps every common decline code to a specific recovery strategy, so you can stop treating all failures the same and start recovering more of each type.
{% endhint %}

## Subscription Payment Decline Codes: What They Mean and How to Recover Each One

***

### How Decline Codes Work: The Anatomy of a Failed Payment

When a customer's payment is attempted, the request flows through a chain: your payment processor (e.g., Stripe) → the card network (Visa, Mastercard) → the issuing bank. The issuing bank makes the approve/decline decision and returns a response code that travels back up the chain.

What you see in your Stripe dashboard is Stripe's interpretation of the bank's response — which is often more descriptive than the raw network code, but still imperfect.

#### The Three-Layer Code Problem

| Layer                          | Code Format                  | Example             | What You See                   |
| ------------------------------ | ---------------------------- | ------------------- | ------------------------------ |
| **Issuing bank**               | Raw response code (DE 39)    | `05`                | You don't see this directly    |
| **Card network**               | Standardized network code    | `05 — Do Not Honor` | Available via Stripe API       |
| **Payment processor (Stripe)** | Stripe-specific decline code | `generic_decline`   | What appears in your dashboard |

This layering creates a translation problem. The bank's raw code gets interpreted by the network, then re-interpreted by Stripe. Nuance is lost at each step. A single Stripe code like `generic_decline` can represent a dozen different underlying bank decisions.

***

### Soft Declines vs. Hard Declines: The Critical Distinction

This is the single most important concept in payment recovery. Every decline falls into one of two categories, and your response to each should be completely different.

#### Soft vs. Hard Decline Comparison

| Characteristic                     | Soft Decline                                             | Hard Decline                                              |
| ---------------------------------- | -------------------------------------------------------- | --------------------------------------------------------- |
| **Nature**                         | Temporary — may resolve on its own                       | Permanent — won't resolve without action                  |
| **% of all subscription failures** | 60–70%                                                   | 30–40%                                                    |
| **Can be recovered with retries?** | Yes — often without customer knowing                     | No — requires customer to update payment                  |
| **Examples**                       | Insufficient funds, processing error, issuer unavailable | Expired card, invalid number, stolen card, account closed |
| **Optimal response**               | Silent retry with optimized timing                       | Dunning email with card update link                       |
| **Recovery potential**             | High (70–90% with smart timing)                          | Medium (40–60% with good dunning)                         |
| **Danger of retrying**             | Low (within network limits)                              | Wastes retries and risks network fines                    |

The golden rule: Exhaust smart retries on soft declines before contacting the customer. Send dunning communications immediately for hard declines.

***

### Complete Decline Code Reference: Every Code, Every Recovery Strategy

#### Soft Declines — High Recovery Potential (Retry First)

| Code    | Stripe Code                        | Meaning                                      | % of Failures | Recovery Strategy                                                                                      | Expected Recovery Rate               |
| ------- | ---------------------------------- | -------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------ |
| **51**  | `insufficient_funds`               | Customer doesn't have enough money           | 30–40%        | Retry around paydays (1st, 15th of month), morning hours in customer's timezone. Don't retry same day. | 70–85% with optimized timing         |
| **05**  | `generic_decline` / `do_not_honor` | Bank refused — no specific reason given      | 15–25%        | ML-optimized retries at varied times. May resolve on its own. This is the "black box" code.            | 40–60% depending on underlying cause |
| **91**  | `issuer_not_available`             | Bank systems temporarily down                | 3–5%          | Retry within 4–24 hours. Almost always succeeds on next attempt.                                       | 90%+                                 |
| **06**  | `processing_error`                 | Generic processing failure                   | 3–5%          | Retry within 24–48 hours with different timing window.                                                 | 80–90%                               |
| **65**  | `card_velocity_exceeded`           | Too many transactions in short period        | 1–3%          | Wait 24–48 hours, then retry. Card's daily limit has been hit.                                         | 70–80%                               |
| **61**  | `withdrawal_amount_exceeds_limit`  | Transaction exceeds card's transaction limit | 1–2%          | Retry after 24 hours. If recurring, consider splitting into smaller amounts.                           | 60–75%                               |
| **N/A** | `try_again_later`                  | Temporary issuer issue                       | 2–4%          | Retry within 4–12 hours.                                                                               | 85–95%                               |

#### Hard Declines — Customer Action Required (Dunning Immediately)

| Code    | Stripe Code                                      | Meaning                               | % of Failures | Recovery Strategy                                                                                                                  | Expected Recovery Rate                 |
| ------- | ------------------------------------------------ | ------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| **54**  | `expired_card`                                   | Card past its expiration date         | 10–15%        | First check if Card Account Updater / Network Tokens can auto-replace. If not, send dunning email with one-click card update link. | 60–80% (with CAU), 40–55% (email only) |
| **14**  | `invalid_number`                                 | Card number doesn't exist or is wrong | 2–3%          | Dunning email requesting customer re-enter card details.                                                                           | 35–50%                                 |
| **43**  | `stolen_card`                                    | Card reported stolen                  | 1–2%          | Do NOT retry. Send gentle notification asking for alternative payment method.                                                      | 30–40%                                 |
| **41**  | `lost_card`                                      | Card reported lost                    | 1–2%          | Similar to stolen — Network Tokens may auto-update. Otherwise dunning email.                                                       | 40–55% (with tokens), 30–40% (without) |
| **04**  | `pickup_card`                                    | Bank wants the card seized            | <1%           | Do not retry. Contact customer for new payment method.                                                                             | 20–30%                                 |
| **N/A** | `card_declined` (with `do_not_try_again` advice) | Terminal decline — bank says stop     | 2–3%          | Do not retry. Immediate dunning with card update form.                                                                             | 30–45%                                 |

#### Authentication Declines — Requires Customer Interaction

| Code    | Stripe Code               | Meaning                          | % of Failures    | Recovery Strategy                                                                                     | Expected Recovery Rate |
| ------- | ------------------------- | -------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- | ---------------------- |
| **N/A** | `authentication_required` | 3D Secure / SCA challenge needed | 5–10%            | Send email with payment link that triggers authentication flow. In-app notification for active users. | 50–65%                 |
| **N/A** | `3ds_required`            | European SCA mandate             | Region-dependent | Redirect customer to complete 3DS verification. Cannot be solved with silent retries.                 | 55–70% with good UX    |

#### Fraud-Related Declines — Handle with Care

| Code    | Stripe Code       | Meaning                               | % of Failures | Recovery Strategy                                                                                                                                          | Expected Recovery Rate          |
| ------- | ----------------- | ------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| **N/A** | `fraudulent`      | Stripe Radar or bank flagged as fraud | 3–5%          | If Stripe blocked: review in Dashboard, add to allowlist if legitimate. If bank-flagged: customer must call bank.                                          | 25–40%                          |
| **59**  | `suspected_fraud` | Bank suspects fraud                   | 2–3%          | Do not retry aggressively. Time-of-day and geography matter — a 3 AM charge from an unusual location gets flagged more often. Retry during business hours. | 30–50% with timing optimization |

***

### The "Do Not Honor" Problem: Solving the Black Box

Code 05 / `do_not_honor` / `generic_decline` deserves special attention because it's both the most common and the least informative decline code in subscription billing.

#### Why "Do Not Honor" Is So Common

When a bank declines a transaction but doesn't want to reveal the specific reason (privacy, competitive reasons, or simply lazy classification), they return code 05. It's a catch-all that can actually mean:

* Insufficient funds (the bank just doesn't say so)
* Velocity limit exceeded
* Temporary security hold
* Risk scoring threshold exceeded
* Card restrictions (e.g., international transactions blocked)
* Account under review

#### Recovery Strategies for "Do Not Honor" by Pattern

| Pattern Signal                              | Likely Underlying Cause                | Recommended Action                          |
| ------------------------------------------- | -------------------------------------- | ------------------------------------------- |
| First-time failure, customer is active      | Temporary hold or insufficient funds   | Retry in 24–48 hours, different time of day |
| Repeat failures on same day each month      | Insufficient funds, timing-related     | Shift retry to post-payday window           |
| Failure occurs at unusual hour (3 AM local) | Fraud risk scoring                     | Retry during 9 AM–12 PM local time          |
| New card recently added                     | Issuer restriction on new cards        | Wait 5–7 days, then retry                   |
| International card, domestic merchant       | Cross-border risk block                | If possible, route through local acquirer   |
| Failure after period of successful charges  | Temporary bank hold or security review | Retry in 48–72 hours                        |

This is where ML models shine. A human looking at "Do Not Honor" sees a dead end. A model that has analyzed millions of these declines across card types, issuers, geographies, and time patterns can predict the underlying cause and apply the right recovery strategy.

FlyCode's internal classifiers disaggregate generic decline codes using hundreds of data points per transaction — turning a black box into an actionable recovery plan.

***

### Card Account Updater and Network Tokens: The Silent Heroes

Before you ever send a dunning email for an expired card, make sure you've enabled the tools that can fix it automatically.

#### Automatic Card Update Mechanisms

| Feature                        | What It Does                                                                         | Who Provides It                                     | Recovery Impact                                                          |
| ------------------------------ | ------------------------------------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------------------ |
| **Card Account Updater (CAU)** | Automatically replaces expired card details with new ones from the network           | Visa VAU, Mastercard ABU — available through Stripe | Prevents 60–80% of expired card failures                                 |
| **Network Tokenization**       | Creates a persistent token that updates automatically when the physical card changes | Visa, Mastercard — supported by Stripe              | Reduces card-on-file failures by 2–5% across all types                   |
| **Backup card charging**       | Automatically charges an alternate card on file when the primary fails               | Not native in Stripe — available via FlyCode        | Recovers 10–15% of failures that would otherwise require customer action |

Implementation check: Network Tokenization and Card Account Updater should be active by default on most Stripe accounts. Verify by checking if you're seeing `card_updated` events in your webhook logs. If you're not seeing them, contact Stripe support.

***

### Recovery Timing Optimization: When to Retry Each Code

Timing isn't just "wait and try again." Different decline types have different optimal retry windows.

#### Optimal Retry Timing by Decline Type

| Decline Type                | First Retry                        | Second Retry                          | Third Retry                  | After 3 Fails                                               |
| --------------------------- | ---------------------------------- | ------------------------------------- | ---------------------------- | ----------------------------------------------------------- |
| **Insufficient funds**      | 48–72 hours (wait for payday)      | 5–7 days (next payday cycle)          | Day 14–15 (mid-month payday) | Dunning email with card update                              |
| **Processing error**        | 4–12 hours                         | 24 hours                              | 48 hours                     | Investigate — may indicate integration issue                |
| **Do Not Honor**            | 24–48 hours, different time of day | 4–5 days, morning hours               | 7–10 days                    | If still failing, likely a hard decline — switch to dunning |
| **Issuer unavailable**      | 4–6 hours                          | 12–24 hours                           | 48 hours                     | Rare to need 3 retries — should succeed quickly             |
| **Expired card**            | Don't retry — wait for CAU update  | After 48 hours (CAU may have updated) | 5 days                       | Dunning email with card update link                         |
| **Authentication required** | Don't retry — send auth link       | 3 days (reminder email)               | 7 days (urgency email)       | In-app paywall or feature restriction                       |

***

### Conclusion: Stop Treating All Declines the Same

The single biggest mistake in payment recovery is applying the same retry schedule and communication sequence to every failed payment. An insufficient funds decline and an expired card decline require fundamentally different responses.

The companies that recover 70–90% of their failed payments do three things differently: they classify every decline by type and adjust their strategy accordingly, they exhaust silent retries before involving the customer, and they use ML models that learn from their specific transaction patterns — not from the global average.

***

Take action:

* <https://www.flycode.com/churn-audit-failed-payments> — Get a free payment audit — See your decline code distribution and recovery rate by type.
* <https://www.flycode.com/revenue-recovery-calculator> — Calculate your recovery ROI.
* <https://marketplace.stripe.com/apps/flycode-payments> — Install FlyCode for Stripe.

***

#### Related Reading

* <https://www.flycode.com/blog/stripe-generic-decline-code-what-it-means-why-it-happens-and-how-flycode-recovers-the-revenue>
* <https://www.flycode.com/blog/the-do-not-honor-decline-code-what-subscription-businesses-need-to-know>
* <https://www.flycode.com/blog/what-are-issuer-declines-in-stripe-failed-payment-report>
* <https://www.flycode.com/blog/subscription-ghosting-when-"insufficient-funds"-steals-your-mrr>
* <https://www.flycode.com/blog/how-to-deal-with-failed-payments-if-you-re-using-stripe>
