generic_decline tells you almost nothing. This cheat sheet translates the decline codes you'll actually see into plain English, with a clear call on when to retry and when to ask for a new card.
The ChargeBell Team·Updated July 20, 2026·7 min read
Written and reviewed by the product team that builds ChargeBell's Stripe and Slack integrations. About our editorial process.
When a payment fails, Stripe gives you a decline code. Some codes mean the money simply wasn't there today and a retry on Friday will probably work. Others mean the card is gone for good and every retry just burns goodwill with the card networks. Knowing which is which is the difference between quietly recovering a subscription and losing a customer who never even knew their payment failed. This is the cheat sheet we wish the Stripe dashboard showed inline.
The one rule to remember
Declines come in two flavors. Soft declines are temporary (not enough money, bank hiccup, velocity limit) and are worth retrying in a few days. Hard declines are permanent (lost card, stolen card, closed account) and should never be retried: ask for a new payment method instead.
The codes you'll actually see
Stripe documents dozens of decline codes, but a handful cover the vast majority of real failures. Here is what each one means, in the language you'd use to explain it to a customer.
Code
What it really means
Retry?
generic_decline
The bank said no and didn't say why. Often fraud rules on the bank's side.
Once. If it fails again, ask for another card.
insufficient_funds
The money isn't there right now.
Yes. Retry in 3 to 5 days, ideally just after the 1st or 15th.
do_not_honor
The bank declined without a reason. The customer usually has to call their bank.
Once, later. Then ask the customer to contact their bank.
expired_card
The card's expiry date has passed.
No. Ask for the new expiry or a new card.
incorrect_cvc
The security code didn't match. Usually a typo.
Yes, but only when the customer re-enters the card.
incorrect_number
The card number itself is wrong.
Yes, once the customer re-enters it.
lost_card / stolen_card
The card was reported lost or stolen. This is a hard decline.
Never. Request a new payment method.
fraudulent
The bank or Stripe flagged the charge as likely fraud.
Never. Retrying can hurt your standing with card networks.
authentication_required
The bank wants 3D Secure verification from the customer.
Yes, through a flow that lets the customer authenticate.
card_velocity_exceeded
The customer hit their card's spending or attempt limit.
Yes. Wait a day or two.
processing_error
Something glitched between Stripe and the bank.
Yes. Often works on the next attempt.
call_issuer / pickup_card
The bank suspects a problem and wants to talk to the cardholder.
No. The customer must call their bank.
The most common Stripe decline codes, translated.
What to do about soft declines
Time your retries. insufficient_funds recovers far more often right after common paydays. Retrying the same day rarely helps.
Cap your attempts. Two or three retries is plenty. Endless retries look like fraud to the networks and can get your account flagged.
Tell the customer early. A friendly note on the first failure ('we'll retry automatically on Friday') recovers more revenue than a stern one after the third.
Use Stripe's Smart Retries if you're on Billing. It already times retries using the bank's response patterns.
What to do about hard declines
Stop retrying and switch to asking for a new payment method. Stripe's hosted customer portal and payment-update emails handle this well. The mistake to avoid is silence: most customers whose card was replaced after fraud have no idea your subscription was on the old one. They didn't cancel, and they'll be annoyed to discover their account lapsed. Treat a hard decline as a customer-service moment, not a billing event.
Catch failures the moment they happen
None of this helps if you find out about failed payments a week later while reconciling. A failed charge alert in Slack, with the decline code and the customer's name attached, turns this cheat sheet into a two-minute fix: see the alert, check the code, send the right email. That's exactly what ChargeBell does, and failed-payment alerts are included on the free plan.
Get failed-payment alerts in Slack
ChargeBell posts every failed charge to Slack in plain English, decline reason included. Free for up to 100 alerts a month, no card required.
The customer's bank refused the charge without giving a reason. In practice it's often the bank's own fraud rules. Retry once; if it fails again, ask the customer for a different card or have them call their bank.
Should I retry an insufficient_funds decline?
Yes. It's the classic soft decline. Retry in 3 to 5 days, ideally just after the 1st or 15th of the month when paychecks land. Cap it at two or three attempts.
Which decline codes should never be retried?
lost_card, stolen_card, fraudulent, pickup_card, and expired_card. These are hard declines: the card will not work again, and repeated retries can damage your reputation with card networks. Ask for a new payment method instead.