Stripe Decline Codes: Complete Reference Guide
Stripe translates raw bank decline codes (ISO 8583) into its own simplified set of decline reason codes. While this makes the developer experience cleaner, it also means some nuance is lost in translation. This comprehensive reference maps every Stripe decline code to its meaning, whether it's a soft or hard decline, the optimal retry strategy, and the equivalent ISO 8583 code where applicable. Understanding Stripe's decline taxonomy is essential for any SaaS using Stripe Billing.
Affected Percentage
N/A — reference guide for all Stripe declines
Recovery Rate
Varies by code: 10-95% depending on decline type
Recommended Action
Retry with strategy
Key Concepts
Stripe-specific code mapping
Stripe maps hundreds of ISO 8583 bank codes to roughly 30 simplified decline reasons. Multiple bank codes can map to the same Stripe code, losing specificity.
Radar fraud detection
Stripe's built-in fraud detection (Radar) can decline transactions independently of the bank. These show as "fraudulent" in the decline reason but weren't necessarily declined by the bank.
Stripe risk evaluation
Stripe may block charges it deems high-risk to protect its own platform, even if the bank might have approved them. These are labeled "highest_risk_level" in the risk assessment.
Webhook and API configuration
Incorrect webhook handling or API integration issues can cause Stripe to report declines that are actually integration failures on the merchant side.
Recommended Retry Strategy
Timing
Varies by code. Soft declines (insufficient_funds, processing_error): retry in 1-7 days. Hard declines (expired_card, stolen_card): do not retry, trigger outreach. See the code-by-code breakdown below.
Max Retries
Depends on the specific code. Stripe Smart Retries (if enabled) handles this automatically.
Reasoning
Stripe provides a decline_code field in the Charge object that tells you exactly what happened. Using this code to route to the correct recovery workflow — retry vs. outreach vs. card updater — is the most effective approach.
Best Practices
- 1
Parse the decline_code field from the Stripe charge response (not just the generic "card_declined" error) to route to specific recovery workflows.
- 2
Enable Stripe Smart Retries in Stripe Billing if you're using Subscriptions — it automatically retries soft declines with ML-optimized timing.
- 3
Configure Stripe Radar rules carefully to minimize false positive fraud blocks while still catching real fraud.
- 4
Use Stripe's built-in card updater integration (automatic_payment_methods) to keep card details fresh without customer intervention.
- 5
Monitor the payment_intent.payment_failed webhook to capture detailed decline data for analytics and recovery workflow triggering.
How Rezoki Handles This Automatically
Rezoki integrates deeply with Stripe's decline taxonomy. When a payment fails in Stripe, Rezoki reads the specific decline_code and maps it to the optimal recovery workflow. For soft declines like insufficient_funds, Rezoki schedules smart retries that complement (and can replace) Stripe's built-in Smart Retries with even more sophisticated timing. For hard declines like expired_card, Rezoki bypasses retries entirely and goes straight to dunning outreach. Rezoki also monitors Stripe Radar blocks and can distinguish between true fraud and false positives, recovering revenue that Stripe's conservative fraud rules might otherwise block.