1
0 Comments

The Stripe decline codes most founders never look at - and what they're actually telling you

Most SaaS founders set up Stripe, turn on Smart Retries, and never look at decline codes again.
That's leaving a lot of money on the table.

Here's what's actually in those codes - and what each one is telling you to do.

The two categories that matter

Every failed payment falls into one of two buckets.

Bucket 1: Timing problems

The customer has money. The card is valid. Something temporary got in the way.

  • insufficient_funds : money is coming, retry later
  • processing_error : technical glitch, retry soon
  • network_error : connectivity issue, retry fast
    For these, Smart Retries work. Timing is everything.

Bucket 2: Action problems

No retry will ever fix these. The customer needs to do something.

  • expired_card : that card is gone forever
  • card_not_supported : wrong card type for subscriptions
  • do_not_honor : bank blocked it, customer needs to call or use a different card
  • card_velocity_exceeded : fraud protection triggered, customer needs to act

For these, you need to send a message. The right message, for the exact reason.

The codes that sit in the middle

Some codes are genuinely ambiguous - and this is where most dunning logic breaks down.
do_not_honor is the classic example. It looks temporary. It often isn't. Issuers use it as a catch-all for a dozen different situations, and retry logic handles it poorly.
The practical fix: treat do_not_honor as a soft Bucket 2. Send a gentle message first, retry once, then escalate communication if unresolved.
card_velocity_exceeded is similar - looks like a fraud flag, but often the customer just hit their daily limit. Day 1 outreach with a clear explanation converts well here.

The one code you should never contact

fraudulent - do not send anything. Ever.
If Stripe has flagged a payment as fraudulent, reaching out to that customer can cause more harm than the lost revenue. This is the one case where silence is the right answer.

What this means in practice

Most dunning setups apply the same retry cadence to everything. That's why recovery rates stay low.
The founders who crack this treat each decline code as a different diagnosis — not just a failed payment.

  • Bucket 1 gets smart retry timing
  • Bucket 2 gets direct customer communication on day 1
  • Ambiguous codes get a fallback approach
  • Fraud codes get nothing

Do you actually look at your decline code breakdown? Or is it mostly set-and-forget?

(Building DunnAI — it reads every decline code and sends the right response automatically. Free diagnostic at getdunnai.com)

on April 7, 2026
Trending on Indie Hackers
I shipped a productivity SaaS in 30 days as a solo dev — here's what AI actually changed (and what it didn't) User Avatar 265 comments Never hire an SEO Agency for your Saas Startup User Avatar 108 comments A simple way to keep AI automations from making bad decisions User Avatar 72 comments 85% of visitors leave our pricing page without buying. sharing our raw funnel data User Avatar 45 comments Are indie makers actually bad customers? User Avatar 40 comments We automated our business vetting with OpenClaw User Avatar 38 comments