Hard Decline vs. Soft Decline: The SaaS Dunning Decision Tree

A soft decline (insufficient funds, timeout, velocity limit) is worth retrying on a spaced schedule, while a hard decline (stolen card, closed account, fraud flag) should go straight to a card-update request since retrying it only adds fees and dispute risk.

Author
Theodore Sterling
Date posted
July 30, 2026
Category
Payment recovery
Time to read
X min

In North American subscription billing, a soft decline is a temporary card rejection, like insufficient funds, a network timeout, or a velocity limit. Retrying it on a schedule usually recovers the charge. A hard decline is permanent, like a stolen card, a closed account, or a fraud flag. Retrying it wastes attempts, adds card-network fees, and raises your dispute risk.

I've built cancel flows for SaaS clients and dunning for my own business, and the same mistake shows up in both. Teams treat every failed payment the same, when the decline code already tells them what to do.

Key takeaways

  • Classify every failed payment by its decline code before you retry.
  • Retry soft declines 2 to 3 times across 7 to 14 days.
  • Send hard declines straight to a card-update request instead of retrying.
  • Visa charges $0.10 per domestic retry on never-approve codes.
  • Stop Mastercard retries after 10 declines on one card in 24 hours.
  • Send expired cards to account updater to recover them automatically.

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

A soft decline is a rejection the issuer may approve on a later retry, and a hard decline is one no retry will ever clear. That single difference decides whether you retry the card or stop. 

The amount, the customer, and the plan don't change the response. The decline code does.

The issuer's response code tells you the reason. Temporary conditions return soft codes, like insufficient funds, a network timeout, or a velocity limit from too many charges too fast. Each one resets once the account is funded, the network recovers, or the period rolls over.

Permanent conditions return hard codes, like a closed account, a lost or stolen card, or a fraud flag. None of those reverse, so the same card declines again no matter when you charge it.

You can see the split in Stripe's own codes. An insufficient funds decline is soft, because the cardholder may have money again in a few days. A stolen card decline is hard, and no future charge on that number will clear, so retrying it only burns attempts.

One code sits in between. Do not honor (code 05) is technically soft but behaves like a hard one. Issuers use it as a catch-all for conditions they won't spell out, so a second attempt within a day rarely works. Give it a shorter retry window than a clean soft code.

Which decline codes are soft and which are hard?

Soft codes get retried and hard codes get stopped, and the response code tells you which before you touch the card. The Decline Decision Tree turns that split into four actions.

The card networks already classify codes this way. Visa's published rules sort them into three buckets, which are never retry, wait and retry, or retry after correcting the data. Mastercard runs a parallel scheme. Stripe maps its plain-English codes onto these same buckets, so the label in a webhook tells you which branch of your dunning sequence a payment belongs on.

Soft declines: the retry category

Soft declines belong in the retry cadence, which is 2 to 3 attempts across 7 to 14 days, spaced 3 to 5 days apart. After that, escalate to a card-update email.

The spacing matters more than the count, because you want to land on a day when the temporary block has cleared.

Each soft code clears for its own reason. Insufficient funds clears when the cardholder's account is funded, so aligning a retry with a likely payday beats hammering the card daily.

A processing error or an issuer-unavailable response clears when the network recovers, and a velocity limit clears when the rolling period resets.

The networks also cap how often you may retry one payment before extra fees apply, which is one more reason to space attempts out. The full dunning playbook covers those network retry limits in detail.

A few soft codes need a fix, not just a wait. Incorrect CVC, incorrect number, and incorrect ZIP mean the stored data was wrong, so a blind retry returns the same decline. These route to a customer email that asks them to re-enter the card. Then you retry against the corrected details.

The exception is do not honor, which earns only 1 to 2 retries instead of the full schedule. A quick second rejection on the same card usually means the block is real, so don't keep spending attempts on it.

Hard declines: the stop category

Hard declines must stay out of the retry cadence. Each one goes straight to a card-update request if the card was replaced, or to an involuntary-churn flag if the account is closed or fraud-flagged. Retrying them only adds cost.

