All segments

Stripe Failed Payment: Causes in Order, and the Fix for Each

A Stripe failed payment has a short list of causes. Read the decline code, fix the right layer and test the fix without touching live customers.

  • Published
  • Reading time 13 min read
  • Author Nafiul Hasan
Stripe Failed Payment: Causes in Order, and the Fix for Each. Diagram: attempts, spaced. RECOVER Stripe Failed Payment: Causes inOrder, and the Fix for Each WIDENING INTERVALS pointerflow.com

Short answer

A Stripe failed payment usually comes from one of a handful of causes: an expired or replaced card, a bank decline, an authentication step the customer never completed, a fraud rule blocking the charge, or your own retry and email settings. Read the decline code first, then fix the layer that owns it.

Why does a Stripe failed payment happen, and where do you look first? Most operators open the Stripe Dashboard, see a red “Failed” badge and a card_declined message, and start guessing. That message is a wrapper. The useful detail sits one level down, in the decline code, and the fix depends entirely on which layer owns the failure: the customer, the bank, Stripe’s risk tooling, or your own configuration. This page ranks the causes in the order we check them and gives the fix for each.

That ordering is a judgement from debugging these problems, not a measured frequency. If you want to know how the causes rank on your own account, the method is in the section on sizing the cost, and the figure stays metric to confirm until you pull it. Nothing below states a share of failures as fact.

We wrote this for operators at $3M–$30M in revenue on Shopify Plus or a paid subscription platform, where a failed recurring charge is real money every month. If you take a handful of orders a week, the checklist still works, but it is not the reader we wrote it for.

Why does it matter how big the problem is?

Two independent-looking benchmarks frame the size. Baremetrics puts revenue lost to failed payments at around 9% of monthly recurring revenue, and Paddle’s ProfitWell puts involuntary churn at 20–40% of all subscription churn. Stripe itself says 25% of lapsed subscriptions trace back to payment failure. All three are vendor-reported and cover different populations, so treat them as a reason to measure yours, not as a forecast.

The reason involuntary churn is worth chasing first is that the customer did not decide anything. They still want the product. Their card expired, their bank got nervous, or an email landed in spam. Recovering that customer costs a retry or a message, not a discount. The same logic runs through involuntary churn and how to reduce involuntary churn, which cover the wider programme. This article stays on the Stripe mechanics.

How do you read a Stripe failed payment before fixing it?

Reading a Stripe failed payment means opening the failed charge, not the invoice or the customer. On the charge, three fields matter: the failure_code, the decline_code, and the outcome block, which carries the risk level and the network status.

The failure_code is the broad class, such as card_declined. The decline_code is the issuer’s reason, such as insufficient_funds, expired_card or incorrect_cvc. The outcome tells you whether the bank said no or Stripe’s own risk layer stopped the charge before it reached the bank. That distinction is the single most useful thing in the record, because it decides who you ask.

A charge blocked by Radar never reached the issuer, so retrying the same card against the same rule will fail again. A charge the issuer declined is a bank decision, and some bank decisions reverse on a later attempt.

Which fields to export

Pull failed charges for a period with these columns: charge ID, customer ID, amount, failure_code, decline_code, the outcome type, whether the payment was on-session or off-session, and whether a later attempt on the same invoice succeeded. That last column is what turns a list of errors into a recovery picture.

What are the causes of a Stripe failed payment, in the order to check them?

The sequence in this list is the order in which we would rule causes in or out, cheapest check first. It is a debugging order, not a frequency table. Where a cause has a clear owner and a clear fix, the section says so.

1. The stored card has expired or been replaced

Expired and replaced cards head the list because the check is trivial and the fix is well understood. A subscription bills months after the card was saved. The card expires, or the customer’s bank issues a new number after a lost card, and the stored credential quietly stops working.

The decline code is usually expired_card, though some issuers return a generic decline for a closed or reissued card. The fix has two parts. First, use Stripe’s automatic card updater support where your account has it, which lets the card networks refresh some credentials without the customer doing anything. Second, send a pre-expiry email so the customer can update before the charge. The updater does not reach every card, so the email is the backstop.

2. The bank declined for insufficient funds

