← Back to blog

Payment Retry Logic: How Retry Schedules Decide When to Charge

10 min read

Payment retry logic is the set of rules your billing system follows after a card payment is declined: whether to attempt the same payment again, how soon, how many times, and when to stop. It's a decision layer, not a feature name — every subscription business has retry logic whether it chose it deliberately or inherited whatever its billing platform does by default.

The term shows up in three different conversations — billing platform settings, vendor comparison pages, and engineering tickets — which is why it can feel more technical than it is. This page is the plain-English version: what the logic is actually deciding, the parts of it worth configuring, and the specific failures it structurally cannot fix.

What the logic is actually deciding

Strip out the jargon and retry logic answers four questions about every failed charge:

  1. Should we try this card again at all? Some declines can resolve on their own. Others tell you the card itself is finished, and another attempt is guaranteed to fail.
  2. When? Hours after the decline, days after it, or timed around something specific like a plausible payday.
  3. How many times, over what period? Both the attempt count and the window it spans.
  4. What happens when we run out of attempts? Cancel the subscription, mark it unpaid, suspend access, or leave it open and hand the problem to a human.

Basic retry logic answers question 1 with "always," question 2 with a fixed interval, and question 4 with whatever the default was. Better retry logic answers each one differently depending on why the payment failed. That's the entire spectrum — everything else is implementation detail.

Why a declined card needs logic rather than just another attempt

A retry only succeeds if something has changed since the last attempt. That single sentence explains why "just try again" isn't a strategy.

Plenty of declines really do change on their own. A card that was temporarily short of funds gets topped up. A one-off bank block or transient processing error clears. A velocity or fraud limit resets. In those cases the charge was always collectable and the only mistake you could make is not trying again.

But a card that has expired, been cancelled, or been reported stolen doesn't change on its own — not in an hour, not in two weeks. Retrying it produces a second identical decline, and on some decline codes the card networks bill you for the reattempt. Retry logic exists to tell those two situations apart, because the correct response to each is close to opposite.

Fixed schedules vs adaptive timing

There are two broad approaches to question 2, and the difference is narrower in practice than the marketing around it suggests.

A fixed schedule means you choose the days: retry on day 1, day 3, day 7, and so on. It's predictable, easy to reason about, and easy to line up your customer emails against. Its weakness is that it applies the same interval to every card, every customer, and every decline reason.

Adaptive (or optimised) timing means a model picks each attempt time using signals a single merchant doesn't have — card-network and issuer behaviour, time-of-day patterns, how recently that payment method has been used elsewhere. Stripe's Smart Retries is the best-known implementation; several other billing platforms ship their own under names like intelligent retries. This is what most people mean by retry optimisation: same number of attempts, better-chosen moments.

Adaptive timing is generally the better default, because there's rarely a reason to believe your fixed interval beats a model trained on network-wide decline data. A fixed schedule earns its place when you need attempts to land on a known date — aligning with a payroll cycle for one customer segment, for example. What matters more than the choice is knowing that both are only answering question 2. Neither is deciding whether the card is worth retrying in the first place. How that choice plays out on Stripe, including a day 1 / day 3 / day 7 custom schedule and the declines where timing cannot collect anything, is in Smart Retries vs a fixed retry schedule.

Attempt limits and retry windows

Two numbers define the shape of any retry policy:

  • Attempt count — how many charges you'll attempt in total, including the original.
  • Retry window — the period those attempts are spread across, typically one to eight weeks.

Four or five attempts across roughly two weeks covers the large majority of recoverable soft declines. Front-loading helps: the cheapest recovery you will ever get is an attempt against a decline that had already resolved by itself, so an early retry within the first day or two does real work. Past the two-week mark, additional attempts against the same unchanged card mostly generate reattempt fees rather than recovered revenue.

More attempts is not automatically better, and aggressive retrying carries its own cost. Several attempts a few hours apart look like a problem to issuers and can raise your decline rate on subsequent tries. The window matters as much as the count, and both should be set against your billing cycle: a retry window that runs past the next invoice date creates its own mess.

Soft vs hard declines: the branch that matters most

If you only add one piece of intelligence to your retry logic, this is it. Every failed charge comes back with a decline code, and those codes fall into two groups that need opposite handling.

Soft declines are timing problems. insufficient_funds, do_not_honor, and processing_error all describe a card that can work, just not at this exact moment. These are what retries are for.

Hard declines are instrument problems. expired_card, lost_card, stolen_card, and incorrect_number describe a card that cannot complete this charge regardless of timing. No retry schedule recovers these; only a new payment method does. Retry logic that fires attempts at them is burning its attempt budget on charges that were never going to clear, and on some of these codes the networks charge for every reattempt.

