The payment failed, and the retries started without you
A monthly subscription renews on the 3rd. On the 3rd, the card is declined.
Nobody at your business finds out. Nobody decides anything. And yet a decision is now being made, on a schedule somebody chose once, possibly at setup, possibly never. Over the next fortnight the billing system will try again some number of times, tell the customer something or nothing, and then put the subscription into one of three end states. By the time a human looks, the outcome is already fixed and cannot be changed retroactively.
This article is about that fortnight. Most of it is documented, and almost none of it is what people assume.
Two weeks is the recommendation, and it is a ceiling dressed as advice
The recommended schedule is eight attempts across two weeks, and the number eight is not an ambition. It is roughly the most the card networks will tolerate.
Stripe's page on automating payment retries states the default plainly: "The recommended default setting is 8 tries within 2 weeks." The window is not a free dial either. It is a short list: "You can set the Smart Retry policy to retry payment a specific number of times within a time period: 1 week, 2 weeks, 3 weeks, 1 month, or 2 months."
So far this reads like a generous piece of engineering working quietly on your behalf, and to a large extent it is. But turn to a different page in the same documentation, the one about card declines, and the number eight changes character completely:
Be aware that card networks limit the number of times you can reattempt a single charge. We recommend a maximum of eight retries for charges that permit retries. Card issuers might see creating additional retries as potential fraud, which can result in increased declines for legitimate charges.
Read those two pages together and the recommendation stops being a recommendation. Eight is close to the edge of what the networks accept before they start treating your business as suspicious. And the punishment is not aimed at the customer whose card failed. It lands on everybody else's payments, which begin declining more often because your account has been retrying too hard.
This is the first thing worth knowing about the fortnight: the dial that looks like "how hard should we try" is actually "how much risk should we take with our other customers".
Eight attempts, and some of them never happened
On a whole category of declines, the retries are scheduled, counted and displayed, but never actually made. No money is requested. The counter goes up regardless.
This is the part that catches everyone, so here it is verbatim from Stripe's smart retries page:
If a failure returns a hard decline code... we can't retry invoice payment without a new payment method. Retries continue to be scheduled, and attempt_count continues to increment, but retries only execute after detecting a new payment method. Unexecuted retries don't create a new Charge.
That last sentence is the whole thing. An attempt is counted without being made.
The nine codes this applies to are listed on the same page: "Stripe can't
automatically retry a payment if the card issuer returns any of these hard
decline codes: incorrect_number, lost_card, pickup_card, stolen_card,
revocation_of_authorization, revocation_of_all_authorizations,
authentication_required, highest_risk_level, transaction_not_allowed."
And the consequence: "For these failures, the scheduled retries continue but the
payment only executes if you obtain a new payment method."
Picture what a business owner sees a week later. An invoice, unpaid, marked with eight attempts. The natural conclusion is that this customer has been asked for money eight times and refused eight times, which sounds like a customer with a problem. What actually happened is that the card was cancelled or stolen, the first request failed, and the following seven were entries in a calendar. The bank was never contacted again.
There is one more line on that page worth having, because it decides four cases without any decline code at all: "Stripe doesn't retry payments if: No payment methods are available. The issuer returned a hard decline code. The payment card is India-issued. The Stripe Connect account has been disconnected." A business selling into India, or one whose connected account quietly came unlinked, gets a counter that is pure fiction from the first tick.
The same counter counts three different things
The number of attempts on an invoice mixes together three situations that need three different responses, and nothing in the number tells you which one you have.
Sort the declines by what a retry can actually accomplish and three groups fall out.
Waiting might work. insufficient_funds is the honest example: the money
was not there on the 3rd and may well be there on the 6th. Stripe's decline
table describes it as a case where "The customer needs to use an alternative
payment method", but nothing prevents the same card from working later. This is
the case the whole retry schedule was designed for, and it is the case where
patience genuinely recovers revenue.
Waiting cannot work, but the attempts are real. expired_card is the one
that surprises people, because it is not on the hard-decline list above. Stripe's
decline documentation says of it only: "The card has expired. The customer needs
to use another card." As far as the retry engine is concerned, that card is
retriable. So it stays in the schedule, and the attempts against it are real
requests to the bank - up to the eight the default allows, each one declining
for the same reason as the first. Nothing is broken.
Nothing is going to change either, because the only fix is a new card and no
amount of retrying produces one.
The attempts are not real. The nine hard codes from the previous section. The counter rises and no request is made.
The difficulty for a small business is that all three look identical from the outside. One invoice, one unpaid status, one attempt count. Deciding what to do about a customer requires knowing which group they are in, and that information lives one level down, in the decline reason, which is precisely the field nobody has put on a dashboard.
There is a useful contrast in the same documentation. For local payment methods
rather than cards, Stripe writes the outcome in plain words next to several
codes: invalid_billing_agreement, currency_not_supported, invalid_amount,
compliance_violation, invalid_payment_information and others each carry the
line "Retries won't succeed." For cards, that sentence does not appear. The
information exists; for the payment method most small businesses actually use,
it is expressed as a list of codes rather than as an answer.
If you would rather have somebody go through what your billing does on its own and put a number against each branch, that is the process audit. $299, three business days, and a written map you keep whether or not you hire us.
In Europe, a routine decline behaves like a stolen card
authentication_required sits on the hard-decline list, so a
European payment that fails because the bank wants the customer to confirm it
produces phantom retries, exactly like a reported-stolen card.
Look again at the nine codes. Seventh in the list is
authentication_required. That is not a fraud signal or a dead card. It is the
bank saying the customer needs to complete a challenge before this payment goes
through, which is ordinary behaviour under European rules.
Those rules have a date. Stripe's page on strong customer authentication describes it as "a rule in effect as of September 14, 2019, as part of PSD2 regulation in Europe". The migration ran longer than the rule: the European Banking Authority's press release of 16 October 2019 says "The Opinion sets the deadline to 31 December 2020 and prescribes the expected actions to be taken during the migration period." The UK ran later still, and the Financial Conduct Authority's statement of 20 May 2021 records the move: "We have extended our deadline for implementing Strong Customer Authentication (SCA) for e-commerce transactions to 14 March 2022."
These dates matter for a reason that has nothing to do with compliance. Anything you read about subscription retries written before roughly 2021 describes a world where this failure mode was rare. It is now ordinary, and it produces the worst version of the counter: eight scheduled attempts, none executed, on a customer who has money, wants the service, and simply needs to tap a confirmation. Whether anybody asks them to is a separate setting again - the same page carries a switch for sending the customer a link to confirm a payment when one is required, and another for chasing them if they do not - and its position is no more knowable from here than any of the others.
The escape hatches are real but not dependable, and Stripe says so directly: "Exemptions aren't guaranteed, and off-session payments might still require authentication by the bank."
The customer hears from you only if somebody ticked a box
The emails that tell your customer their payment failed are settings, described in the documentation as things you enable. And nothing in that documentation describes an automatic email to you.
Stripe's page on customer emails introduces the failed-payment message with a condition: "When you enable this setting, Stripe automatically sends an email to your customer after each failed payment." The setting is named Send emails when card payments fail. The expiring-card warning is a separate one, with its own description: "This automatically sends an email 1 month before your customer's card on file expires, where the card is their default payment method or default source."
I want to be careful here, because absence of evidence is not evidence. What the documentation states is that these are settings you enable. It does not state, on the pages I read, whether they are on or off when you open a new account. The honest instruction is therefore not "they are off" but "go and look, because this is a switch and you do not currently know its position".
There is a trap sitting right next to it, documented on the same page: "In sandbox, Stripe doesn't automatically send customer emails." There is a way through it, spelled out in the very next sentence - emails do go out in a sandbox if the test customer's address belongs to your verified email domain or an active team member. Which produces a peculiar split. A business that tests with a throwaway address sees nothing and concludes the feature is off. A business that tests with its own address sees everything and concludes it is on. Neither has learned what happens to a real customer.
The other half is more striking. Across the pages I read, nothing describes an automatic email to the business when a subscription payment fails. What is offered instead is a webhook event, the dashboard, recovery analytics, and automations you build yourself; the revenue recovery page lists "Notify your team when high value invoices are overdue" as a recipe to construct, not a default that exists. The one unprompted email Stripe documents sending to the merchant is about broken webhooks: "We'll also send you an email to notify you that the webhook is failing."
Which is a reasonable design. It also means that in the default configuration, the fortnight passes with the machine talking to the customer and nobody talking to you. If the customer emails are off as well, the fortnight passes with nobody talking to anybody. This is the same shape as the problem in why automations fail silently: the system is working exactly as configured, and the configuration contains no route to a human.
The card that expired may have been replaced already
Card networks push new card details to processors automatically when a customer is reissued a card, which means some expired cards fix themselves. Which ones, you cannot find out.
Stripe's cards overview describes the mechanism: "Stripe works with card networks and automatically attempts to update saved card details whenever a customer receives a new card (for example, replacing an expired card or one that was reported lost or stolen)."
Then it draws the boundary, and the boundary is the interesting part:
It's widely supported in the United States, allowing Stripe to automatically update most American Express, Visa, Mastercard, and Discover cards issued there. International support varies from country to country. It isn't possible to identify cards that support automatic updates.
Three separate facts in one paragraph. Coverage is strong in one country. It varies elsewhere. And there is no flag, list or report that tells you which of your customers you can rely on this for.
For a business with a domestic American customer base, "the card expired" is
often a non-event that resolved itself before anybody noticed. For a business
selling across borders, the same phrase means a customer who has to be contacted
by a human. Same wording on the invoice, different problem entirely, and no way
to sort one from the other in advance. The one signal available is an event
Stripe emits when it happens: "The payment_method.automatically_updated event
notifies you of automatic card updates from the network."
Cutting access on day one defeats the whole window
The documentation says to notify during past_due and revoke only at
unpaid or canceled. A great deal of software does the opposite, and has been
doing it for years.
Stripe's guidance on subscription webhooks is unambiguous about the two moments:
"When a subscription changes to past_due, notify the customer directly and ask
them to update their payment details." And separately: "When a subscription
changes to canceled or unpaid, revoke access to your product." The
subscription statuses page repeats it with the reasoning attached: "Revoke access
to your product when the subscription is unpaid because payments were already
attempted and retried while past_due."
That is the intended shape. Two weeks of trying, with the customer still served, then a decision.
What actually happens in a lot of code is that past_due gets folded into "not
a paying customer", and the customer is locked out on day one. This is not a
fresh mistake, and it is not a rare one: the billing libraries that sit between
a web application and Stripe have, for years, tended to answer "is this
subscription active?" with "no" the moment the status leaves active, so a
customer whose card failed yesterday is treated exactly like one who cancelled
last year. The vendor is still retrying; the application has already shown
the door.
The failure at the other end of the fortnight is stranger. A renewal fails,
the account looks unsubscribed to the customer, the customer buys again - and
then the processor's retry on the original past_due subscription succeeds.
Two live subscriptions, one customer, one confused conversation. The usual
advice from the people who maintain such libraries is to treat past_due as
not subscribed and show a banner asking for a new card, which is a sensible
fix for a customer-facing app and also, read literally, the opposite of what
the vendor documentation recommends.
Both positions are defensible. That is the point. There is no single correct answer to "is a customer whose card failed yesterday still a customer", and if nobody at your business has answered it deliberately, it has been answered by whichever library you installed.
Choosing more control gives you fewer attempts
Replacing the automatic schedule with your own rules caps the attempts at three instead of eight.
There is a natural instinct, when a system does something on its own, to take the wheel. Stripe offers a custom schedule for exactly that, and the page states its limit: "You can configure up to three retries, each with a specific number of days after the previous attempt."
Set against a default described as "8 tries within 2 weeks", switching to manual control removes five attempts. The same documentation is direct about the trade-off: "Using AI, Smart Retries chooses the best times to retry failed payment attempts to increase the chance of successfully paying an invoice."
There is a second edge, and it is the kind that only shows up once: "After the final payment attempt, we make no further payment attempts. Changing your subscription settings only affects future retries." Discovering the schedule was wrong does not let you re-run the fortnight for the customers it already ran on. Whatever the old settings decided, they have decided.
Nobody else's billing ends the same way
The end state after retries are exhausted differs by platform in ways that change what happens to the money, not just to the record.
Stripe offers three outcomes, and the merchant picks in advance. Cancel: "The
subscription changes to a canceled state after the maximum number of days
defined in the retry schedule", and cancellation "is a terminal state that can't
be updated". Unpaid: "The subscription changes to an unpaid state... Invoices
continue to be generated and stay in a draft state." Or leave it: "The
subscription remains in a past_due state... Invoices continue to be generated
and charge the customer based on retry settings."
Read the third one carefully. Choosing not to decide is itself a choice with teeth: invoices keep being generated and charges keep being attempted, on a customer who may still be using the service.
Other platforms answer the same question differently, and the differences are not cosmetic.
Braintree's recurring billing guide describes three merchant-chosen outcomes as well, one of which is to "Continue retrying the subscription" once per billing cycle. The same documentation notes what that does to the ledger: "The balance on Past Due subscriptions will continue to increase every billing cycle - either indefinitely or until the number of cycles in the subscription is reached." Read the word "indefinitely" and picture what it means for a customer who stopped paying in March.
PayPal's subscriptions documentation describes a threshold rather than a schedule: "If a payment fails, PayPal retries the payment every 5 days. PayPal retries the payment up to twice per billing cycle." The end state is not cancellation but suspension, and the money is not written off: "The failed payment amount is added to the outstanding balance for the next billing cycle."
Chargebee publishes two numbers depending on which mode you use. Its smart dunning documentation says "Chargebee will retry upto 12 times to collect the payment", while its dunning documentation puts the manual ceiling lower: "The max number of retries you are allowed to set is 5."
Paddle's Retain documentation gives a window rather than a count: "By default, dunning takes place over a 30-day period", ending with a pause or a cancellation
- "When all payment recovery attempts are exhausted, Paddle Retain automatically pauses or cancels subscriptions for you." I could not confirm its number of attempts, so I am not giving one.
Four platforms, four different answers to "what does the customer owe when this is over". Anything you have read about how subscription billing behaves after a failed payment is a description of one platform, including this article.
The documentation contradicts itself about what happened
Two pages in the same set of documentation name two different statuses for a failed subscription payment, and a third sentence reconciles them.
The collection method page says: "If a payment fails or if it requires customer
authentication, the subscription's status is set to past_due..."
The subscription webhooks page, in its table of payment failures, says the
subscription moves to incomplete.
Both are right, and the sentence that makes them right is elsewhere on the
second page: the status stays incomplete "only for the subscription's first
invoice". A brand-new subscription whose very first payment fails behaves
differently from a renewal that fails in month nine, and the statuses page gives
the first case its own clock: "The customer must make a successful payment within
23 hours to activate the subscription."
I am not raising this to score a point against a documentation team. I am raising it because it is exactly the kind of thing that produces a wrong access rule. Somebody reads one page, writes a rule that checks for one status, and ships software that behaves correctly for new customers and incorrectly for renewals, or the reverse. The bug will not appear in testing, because testing uses new subscriptions and the failure being modelled is a renewal.
What to check in your own setup
Find out where the failure notification goes. Not whether one exists in principle: who receives it, at which address, and when somebody last read one. If the answer is "the customer gets an email, I think", that is two unknowns.
Look at the decline reason, not the attempt count. Once, on a real failed invoice. Learning that your unpaid invoices are mostly expired cards leads to a completely different response from learning that they are mostly insufficient funds, and the attempt count is identical in both cases.
Decide what a customer in past_due is allowed to do. They are mid-window
by design. Write the answer down, then check that your software agrees with it,
because the library you are using has already made a choice on your behalf.
Check which end state you chose. Cancel, unpaid, or leave it. Many businesses have never opened this setting, which means the outcome for every failed subscription they will ever have was set by a default.
Look at your customers' countries before trusting automatic card updates. The mechanism is real and strongest in one market. If your customers are elsewhere, expired cards are a human task, not a solved problem.
Count what the fortnight costs. Take last quarter's failed subscriptions, separate the ones that recovered from the ones that ended, and put a figure on the second group. Until that number exists, any argument about retry settings is a matter of taste.
When this stops being a settings question
For a business on one billing platform with a handful of subscriptions, the checks above are the whole job. Open the settings, read the decline reasons once, choose the end state deliberately.
It stops being that when the failure has to propagate. The subscription is in one system, the customer's access in another, the invoice in the accounting ledger, the renewal date in a spreadsheet somebody maintains, and the conversation with the customer in an inbox. A failed payment is an event that all five of them need to hear about, in an order, with a rule for what each does while the fortnight is still running. That is different from the retry problem in what happens when an automation runs the same job twice, where the work is done and done again; here the work is scheduled, counted, and in some cases never performed at all. It is also the opposite end of chasing overdue invoices, where you decide when to send the next reminder. Nobody is deciding here.
Working out whether you need a rule or a rebuild is what the process audit settles: what can be automated, in what order, and what each piece is worth, in writing, in three business days.
Related: what happens to your automations when the plan runs out is the same fortnight seen from the other side, when the payment that fails is the one you owe a vendor.