An insufficient_funds decline is the honest one. The account balance was too low on the day of the charge. It is also the cause most likely to clear by itself, because pay cycles move balances.

The fix is timing, not messaging. A retry a few days later, ideally after a typical payday boundary for your customer base, recovers many of these. Emailing straight away treats a temporary shortfall as a problem the customer must solve and costs you goodwill. Hold the email until the retry sequence has had a fair go.

3. The issuer gave no reason

Generic declines and “do not honour” style codes are the issuer saying no without saying why. They are frustrating because the code gives you nothing to act on, and they are common on recurring, off-session charges, where the issuer’s fraud model has less context than it has for a customer standing at a checkout.

The fix is a mix. Retry, because some clear. Check that the payment method was saved with the right setup so the issuer sees a legitimate stored-credential charge. And offer the customer a way to try a different card, since no amount of retrying will change a bank’s standing preference.

4. Authentication was required and nobody completed it

Some cards need the customer to authenticate a charge, through the 3D Secure step in Europe and the UK and increasingly elsewhere. An off-session subscription charge cannot pop up a challenge, so if the issuer demands authentication, the charge fails with an authentication-required outcome and the invoice waits for the customer.

Stripe Billing has hosted flows and emails that bring the customer back to authenticate. The common mistake is leaving those emails switched off, or sending your own message with a link to a card-update page that does not trigger authentication. Turn on the built-in customer emails for this case and check that the link you send lands on a page that can complete the challenge.

5. The customer’s card was fine, but the security code or address was wrong

Incorrect CVC and postcode mismatches show up mostly on first charges and after a customer edits their details. They are usually not a subscription-renewal problem, which is why they rank lower. On a new signup they are a checkout problem: the form validated loosely, or autofill filled the wrong field.

The fix sits in the checkout, not in recovery. Confirm the form passes the security code and postal code to Stripe, and that your Radar rules are not set to reject on a mismatch for customers you would otherwise accept.

6. Stripe Radar or your own risk rules blocked the charge

A charge stopped by Radar shows a risk outcome and never reaches the bank. This is the failure operators most often blame on the customer and least often check. Rules written to stop a burst of fraud can stay in place for months and quietly block good repeat customers.

Open the rule that fired. If a rule blocks on country mismatch, prepaid cards, or a velocity limit, ask whether it also catches your renewals. The fix is a scoped rule or an allow-list for customers with a paid history. For the wider trade-off between blocking fraud and losing good orders, see the material under fraud and chargebacks.

7. The card is closed, lost or stolen

A card reported lost or stolen returns codes that mean do not retry. Hammering a card in these states looks like abuse to the issuer and can hurt your standing. The fix is to stop retrying, mark the payment method dead, and ask the customer for a new one immediately. This is one case where fast email is right.

8. Your retry schedule stops too early, or never starts

A misconfigured retry schedule is a failure you cause. Stripe Billing lets you choose between a fixed schedule and Smart Retries, and lets you decide what happens to the subscription when retries end. If the schedule ends after a couple of quick attempts, or if the end state cancels the subscription while a customer is mid-recovery, you convert recoverable declines into lost customers.

Check three things: which retry mode is active, how long the window runs, and what state the subscription lands in when it ends. We treat this as the cause to check whenever the recovery rate is low and the decline codes look mostly benign.

9. The customer’s bank or region has quirks you have not accounted for

Some issuers, currencies and countries behave differently: local card schemes, strict authentication regimes, or currencies your account is not set up to settle. These show up as clusters in your export, not as scattered noise. Group failed charges by card country and currency before you conclude the problem is random.

How do you run a Stripe failed payment test?

A Stripe failed payment test uses test mode and Stripe’s published test card numbers, which force specific outcomes. Never use a real card to simulate a failure. Working in test mode is free and leaves no trace on customers.

Two test cards cover most needs. One is declined outright on the charge. The other attaches to a customer successfully and then fails on the first charge, which is the useful case for subscriptions because it mirrors a card that worked at signup and failed at renewal. Stripe’s testing documentation lists the current numbers and the outcome each produces, so copy them from there rather than from memory.

