Visa Caps You at 15 Retries a Month — and Fines You for Wasting Them on the Wrong Decline Code
Visa and Mastercard fine merchants for retrying the wrong declined payments. Here's the decline code taxonomy your dunning logic needs to respect it.
Most dunning guides — including our own — teach you to sort failed payments into two buckets: soft declines that deserve a retry, and hard declines that don't. That's the right instinct, but it's not how the card networks actually grade you. Visa and Mastercard run a four-category system on every decline code, they publish an exact retry ceiling for the categories that allow retries at all, and they fine merchants who resubmit past it. A dunning stack that treats do_not_honor and insufficient_funds as the same kind of "soft, try again" failure isn't just being imprecise. It's accumulating a bill.
A decline code is not a yes/no signal
When a Stripe charge fails, you get back more than a boolean. The decline_code field carries the specific reason the card network or issuing bank gave — insufficient_funds, do_not_honor, expired_card, lost_card, dozens of others. Most teams read that field, decide "soft" or "hard," and move on. The networks read the same code and place it into one of four compliance categories that determine whether you're even allowed to try again.
| Network category | What it means | Example decline codes | Retry policy |
|---|---|---|---|
| Category 1 — never retry | The card or account is permanently unusable | lost_card, stolen_card, pickup_card, revocation_of_authorization | Zero retries. First reattempt is a violation. |
| Category 2 — wait and retry | A temporary condition that may clear with time | insufficient_funds, try_again_later, card_velocity_exceeded | Up to 15 reattempts per 30 days. |
| Category 3 — correct and retry | The transaction data itself was wrong | incorrect_cvc, incorrect_number, expired_card | Retry only after the customer supplies corrected details. |
| Category 4 — generic decline | Issuer declined without a specific reason | do_not_honor, generic_decline | Same 15-in-30-days cap as Category 2. |
The category most teams get wrong is the fourth one. do_not_honor and its close relative generic_decline feel like they belong in the "give it a few days" pile because the bank hasn't told you anything specific went wrong. Networks treat them as retryable — but capped at the same 15 attempts in 30 days as an insufficient-funds decline, not an open-ended window. A retry schedule built to squeeze value out of a 21–28 day dunning period, the recommendation in our own Stripe dunning guide, can burn through 15 attempts well before day 28 if it's retrying daily or every other day — and every attempt after that is billable.
Illustrative — decline-reason shares from our Stripe dunning guide (insufficient funds, expired card, do-not-honor, incorrect details ≈ 80%; lost/stolen/fraud-block/other hard decline ≈ 20%) mapped against Visa and Mastercard's published category definitions. Exact splits vary by customer base and card mix.
Most of what hits a SaaS billing system is retryable in some form — that's exactly why a naive "just keep retrying" instinct works well enough that teams never notice they've capped out. The problem shows up specifically on accounts that fail repeatedly over a long dunning window: precisely the customers a 21–28 day retry schedule is designed to chase hardest.
What the fine actually looks like
Visa's Excessive Reattempts Rule has been in effect since April 2022. Every reattempt of a Category 1 decline, and every reattempt past the 15th within 30 days for Category 2–4, is billed back to the merchant of record at roughly $0.10 per domestic attempt plus $0.05 for cross-border. It shows up on a processor statement as a line item, not a dramatic account suspension — which is part of why it goes unnoticed. Nobody's dunning dashboard has a "network compliance fees" row. The charge just quietly erodes whatever revenue the retry was supposed to recover in the first place.
Mastercard runs the equivalent under its Transaction Excellence Program, but signals it differently: rather than one published cap, it attaches a Merchant Advice Code to the decline response. MAC 03 means "do not try again." MAC 21 means "no retry, account closed for the life of the card." Resubmitting after either code is what triggers the fee, independent of how many attempts you've made in total. The mechanism is different from Visa's flat counter, but the instruction is the same: the network is telling you, in the response itself, whether this specific decline is worth a second try.
Does Stripe handle this for you?
Partially, and only if you're using the feature it applies to. Stripe's Smart Retries is built with network compliance in mind — it won't knowingly resubmit a Category 1 decline, and it paces retries to stay under the 30-day reattempt ceiling. If your entire retry logic runs through Smart Retries with no custom overrides, you're largely covered.
The exposure is everywhere else. Teams that pull invoice.payment_failed webhooks and run their own retry scheduler — common once you want SMS nudges, custom escalation paths, or the pause-instead-of-cancel logic we've recommended elsewhere — are making their own retry-timing decisions on raw decline_code values. If that custom logic treats do_not_honor as "wait three days and try again, repeat," it has no idea it's approaching a network cap, because Stripe's compliance handling doesn't extend to charges you're manually resubmitting outside Smart Retries.
Building a per-code retry policy
The fix isn't a new tool — it's mapping the decline codes you already receive to their network category before deciding what your dunning logic does next.
1. Gate Category 1 codes at the point of decline
The moment a charge returns lost_card, stolen_card, pickup_card, restricted_card, or revocation_of_authorization, mark that payment method as dead in your own database and route straight to a "please add a new card" email. No retry, no exceptions — retrying any of these is a violation on the first attempt, not a matter of degree.
2. Count reattempts per card, not per invoice
The 15-in-30-days cap is scoped to the card, across every transaction you've attempted on it — not per invoice or per subscription. If a customer has two products on two subscriptions billing the same card, your reattempts on both count against the same limit. Most billing systems track retry count per invoice by default, which undercounts exposure for multi-subscription customers.
3. Treat Category 3 as "wait for new data," not "wait and retry"
expired_card and incorrect_cvc aren't going to resolve themselves on attempt four. Retrying identical, uncorrected data against these codes doesn't just waste a dunning cycle — it's arguably not even a legitimate reattempt under the network's own logic, since nothing about the transaction changed. Route these straight to a card-update prompt instead of a scheduled retry; our Card Account Updater guide covers how to close part of this gap automatically, before the decline ever happens.
4. Reserve your 15 attempts for the window that matters
If you're running a 21–28 day dunning window per our Stripe dunning guide, don't spend all 15 reattempts in the first week. A schedule of roughly one retry every 2–3 days spreads 15 attempts across the full window instead of exhausting the cap by day 10 and then having nothing left to try when a payday cycle would actually have cleared the balance.
None of this replaces the underlying dunning and card-refresh strategy — most of what determines whether you recover a failed payment is still timing, communication, and getting ahead of expiry. What changes is the ceiling. A retry schedule that ignores network category treats every decline as an unlimited resource; one that respects it gets the same recovery rate without turning a failed $50 invoice into a $50 invoice plus a stack of $0.10 compliance fees on a card that was never going to clear. You can model how much of your reported involuntary churn is genuinely recoverable versus permanently gone with our churn calculator — split your failed-payment cohort by decline category before assuming another retry cycle is worth running. And for the subscribers who do want out rather than being quietly retried into frustration, that's the moment a CancelFlow cancellation flow is built to capture the real reason, instead of a fifth do_not_honor charge nobody ever explained to them.
Frequently asked questions
How many times can I retry a failed subscription payment on Visa or Mastercard?+
Under Visa's Excessive Reattempts Rule, transactions in Category 2 or 3 (temporary declines you're allowed to retry) are capped at 15 reattempts within any rolling 30-day period per card. Category 1 declines — lost, stolen, or closed cards — can't be retried at all; the first reattempt is already a violation. Mastercard runs a parallel system through its Transaction Excellence Program, signaling per-transaction via Merchant Advice Codes rather than publishing one universal number.
What's the difference between a Stripe decline_code and a hard vs. soft decline?+
decline_code is the specific reason Stripe returns for a failed charge — insufficient_funds, do_not_honor, expired_card, lost_card, and so on. 'Hard' and 'soft' decline are a simplified two-bucket summary of those codes. The network rules actually run on four categories, not two, and some codes that get lumped into 'soft decline' in casual usage — like do_not_honor — are technically generic declines with their own 15-attempt cap, not an invitation to retry indefinitely.
Does Stripe Smart Retries already comply with these network rules?+
Stripe builds network compliance into Smart Retries when it's enabled — it won't knowingly resubmit a Category 1 decline or blow through the 30-day reattempt cap on your behalf. The exposure is for teams running custom retry logic outside Smart Retries, or teams who've built their own dunning schedule on Stripe's raw decline_code data without mapping it to network categories first.
Which Stripe decline codes should never be retried?+
lost_card, stolen_card, pickup_card, restricted_card, and revocation_of_authorization all map to Visa's Category 1 and should trigger an immediate stop — no retry, ever, on that card. The customer needs a new payment method, not a scheduled retry. Retrying any of these is a compliance violation on the first attempt, not just an inefficiency.
Stop losing subscribers today
One script tag. One function call. A live cancellation flow in under 10 minutes.
Start free trial →