Most SaaS founders track MRR, new signups, and voluntary churn religiously. But there's a number hiding in your Stripe dashboard that you've probably never looked at: failed payments.
On average, around 9% of subscription payments fail every month. Not because customers canceled, but because their credit card expired, hit its limit, or got flagged by the bank. These customers didn't choose to leave. They just silently disappeared from your revenue.
Here's how to find out if this is happening to you.
Step 1: Go to your Stripe Dashboard
Log into your Stripe account and navigate to Payments in the left sidebar. By default, you're looking at successful payments. That's the problem: you never see what's failing.
Step 2: Filter by Failed Payments
Click the Status filter at the top and select Failed. This shows every payment attempt that didn't go through.
Now look at the date range. Set it to the last 30 days and count the total amount. Compare that to your MRR. If you're like most SaaS businesses, you're looking at 5-10% of your monthly revenue sitting there, uncollected.
Step 3: Look at the Failure Reasons
Click on any failed payment and Stripe will show you the decline code. The most common ones are:
- card_declined: Generic decline. Could be insufficient funds, fraud detection, or bank restrictions.
- expired_card: The customer's card expired and they never updated it.
- insufficient_funds: The customer didn't have enough balance. Often temporary: they might have funds a few days later.
- authentication_required: The bank wants 3D Secure verification but the customer never completed it.
Each of these requires a different recovery strategy. An expired card needs a polite email asking the customer to update their payment method. Insufficient funds? You're better off waiting a few days and retrying silently.
Different decline codes require completely different recovery strategies
Step 4: Check Stripe's Built-in Retry Schedule
Go to Settings > Billing > Subscriptions and emails > Manage failed payments. Here you'll see Stripe's Smart Retries configuration. By default, Stripe will retry failed payments using their own schedule.
The problem? Stripe's retry logic is generic. It doesn't optimize based on the specific decline reason, and the retry timing isn't tailored to maximize recovery. More on that in our post about why Stripe's default retries aren't enough.
What to Do With This Data
Now that you can see your failed payments, here's the math:
- Your MRR: Let's say $10,000
- Failed payment rate: ~9% = $900/month
- Stripe's default recovery rate: ~38% = $342 recovered
- What's left on the table: $558/month = $6,696/year
That's real money walking out the door every month. And most founders don't know it's happening until they check.
Your Options
You have three choices:
- Do nothing. Keep losing 5-10% of MRR and let Stripe's basic retries handle it (they'll recover about a third).
- Handle it manually. Check failed payments weekly, email customers yourself, retry manually. Works at small scale but doesn't scale.
- Automate recovery. Use a dunning tool that retries intelligently based on the failure reason and reaches customers through channels they actually check, like email or WhatsApp.
Whatever you choose, the first step is the same: go look at your failed payments right now. The number might surprise you.