Most default configurations treat both groups the same way, which is why decline-code branching is usually the highest-return change available to an existing retry setup. We've broken down how to split your own failure pile by code, and what the unrecoverable slice actually costs, in hard declines vs soft declines. The specific per-code timing table — which code to retry after four hours versus four days — sits in how to set up automated payment retries in Stripe.

What retry logic can't do

Being clear about the boundary is what keeps expectations honest:

  • It can't recover a dead card. If the account behind the card is closed, retry timing is irrelevant. The only recovery path is the customer adding a new payment method.
  • It doesn't tell the customer anything. Retries run silently in the background. In most billing platforms, failed-payment emails are a separate feature you configure separately — and a customer who never learns their card failed can't fix it.
  • It doesn't make fixing the card easy. Every step between "customer decides to update their card" and "new card on file" costs you recovered payments. That's a product problem, not a scheduling one.
  • It doesn't measure itself. Knowing your own recovery rate — by decline code, before and after a change — is a separate job, and most teams running on defaults can't answer the question at all.

This is why retry-only setups are commonly discussed as recovering somewhere in the 30–40% range of failed payments, with layered approaches that add decline-code handling and well-timed customer messaging often quoted higher. Treat those as illustrative industry figures rather than a guarantee — they aren't measured RetryFix results, and the only number that means anything for your business is your own baseline.

How this differs from Stripe Smart Retries

Smart Retries isn't a synonym for retry logic — it's one specific, well-built answer to one of the four questions above. It's a Stripe Billing setting that decides when each attempt fires, using Stripe's own network data instead of an interval you picked. It does that job well, it costs nothing extra, and there's rarely a good reason to turn it off.

What it doesn't decide is whether a given card should be retried at all (beyond a short protected list of hard-decline codes), what the customer hears, or what happens to their access while attempts are running. So "we have Smart Retries on" and "we have retry logic" aren't the same statement — the first is a timing engine, the second is the whole policy around it. If you want the setting itself defined properly, see what Stripe Smart Retries are, and for why the timing layer alone tends to plateau, why Smart Retries alone still leave most failed payments unrecovered.

How this differs from buying payment retry software

Retry logic is a policy. Payment retry software is a product category that implements one for you, plus the layers retry logic can't cover on its own — customer messaging sequenced into the retry gaps, a one-click card-update path, escalation rules for high-value accounts, and recovery reporting.

The distinction is worth holding onto when you're evaluating anything, because the retry itself is the commodity. Your processor already does it. If a tool's pitch is "we retry failed payments," it's selling you something you have. What's actually worth paying for is the decision-making around the attempt and the customer-facing work after it. We've written up what the category adds beyond a processor's built-in retries, and the size thresholds where it starts to pay for itself, in payment retry software.

Common questions

What is a retry window? The period your attempts are spread across, measured from the first failure. Distinct from the attempt count — eight attempts in two weeks and eight attempts in two months are very different policies.

Is retry optimisation the same thing as retry logic? No. Optimisation usually refers specifically to improving when attempts fire. Retry logic is the wider policy, including whether to attempt at all and when to stop.

How many times should you retry a failed payment? Four or five attempts across roughly two weeks is a reasonable starting point for soft declines. For hard declines, the honest answer is closer to zero — send the customer a message instead.

Does retry logic replace dunning emails? No, and the two work best in step: attempts running in the background, messages landing in the gaps between them so each attempt gets a fresh chance at an updated card. Why the default failed-payment email still gets ignored until the subscription cancels is in why customers ignore Stripe failed-payment emails. The wider process those emails belong to is what dunning is.

Where to start

If you're configuring this for the first time: turn on your platform's adaptive retry timing, set four or five attempts across about two weeks, enable automatic card updates if your processor offers them, and decide explicitly what happens when attempts run out. That's a solid baseline in well under an hour.

The upgrade after that isn't a longer schedule — it's branching on the decline code so hard declines stop absorbing attempts, and putting a clear, specific message in front of the customer while the attempts are still running. The full walkthrough is in how to set up automated payment retries in Stripe.

We build RetryFix, which runs that layer on top of your processor's retries rather than replacing them, on a pay-on-recovery basis — a percentage of revenue actually recovered, nothing if we recover nothing. If you'd rather see your own baseline before changing anything, try the demo and we'll show you what's currently going unrecovered. RetryFix never holds or moves your money; recovered payments land in your own Stripe account.

See how RetryFix recovers failed payments in under 2 minutes

RetryFix never holds or moves your money; recovered payments land in your own Stripe account.