Use test clocks to watch retries fire

A Stripe test failed payment on its own only shows the first attempt. The interesting behaviour is what happens over the following days. Test clocks let you create a customer and subscription against a simulated clock, then advance time and watch invoices, retries, emails and status changes play out in seconds.

Run this sequence once for each end state you care about: attach the failing card, advance the clock through each retry, and confirm the subscription lands in the state you chose. Then repeat with a card that fails once and succeeds on retry, to confirm your success path clears the past_due status and does not leave a stray open invoice.

What to check in the test

Check that webhooks fire and that your systems react. A invoice.payment_failed event should reach whatever sends your recovery email, and invoice.paid should stop it. Many recovery gaps are not in Stripe at all: the webhook endpoint returns an error, the email tool does not receive the event, or a suppression rule keeps the message from sending. The test is the cheapest way to find that.

What does a Stripe subscription failed payment do to the subscription?

A Stripe subscription failed payment moves the subscription to past_due when the latest invoice fails and retries are still running. The customer keeps access unless your own logic removes it. When retries end, Stripe applies whichever end state you configured: cancel the subscription, mark it unpaid, or leave it past due.

That final setting matters more than most teams realise. Cancelling automatically is simple but forecloses late recovery, because a customer who updates their card a week later now has to resubscribe from scratch, often at a new price. Marking unpaid keeps the record open so a late card update can revive it. Pick this deliberately, and decide what your product does with a past_due customer, whether full access, limited access or a banner, since that is a support and policy decision as much as a billing one. If you run subscriptions through a platform layer, the equivalent behaviour lives in its own settings, as covered in Recharge dunning.

What do retries fix, and what do they never fix?

Retries fix declines that can change without the customer doing anything. Low balance, a temporary issuer block and a network blip can all clear on a later attempt. Retries never fix an expired card, a closed account, a missing authentication step or a Radar block, because the underlying condition stays the same.

That split is why the ranked list guides action. Causes 2 and 3 respond to timing. Causes 1, 4 and 7 need the customer. Causes 5 and 6 need you to change configuration. Sending a retry at a cause that needs a human wastes attempts, and sending a human email at a cause that needs time wastes goodwill.

Stripe’s Smart Retries choose attempt timing using its own model, and the fixed-schedule option puts you in control. Which is better for your account is an empirical question. Run one against the other on comparable cohorts, using the recovered-amount column from your export, before you commit. The general playbook for sequencing retries and messages is in dunning management, and the software options are compared in dunning management software.

When is a Stripe failed payment your own fault?

A failure is your own doing when it traces to configuration, not to the customer or the bank. Four patterns recur. Radar rules that are too broad. A retry window that ends too soon. Customer emails for failed payments and authentication left off. And a webhook consumer that drops invoice.payment_failed events.

Each of these is invisible in the Dashboard’s failure count, because the count only tells you charges failed, not why. That is why the export with decline codes and outcome types earns its place: it lets you separate the failures the customer owns from the ones you own. Fix your own layer first. It is the only part where the improvement is guaranteed, because nobody else has to act.

One caution on scope. Recovery tooling does not belong on customers you should not keep. If a chargeback or fraud pattern sits behind the failures, that is a risk problem to handle separately, not a recovery problem to retry your way out of.

How do you size the cost of failed payments for your own store?

Sizing the cost means measuring three amounts for one period: revenue billed, revenue that failed on first attempt, and revenue recovered afterwards. The gap between failed and recovered is your lost revenue, and dividing it by billed revenue gives your own rate to compare with the Baremetrics and ProfitWell figures.

Do the same split by decline code. The share of lost revenue attached to each code is what actually ranks the causes for your account, and it may not match the order in this article. That is fine. Our order is where to start looking; your export is what to trust. Any share we would quote here would be a metric to confirm for your account, so we leave it blank on purpose.

For a quick estimate, the failed payment calculator takes your billed and recovered amounts and returns the monthly and annual gap, and the failed payment and involuntary churn benchmark shows how the published figures compare.

Who is this checklist not for?

