Stripe Decline Codes Explained: What They Mean and How to Recover
← Back to blog
·10 min read

Stripe Decline Codes Explained: What They Mean and How to Recover

A complete reference of Stripe decline codes, what each one means, whether the payment is recoverable, and the best recovery strategy for each type.

When a payment fails on Stripe, the card issuer returns a decline code explaining why. These codes are your most valuable signal for deciding what to do next: retry the payment, contact the customer, or stop trying altogether.

This guide covers every common Stripe decline code, what it actually means, whether the payment is recoverable, and the best strategy for each.

Where to Find Decline Codes in Stripe

Decline codes appear in several places in your Stripe account:

  • Payments page: Go to Payments, filter by "Failed," and click any failed payment. The decline code appears in the payment details under "Failure reason."
  • Invoice details: For subscription payments, check the invoice. Failed invoices show the decline code from the most recent charge attempt.
  • Stripe API: In the PaymentIntent or Charge object, the decline code is available at last_payment_error.decline_code.
  • Webhooks: The invoice.payment_failed webhook event includes the decline code, which is how dunning tools detect and classify failures automatically.

Soft Declines vs. Hard Declines

The single most important distinction in payment recovery is whether a decline is soft or hard.

Soft declines are temporary. The payment method is still valid, but something prevented the charge from going through right now. These are highly recoverable with proper retry timing. Examples: insufficient funds, processing errors, rate limits.

Hard declines are permanent. The payment method cannot be used, and no amount of retrying will change that. The customer must provide a new payment method. Examples: expired card, stolen card, invalid card number.

~60%
Of failures are soft declines (recoverable with retries)
~30%
Are hard declines (customer must update card)
~10%
Are fraud/security blocks

Treating all declines the same is one of the biggest mistakes in payment recovery. Retrying a hard decline wastes API calls and can increase your decline rate with card networks. Emailing a customer about a temporary processing error is premature and unnecessary.

Common Stripe Decline Codes Reference

CodeMeaningTypeRecovery Strategy
insufficient_fundsThe card does not have enough balance to cover the chargeSoftRetry near common pay dates (1st, 15th of the month)
expired_cardThe card has passed its expiration dateHardDo not retry. Contact the customer to update their card.
card_declinedGeneric decline from the card issuer with no specific reasonSoftRetry in 24-72 hours. If it fails again, contact the customer.
generic_declineThe issuer declined the charge without providing a specific reasonSoftRetry after 24 hours. If repeated, request a card update.
do_not_honorThe issuer has flagged the transaction. Often a fraud or risk signal.SoftRetry once after 24 hours. May clear on its own, but do not retry aggressively.
authentication_requiredThe bank requires 3D Secure authentication (SCA)SoftSend the customer a 3D Secure payment link to complete authentication.
fraudulentThe issuer suspects fraud on this cardHardDo not retry. Do not contact the customer about this card.
stolen_cardThe card has been reported stolenHardDo not retry. Cancel the payment method immediately.
processing_errorA temporary error occurred while processing the chargeSoftRetry immediately or within a few hours.
card_not_supportedThe card does not support this type of transactionHardDo not retry. Ask the customer for a different payment method.
incorrect_numberThe card number is incorrectHardDo not retry. Customer must re-enter their card details.
try_again_laterTemporary issuer issue. The payment should succeed if retried.SoftRetry in 2-4 hours.

The Two Most Common Decline Codes

insufficient_funds and generic_decline together account for over 60% of all payment failures. Both are soft declines and both are highly recoverable, but they require different timing.

60%+
Of all payment failures are insufficient_funds or generic_decline, both soft declines with high recovery potential

Insufficient funds is the most straightforward. The customer does not have enough money in their account right now. The optimal strategy is to retry near common payroll dates. For most customers, the 1st and 15th of the month are when funds are deposited. Retrying the day after a failed payment is almost always pointless for this code.

