lycheeSubscription payment decline codes guide for Stripe

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

circle-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.

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

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.


  • 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

Last updated

Was this helpful?