There's one screen in Stripe I quietly avoided for months: the failed charges tab.
I'd check MRR. I'd check new signups. I'd refresh those out of nervous habit. But the failed payments? I always told myself I'd "get to it later."
Looking back, I avoided it because it felt like a scoreboard for things I couldn't control. New signups feel like a win I earned. Failed charges feel like money slipping out a hole in the boat, and staring at the hole doesn't feel productive.
Then one evening I actually sat down and went through it line by line. And the rows were more specific, and more human, than I expected:
None of those three people decided to leave. But in my head I'd already filed them under "churned."
That's the part that got me. I'd been grieving them as lost customers, when most were closer to a delivery that failed at the door than a customer walking away. And each type needs a totally different response: the expired card needs a heads-up, the insufficient-funds one needs a smarter retry, the auth one needs a "confirm this was you" nudge, not a "replace your card" email.
I'm early and I won't throw out stats I can't back. But the general industry ranges (failed payments quietly costing something like 5-10% of revenue) stopped being abstract the moment I saw my own rows.
Going through it line by line is literally what made me start building Revova (https://revova.io) around this problem. The first thing I made was almost selfish: a scan that just shows you your own number, because I wanted to see my own damage first.
So I'll go first on the vulnerability: have you actually opened your failed charges tab recently and read it line by line? Or is it the screen you keep meaning to get to?
Failed payments are easy to ignore because the revenue already looked won. I would separate preventable failures, recoverable failures, and true churn, then measure recovered revenue without increasing complaints or involuntary cancellations.
Strong framing, and it maps closely to how we split it. The three-bucket split (preventable / recoverable / true churn) is basically what decline-code routing gives you for free — a card that's expired or hit insufficient funds isn't the same signal as a hard decline or a customer clicking cancel, so lumping them into one "failed payment" number hides which lever actually moves it.
On the "without increasing complaints" part — that's mostly an email-cadence problem, not a targeting problem. We cap it at 5 emails over 21 days for retryable declines, but hard declines and 3DS/auth failures get pulled into a faster, shorter 3-email track instead — no point sending the same nudge 5 times to someone whose card is dead. Complaint/unsubscribe rate per sequence is the metric we watch most closely for this exact reason; if that ticks up, it usually means the cadence is too aggressive for that decline type, not that the copy is wrong.
The harder part honestly isn't recovering the payment — it's attribution. Some of what shows up as "recovered" would've paid anyway on the next retry with zero email sent. Curious how you're thinking about isolating that in the preventable bucket, since that's the one most likely to inflate the recovered-revenue number if you're not careful.
This is the flip side of what I see building CancelKit — the involuntary churn you're describing (expired card, insufficient funds, auth required) needs a completely different playbook than someone who deliberately clicks cancel. The person with the expired card never made a decision to leave; the canceller did. Conflating both into one "churned" bucket is how teams end up sending win-back emails to people who were never gone. Curious — does Revova segment retry timing by decline code (e.g. wait a few days for insufficient funds vs. an immediate nudge for auth required)?
Good question, and yes — on the Pro plan it splits into two tracks. Retryable declines (insufficient funds, processing error, generic decline, velocity) get daily auto-retry attempts on the charge itself — plus if you turn on smart retry, we concentrate those attempts around payday windows (1st-5th, mid-month, month-end) instead of hammering it blind every day — alongside the standard 2/4/7/7-day email cadence. Hard declines and 3DS auth failures skip the auto-retry (no point re-charging a dead card) and go straight to a faster 3-email track, 1 day then 3 days apart. Starter plan uses one cadence for everything — the decline-based routing is the Pro differentiator. Appreciate the churn-bucket framing too, that's the exact reason we split it instead of treating "failed payment" as one bucket.
The line-by-line pass is useful once, but the product test is whether the scan turns rows into ranked recoverable revenue. I'd show count and value by failure reason, then one next action per bucket. Otherwise the failed-charges tab has just been rebuilt with nicer copy.
Fair hit, and you're right on the current state — today it's dedupe-by-customer, sorted by amount, with a count/total up top. No grouping by failure reason, no ranked bucket, no suggested next action per group. So as shipped it's closer to "failed-charges tab with a nicer summary" than the ranked-revenue view you're describing. Grouping by decline code (retryable vs. dead-card vs. needs-auth) with a next action per bucket is the right shape and not currently there — appreciate you calling it out specifically instead of just "add more filters."
Three buckets are enough for the first release: value at risk, next action, and recovery rate for retryable, dead-card, and auth failures. Ship that before turning it into a rules engine.