The reason is in the codes. A lost or stolen card can't be un-reported, a closed account won't reopen, and a fraud-flagged number won't clear later. Visa files these under its never-retry bucket:

  • Code 04, pick up card, retain the card if presented.
  • Code 41, the card was reported lost.
  • Code 43, the card was reported stolen.
  • Code 46, the account is closed.
  • Codes R1 and R3, the cardholder revoked authorization for the charge.

Every reattempt on one of these codes triggers a Visa "never approve reattempt fee" of $0.10 per domestic retry, and it lands from the first retry. The cost of treating a hard decline like a soft one shows up on your next statement.

A stopped retry still leaves a path to the customer. A lost or stolen card gets reissued with a new number, so email the customer for updated details. The charge then runs against the new card, with no fee and no monitoring exposure.

The expired card code is the one exception, and it gets its own section next.

What happens when you retry a hard decline?

Retrying a hard decline never recovers the payment. It adds card-network monitoring risk, and on fraud-flagged codes it pushes up your dispute rate. You pay to make your numbers worse.

Visa and Mastercard both watch how often a merchant retries declined charges, through Visa's Acquirer Monitoring Program and Mastercard's Excessive Authorization program. Both track the share of your authorizations that get declined, so reattempting dead cards pushes that ratio up until it crosses the line.

Past that point, the network reads your retries as card testing or broken billing. The fallout hits your acquirer first, in fees, a remediation plan, and at worst a closed merchant account.

The thresholds are specific.

Mastercard tells merchants to stop authorizing a card once it returns 10 declines in a 24-hour window, and attempts past that carry per-transaction fees. Visa's never-approve fee stacks on top of that, and neither charge buys you a recovered customer.

This risk is a volume problem. A few accidental retries from a misconfigured webhook won't trigger monitoring. The exposure builds when your retry logic can't tell hard codes from soft ones and reattempts them across every failed payment, month after month.

The other cost is disputes. Once a fraud-flagged charge clears and the cardholder disputes it, you're past dunning and into chargeback territory.

Chargeback.io covers how retrying hard declines feeds chargeback risk and how to fight the disputes that land.

The expired-card exception: when a "hard" decline needs account updater, not a churn flag

An expired-card decline is the one hard code you can recover without a retry. The card number is dead, but the cardholder has a new one, and account updater can push the fresh credentials to your processor before the next charge.

Expired and reissued cards are a steady source of failed charges. Cards turn over every year through expiry, loss, and fraud, and each new card breaks the stored number behind a subscription.

Account updater closes that gap by receiving the credential change from the issuing bank and writing the new number into your customer record. The account updater guide covers setup, costs, and where it sits in your recovery stack.

Prepaid cards and issuers outside the Visa and Mastercard updater networks don't refresh, so some expired cards still slip through. For those, email the customer before the next billing date with a link to update the card directly.

An expired card is a billing event, not a churn event. Flagging that account as involuntary churn writes off revenue you were one credential refresh away from keeping.

Use the churn rate calculator to size the revenue at stake before you configure your retry logic.

FAQ

Is insufficient funds a hard decline or a soft decline?

Insufficient funds is a soft decline, because the cardholder may have funds again within a few days. Retry it on a spaced schedule rather than charging the same card daily.

What does "do not honor" mean in a payment decline?

Do not honor (code 05) is a generic issuer rejection with no stated reason, used as a catch-all for conditions the bank keeps private. It is technically soft but clears on retry far less often than a code like insufficient funds.

Can Stripe automatically retry hard declines on my behalf?

No. Stripe's Smart Retries skip the decline codes it classifies as hard, such as stolen or closed-card responses, and retry only the soft ones.

What is the difference between a hard decline and a chargeback?

A hard decline blocks the payment before it goes through, while a chargeback reverses a payment that already cleared after the cardholder disputes it. A decline costs you the charge, and a chargeback costs you the charge plus a dispute fee.

Theodore Sterling

Share this article: