Stripe Revenue Recovery Settings: Complete Configuration Guide (2026)
Stripe has 8+ settings that affect payment recovery, scattered across Dashboard > Settings > Subscriptions and emails. Most founders use the defaults and don't realize they're recovering 10-15% less than they could. The optimal SaaS configuration: Smart Retries ON, post-retry status = "mark as unpaid" (not cancel), customer emails ON for failed payments, invoice finalization emails ON, payment due days = 1, and automatic tax calculation if applicable. Even with perfect settings, Stripe's built-in recovery caps at ~25%. Adding a dedicated recovery layer pushes it to 40-55%.
Why Default Settings Lose Revenue
Stripe ships with conservative defaults designed to work for every business type. e-commerce, marketplaces, SaaS, and usage-based billing. But SaaS subscriptions have unique recovery dynamics: your customer has an active account they want to keep, the charge is recurring (so the card is usually still valid), and the relationship is ongoing. Conservative defaults optimized for one-time purchases leave SaaS revenue on the table.
The biggest default mistake: Stripe's post-retry behavior is often set to "Cancel the subscription" after all retries fail. For SaaS, this is the nuclear option. It permanently ends the customer relationship when a temporary payment issue could have been resolved with one more email or a card update link. Switching to "Mark as unpaid" preserves the subscription and gives you more time to recover.
Here are the 8 settings that affect recovery, and why each one matters:
Smart Retries toggle. uses Stripe's ML to pick optimal retry timing vs; a fixed schedule. ML-based retries recover 5-10% more than fixed intervals.
Retry schedule. If Smart Retries is off, this controls when retries happen (e.g., 3, 5, 7 days). Most founders leave this at default without optimizing for their billing cycle.
Post-retry subscription status. what happens after all retries fail. Options: cancel subscription, mark as unpaid, or leave as past_due. This single setting determines whether you lose the customer permanently or get more time to recover.
Customer emails for failed payments. Stripe can send an email when a payment fails. This is separate from your own dunning emails. Turning it off when you have no dunning system means the customer never knows their payment failed.
Invoice finalization email. sends the customer an email when a new invoice is created. For SaaS, this serves as a payment receipt and helps customers recognize the charge on their statement.
Invoice payment due days. how many days after creation the invoice is due. Shorter = faster first retry on failure. Default is often 30 days (designed for B2B invoicing, not SaaS subscriptions).
Automatic collection. whether Stripe automatically attempts to charge the customer or waits for manual payment. Must be "on" for subscription auto-billing.
Subscription proration behavior. how mid-cycle plan changes are handled. Not directly a recovery setting, but incorrect proration can cause unexpected charge amounts that trigger declines.
Warning: Changes to these settings only affect future invoices, not existing past_due invoices. If you have customers currently in a retry cycle, the old settings still apply to their invoices. You need to manually retry or update those invoices individually.
Optimal Configuration (Step-by-Step)
Open your Stripe Dashboard and navigate to Settings > Subscriptions and emails. Here is the exact configuration optimized for SaaS recovery:
Smart Retries: Turn ON. This lets Stripe's ML model pick the best retry time based on the decline code, card type, and issuing bank. It recovers 5-10% more than any fixed schedule.
Retry schedule (if Smart Retries is off): Set to 3, 5, and 7 days after the initial failure. This gives the customer time to resolve the issue while keeping urgency high. Do not space retries more than 7 days apart.
After all retries fail: Select "Mark the subscription as unpaid". NOT "Cancel the subscription." Unpaid keeps the subscription alive so you (or your dunning tool) can continue recovery efforts. You can always cancel later if recovery fails.
Send emails when payments fail: Turn ON. Even if you use a third-party dunning tool, Stripe's built-in email acts as a backup notification. The customer sees it's from Stripe (trusted sender), which increases urgency.
Send finalization emails for one-off invoices: Turn ON. This ensures customers receive a receipt for every charge, reducing disputes and chargebacks.
Send reminders for upcoming renewals: Turn ON if available. Giving customers advance notice reduces "I didn't expect this charge" disputes.
Navigate to Settings > Invoices. Set default payment terms to "Due upon receipt" (or 1 day). This ensures failed subscription payments enter the retry cycle immediately rather than waiting 30 days.
Under Settings > Customer portal, enable payment_method_update so customers can self-service their card updates. This reduces support tickets and speeds up recovery.
// Check your current subscription settings programmatically
// Note: not all settings are API-accessible; some are Dashboard-only
// Check Smart Retries and retry schedule
const settings = await stripe.accounts.retrieve();
console.log('Account ID:', settings.id);
// Check a specific subscription's collection behavior
const sub = await stripe.subscriptions.retrieve('sub_xxx');
console.log('Collection method:', sub.collection_method);
// Should be "charge_automatically" for SaaS
console.log('Days until due:', sub.days_until_due);
// Should be null (immediate) or 1 for SaaS
// Check billing portal configuration
const configs = await stripe.billingPortal.configurations.list();
for (const config of configs.data) {
console.log('Portal config:', config.id);
console.log('Card update enabled:',
config.features.payment_method_update.enabled
);
}// When creating subscriptions, enforce optimal settings
const subscription = await stripe.subscriptions.create({
customer: 'cus_xxx',
items: [{ price: 'price_xxx' }],
collection_method: 'charge_automatically',
// Don't set days_until_due for auto-charge (it's immediate)
payment_behavior: 'default_incomplete',
payment_settings: {
save_default_payment_method: 'on_subscription',
payment_method_options: {
card: {
request_three_d_secure: 'automatic',
},
},
},
});
// Update existing subscriptions to use optimal collection
const updated = await stripe.subscriptions.update('sub_xxx', {
collection_method: 'charge_automatically',
});
console.log('Updated:', updated.id, updated.collection_method);// Configure what happens when all retries are exhausted
// This is set at the subscription level via the API
const subscription = await stripe.subscriptions.create({
customer: 'cus_xxx',
items: [{ price: 'price_xxx' }],
// When all retries fail, mark as unpaid (don't cancel)
// This is controlled by your Dashboard settings, but you can
// also handle it via webhook:
});
// Listen for invoice.payment_failed and take action
app.post('/webhooks/stripe', async (req, res) => {
const event = stripe.webhooks.constructEvent(req.body, sig, secret);
if (event.type === 'invoice.payment_failed') {
const invoice = event.data.object;
const attemptCount = invoice.attempt_count;
console.log(`Payment failed for ${invoice.customer}`);
console.log(`Attempt #${attemptCount}`);
console.log(`Next retry: ${invoice.next_payment_attempt
? new Date(invoice.next_payment_attempt * 1000)
: 'No more retries'
}`);
// If this is the final attempt, trigger your own recovery
if (!invoice.next_payment_attempt) {
console.log('All Stripe retries exhausted. starting extended recovery');
await startExtendedRecovery(invoice.customer, invoice.id);
}
}
res.json({ received: true });
});Tip: After changing settings, create a test subscription in test mode and simulate a failed payment using Stripe's test card 4000000000000341 (attach succeeds, charge fails). Walk through the entire retry cycle to verify your settings work as expected before they affect real customers.
Beyond Settings: The 25% Recovery Ceiling
Even with every Stripe setting perfectly optimized, you'll hit a ceiling of approximately 25% recovery on failed payments. See the state of Stripe SaaS churn for industry data. That's because Stripe's recovery tools are limited to: automatic retries (Smart Retries), a single email notification, and the customer portal for self-service card updates. There's no multi-touch dunning sequence, no pre-dunning prevention, no behavior-based outreach, and no cancel flow interception.
The math is clear: Stripe's built-in recovery (Smart Retries + one email) recovers ~15-25% of failed payments. Use our churn cost calculator to see what this means for your business. Adding a dedicated recovery layer with multi-email dunning, one-click card update links, pre-dunning card expiry alerts, and escalating urgency messaging pushes total recovery to 40-55%. For a SaaS at $20K MRR with 5% monthly payment failure, that's the difference between recovering $150-$250/mo and recovering $400-$550/mo.
SaveMRR is the recovery layer that sits on top of your optimized Stripe settings. It doesn't replace Stripe's Smart Retries. It complements them. Stripe handles the payment retry timing. SaveMRR handles everything else: the 7-email dunning sequence, card expiry pre-alerts, one-click update links, and real-time recovery tracking. Together, they form a complete recovery pipeline.
// Recovery rate modeling for a SaaS at $20K MRR
// with 5% monthly payment failure rate ($1,000 at risk)
const scenarios = {
stripeDefaults: {
smartRetries: false,
postRetry: 'cancel', // Loses customer permanently
customerEmail: false, // Customer doesn't know
recoveryRate: 0.10, // ~10% recovery
recovered: '$100/mo',
lost: '$900/mo',
},
stripeOptimized: {
smartRetries: true, // ML-based retry timing
postRetry: 'unpaid', // Preserves the subscription
customerEmail: true, // Customer gets notified
portalEnabled: true, // Self-service card update
recoveryRate: 0.25, // ~25% recovery
recovered: '$250/mo',
lost: '$750/mo',
},
stripeOptimizedPlusSaveMRR: {
smartRetries: true, // Stripe handles retries
sevenEmailDunning: true, // SaveMRR handles dunning
preDunning: true, // Card expiry alerts
oneClickCardUpdate: true, // Fresh links in every email
recoveryTracking: true, // Real-time analytics
recoveryRate: 0.47, // ~47% recovery (average)
recovered: '$470/mo',
lost: '$530/mo',
savemrrCost: '$19/mo', // Early-bird pricing
netGain: '$451/mo', // After SaveMRR cost
},
};
// The gap between optimized Stripe ($250) and
// optimized Stripe + SaveMRR ($470) is $220/mo.
// SaveMRR costs $19/mo. That's an 11.6x ROI.Tip: Run a free Revenue Scan at app.savemrr.co to see your actual recovery rate with current Stripe settings. The scan analyzes your last 90 days of payment data and shows you exactly how much of the $1,000/mo at risk you're currently recovering, and how much more SaveMRR could recover. First $200 recovered is free.
Related Stripe Billing Issues
Frequently Asked Questions
Does changing Stripe recovery settings affect existing past_due subscriptions?
No. Settings changes only apply to future invoices. Existing invoices in a retry cycle will continue using the settings that were active when the invoice was created. To change recovery behavior for existing past_due invoices, you need to manually retry them (stripe.invoices.pay) or void and re-create them. This is a common gotcha. founders change settings and wonder why existing customers aren't affected.
Should I use Smart Retries or a custom retry schedule?
Smart Retries for almost every SaaS. Stripe's ML model has been trained on billions of payment attempts and picks retry timing based on the decline code, card type, issuing bank, and time of day. The only reason to use a custom schedule is if you need retries aligned to specific business days (e.g., payroll cycles for B2B). For B2C SaaS, Smart Retries consistently outperforms fixed schedules by 5-10%.
What's the best post-retry status for SaaS subscriptions?
"Mark as unpaid" is the best choice for SaaS. It keeps the subscription active (so your dunning tools can continue working) but you can restrict access in your app by checking the subscription status. "Cancel" permanently ends the relationship and makes recovery much harder. "Leave as past_due" is also viable but can lead to zombie subscriptions if you don't have a cleanup process.
How can I test Stripe recovery settings without affecting real customers?
Use Stripe's test mode (Dashboard toggle in the top-left). Create a test customer, attach a test card that will fail on charge (4000000000000341), and create a subscription. The payment will fail and you can watch the retry cycle play out. Test mode uses a compressed timeline. retries happen faster than in live mode. You can also use the Stripe CLI to trigger webhook events locally for testing your webhook handlers.
Will Stripe's recovery settings improve over time?
Stripe continues to improve Smart Retries (their ML model gets better with more data) and occasionally adds new recovery features. However, Stripe's roadmap focuses on payment processing, not retention. Features like multi-email dunning sequences, cancel flow interception, and churn prediction are outside Stripe's core scope and are unlikely to be added. The gap between "payment processor" and "retention platform" will persist, which is why dedicated tools like SaveMRR exist.
SaveMRR catches these automatically
Stop firefighting Stripe billing issues manually. Paste your API key, get a free Revenue Scan in 60 seconds, and let SaveMRR handle recovery automatically.
Run my free scan