Voluntary churn announces itself: a subscriber opens your portal and cancels. Involuntary churn doesn't. A card expires, a charge bounces, the retries quietly run out, and a subscriber who never chose to leave is gone. If you've never checked how many of your "cancellations" are actually payment failures, check — the split surprises almost everyone who pulls it.
This is one of the first places I look in a subscription teardown, because it's the leak nobody is staring at. Checkout gets an owner. The cancellation flow gets a meeting. The dunning flow — the machinery that runs when a recurring charge fails — usually runs on whatever defaults the app shipped with.
Why subscription payments fail
Not one problem — a family of them:
Expired and reissued cards. Cards expire on a schedule, and banks also reissue them off-schedule: fraud somewhere upstream, a bank merger, a lost wallet. The subscriber did nothing; their stored card simply stopped being real. Give any subscriber file enough months and this happens to a slice of it.
Insufficient funds. The charge arrived at the wrong moment for that account. Nothing is wrong with the card; everything is wrong with the timing. The same charge can succeed a few days later.
Soft versus hard declines. The distinction that should drive everything downstream. A soft decline is the bank saying "not right now" — insufficient funds, a temporary hold. A hard decline is "not ever" — card reported stolen, account closed, number invalid. Retrying a soft decline is sensible. Retrying a hard decline is pointless; that card is never coming back, and the only fix is a new payment method from the customer.
Everything else. Fraud-screening false positives, processor hiccups, bank maintenance windows. Individually rare, collectively a steady hum.
What dunning actually is
Dunning is everything that happens between "the charge failed" and either "the charge succeeded" or "the subscription is closed": the retry schedule, the customer messages, the card-update path, and the end state. On Shopify, subscriptions run on subscription contracts; when a recurring charge comes due, a billing attempt runs, and when it fails, your subscription app decides what happens next. That decision tree is your dunning flow — whether or not anyone at your company has ever looked at it.
The parts of the tree:
The retry schedule. How many attempts, spaced how far apart, before giving up. Retrying instantly after an insufficient-funds decline mostly re-asks a question the bank just answered; spacing retries out gives paydays and deposits a chance to land. Apps ship default schedules and let you adjust attempt counts and spacing — how clever the schedule can get beyond that varies by app.
Pre-dunning. The cheapest recovery is the failure that never happens: the card on file expires next month, so ask for the update before the charge fails, not after. Whether your app sends expiry warnings, and how far you can shape them, is worth checking — apps differ here.
Card updates without friction. When you do have to ask, the ask has to be one tap: a message that lands on a phone and links straight to the portal's payment-method page. Every extra step between "my card failed" and "my card is updated" loses some of the people who were willing.
Automatic card refreshing. Card networks run updater programs that can refresh stored card details when a bank reissues a card, with no customer action at all. Whether your charges benefit depends on your payment setup — check what your processor provides rather than assuming.
The end state. When the last retry fails: cancel the subscription, pause it, or hold the order for manual follow-up. Defaults differ by app, and the right answer depends on your product. A paused subscription with a good win-back path can come back; a hard-cancelled one usually needs the customer to start over from scratch.
Messaging through all of it. Email, SMS if you have consent, and a tone that assumes good faith — the subscriber didn't fail you, their card failed them. "Your box is on hold — tap here and it ships as planned" reads like a favor. A payment-demand email reads like a debt collector. Same information, different outcome.
What you can configure in the app
Real controls exist here, and you should max them out before considering anything custom. In Seal's case — the app I build on — dunning behavior is configurable from the settings the app exposes. [TK-verify: confirm the current list of Seal's configurable dunning settings — retries, failure emails, end-state handling — before publish.] The general rule across apps: attempt counts, spacing, message templates, and the end state are typically settings; the intelligence connecting them is typically not.
Do these this week, whatever app you're on:
- Find out what your retry schedule actually is — not what you assume, what's configured. Most merchants have never looked.
- Read your failure emails as a customer would. Send yourself one.
- Check whether an expiring card triggers any message at all before the charge fails.
- Check the end state: what happens to a subscriber after the final retry?
That's an hour of settings work, and it's the best-paid hour in subscriptions.
What needs custom work
The ceiling shows up where your program's economics stop being average:
Margin-tuned retry logic. How hard to chase a failed charge is an economics question: the value of the order, the cost of another attempt, the risk of annoying a subscriber who was coming back anyway. An app applies one schedule to every failure. A custom layer can decide per case — by decline type, order value, subscriber tenure — because those variables are readable through the APIs, and rules can be built on them. This is what "dunning tuned to your margins" means in practice.
Recovery flows with your brand's judgment. The generic flow sends everyone the same sequence. A custom flow can treat a longtime subscriber whose card expired differently from a first-box subscriber whose charge bounced — different message, different offer, different patience. That's retention logic, and it's built, not toggled.
Analytics on the leak itself. The dashboard tells you charges failed. The questions that drive fixes sit one level deeper: which failures recover on their own, which messages actually get cards updated, where in the sequence subscribers go silent. Answering those means joining billing events with subscriber history — an analytics job on the API side, and usually the first custom piece I suggest, because it tells you whether you need the other pieces at all.
Win-back past the end state. After the final retry, the app's job ends. But the subscribers who fell off six weeks ago are still the warmest list your store has. Building them a clean path back — their old plan, their old terms, one tap — is custom work that's easy to under-prioritize precisely because the leak it fixes is quiet.
Where to start
Not with a build. Start with the settings audit above — it's free and takes an hour. Then measure the leak before deciding how much machinery it deserves: a small leak deserves settings, a big one deserves engineering.
If you'd rather have the leak found for you, I do a free teardown: a short recorded review of your live subscription flow, naming 2–3 revenue leaks. Failed payments are one of the first places I look. No pitch attached. Get a free teardown →
And if what you find is that fixing it properly needs more than the settings expose, the ladder of options — configure, extend, go custom — is mapped in When Seal Subscriptions can't do what you need.