This checklist is not for brands below the $3M floor Pointerflow publishes, where a founder can still read every failed payment by hand. It is also not for teams whose failures come mostly from chargebacks and disputes, which need a different playbook, and not for anyone who wants a promise of a specific recovery percentage. We do not state one, because it depends on your customer mix, your card base and your existing settings.

A failed payment is a payment recovery problem, and at the volumes above it needs an owner across Stripe configuration, retry timing, customer messaging and reporting together. That is the work Pointerflow’s payment recovery service covers, starting from your own decline-code export rather than a template.

Sources

  • Baremetrics: around 9% of monthly recurring revenue lost to failed payments (vendor-reported).
  • Paddle / ProfitWell: 20–40% of subscription churn is involuntary (vendor-reported).
  • Stripe: 25% of lapsed subscriptions trace to payment failure (vendor-reported).
  • Everything else is written from long-standing, documented Stripe behaviour. Check Stripe’s current documentation for test card numbers, retry options and updater coverage before you configure anything.

Frequently asked

Which Stripe decline code should I look at first?

Start with the decline_code on the failed charge, not the generic card_declined error that wraps it. The decline_code names the bank's reason, such as insufficient_funds or expired_card. Generic and do-not-honour style codes tell you the issuer gave no reason, so treat them as a retry candidate rather than a card-update request.

Does Stripe retry a failed subscription payment automatically?

Stripe Billing can retry failed invoice payments, either on a fixed schedule you set or through its machine-learning based Smart Retries. Both are configured in your Billing settings, so check which one is active on your account. Retries only help declines that can clear on their own, and they do nothing for a card that no longer exists.

What is the difference between past_due and unpaid on a subscription?

past_due means the latest invoice failed and Stripe is still retrying or waiting on the customer. Unpaid, or the cancelled state, is what you choose to happen once retries are exhausted. That end state is a setting in your Billing configuration, so confirm it deliberately instead of accepting the default.

Can I test a failed payment without a real card?

Yes. In test mode, Stripe publishes test card numbers that force specific outcomes, including a card that attaches to a customer but fails on the first charge. Use those in test mode only, and pair them with test clocks so you can advance time and watch retries fire without waiting days.

Why did a customer's card fail when it works everywhere else?

Issuers judge each merchant and each transaction separately. A card can pass at a grocery store and fail on a recurring charge because of a fraud model, a stale stored credential, or a missing authentication step. Look at the outcome on the specific charge, including the risk and network fields in the payment record.

How do I stop expired cards causing failures?

Turn on Stripe's automatic card updater features where your account supports them, and send a pre-expiry email so the customer can replace the card before the next charge. The updater covers only part of the card base, so the email remains your backstop for the cards it cannot refresh.

Should I email customers on every failed payment?

No. Email when the customer can do something about it: update an expired card, complete authentication, or replace a closed account. A one-off insufficient-funds decline often clears on a later retry, and an urgent email about it costs goodwill. Match the message to the decline code instead of sending one template.

Can a failed payment be caused by my own Stripe settings?

Yes. Radar rules that are too strict, a missing billing address requirement, an unsupported payment method type, or a retry schedule that stops too early all create failures Stripe itself would not. Review your Radar rules and Billing settings before assuming every failure is the customer's bank.

How do I find out how much a failed payment problem costs?

Export failed and later-recovered invoices for a period, sum the recovered and lost amounts, and divide by your recurring revenue for the same period. Any industry figure is only a comparison point. The number that matters is yours, and Pointerflow's failed-payment calculator walks through the method.

Does a failed payment always mean the customer wanted to leave?

No. Involuntary churn is the customer who intended to stay and lost the subscription to a payment problem. It is a different problem from a customer who chose to cancel, and it is fixed with different tools: retries, updater services, and well-timed messages, not save offers or discounts.

When should I bring in outside help with failed payments?

When the fixable share is large enough to matter and your team cannot instrument it. Recovery involves Stripe settings, emails, retry timing and reporting together. If revenue at stake is meaningful and nobody owns the whole loop, an outside team can own it end to end.

Next step

Is this your payment recovery problem, or a symptom of another one?

Bring your numbers — the churn split, the decline rate, whatever your flows are earning — and we will tell you which of them is the expensive one.

Book a call →