Generic decline is trickier because the issuer does not tell you why. It could be a temporary fraud flag, a spending limit, or an internal bank policy. The best approach is to retry after 24 hours. If it fails again, send the customer a message asking them to contact their bank or provide a different card.

Hard Declines: When to Stop Retrying

Hard declines require a different playbook. Retrying will not work, and excessive retries can actually harm your business:

  • Higher decline rates with card networks. Visa and Mastercard track your decline-to-transaction ratio. Repeatedly retrying hard declines inflates this ratio and can lead to higher processing fees or account restrictions.
  • Wasted webhook and API capacity. Every retry triggers webhooks and API calls. For hard declines, these are entirely wasted resources.
  • Delayed customer outreach. While you are waiting for retries to fail, the customer could be updating their card if you had contacted them immediately.

For hard declines (expired_card, stolen_card, fraudulent, card_not_supported, incorrect_number), the correct action is to skip retries entirely and contact the customer right away with a link to update their payment method.

Using Decline Codes to Improve Recovery

The difference between a 40% recovery rate and a 70%+ recovery rate often comes down to how well you use decline code data. Here is how to apply it:

Customize retry timing by code. Do not use a fixed retry schedule for all failures. Insufficient funds should be retried on the 1st or 15th. Processing errors should be retried in hours. Generic declines should be retried after 24 hours.

Adjust email urgency by code. A customer with an expired card needs to take action immediately. A customer with a temporary processing error does not need to do anything. Sending a "your payment failed, update your card now" email for a processing error creates unnecessary alarm.

Route hard declines to immediate outreach. When the decline code indicates the card is permanently unusable, skip the retry queue and send the customer a message right away. Every day of delay increases the chance of churn.

Track recovery rates by code. Monitor which decline codes you are recovering and which you are losing. If your insufficient_funds recovery rate is low, your retry timing may be off. If expired_card recovery is low, your customer outreach is not reaching them.

How Rebounce Classifies Decline Codes

Rebounce automatically classifies every failed payment by its Stripe decline code and applies the optimal recovery strategy. Soft declines are retried with timing specific to the decline type. Hard declines skip retries and trigger immediate customer outreach via email and WhatsApp.

This classification happens automatically when a payment fails. There is no manual setup required. You can see the decline code breakdown in your Rebounce dashboard, including recovery rates by code type, so you always know where your revenue is being recovered and where it is being lost.

For a broader look at how dunning tools handle payment recovery, see our comparison of the best dunning tools in 2026.

Frequently Asked Questions

What is the most common Stripe decline code?+

'insufficient_funds' and 'generic_decline' are the two most common decline codes, together accounting for over 60% of all payment failures. Both are soft declines and are highly recoverable with proper retry timing.

What is the difference between a soft decline and a hard decline?+

A soft decline is temporary and the payment may succeed if retried later (e.g., insufficient funds, rate limiting). A hard decline means the card cannot be used and the customer must provide a new payment method (e.g., expired card, stolen card).

Should I retry a payment after a hard decline?+

No. Hard declines like 'expired_card', 'stolen_card', or 'fraudulent' will not succeed on retry. Instead, send the customer a link to update their payment method. Retrying hard declines wastes API calls and can increase your decline rate with card networks.

How long should I wait before retrying a failed payment?+

It depends on the decline code. For 'insufficient_funds', retry near common pay dates (1st, 15th of the month). For 'generic_decline' or 'do_not_honor', retry after 24 hours. For 'processing_error', retry immediately.

How does Rebounce use decline codes?+

Rebounce automatically classifies every failed payment by its decline code and applies the optimal recovery strategy: specific retry timing, appropriate email urgency, and whether to request a card update or simply wait and retry.

Stop losing revenue

Rebounce recovers failed payments automatically

Smart retries, dunning emails, and WhatsApp recovery. Starting at $3.50/mo. 14-day free trial.

Start free trial

Keep reading