Every SaaS business running on Stripe has two options when a customer's payment fails: let Stripe handle the retry automatically, or build (or buy) custom retry logic that gives you more control. Most founders start with Stripe's default and never question it. That is a mistake worth thousands of dollars a month.
This guide breaks down exactly what Stripe Smart Retries do, where they fall short, what custom retry logic brings to the table, and how to decide which approach is right for your business. If you have been wondering why your payment recovery rate feels stuck, this is probably the missing piece.
What Are Stripe Smart Retries?
Stripe Smart Retries is Stripe's built-in system for automatically retrying failed subscription payments. When a charge fails, Stripe does not just give up. It schedules a retry and attempts to collect the payment again later. As of their current implementation, Smart Retries uses machine learning models trained on aggregate payment data across the Stripe network to determine when to retry.
Here is what Smart Retries actually does under the hood:
- Automatic scheduling: When a subscription payment fails, Stripe queues it for retry. You do not have to write any code or trigger anything manually.
- ML-based timing: Stripe uses data from millions of transactions across its platform to predict the best time to retry a specific failed payment. The idea is that patterns in the aggregate data can help determine when a retry is most likely to succeed.
- Up to 4 retries: By default, Stripe will retry a failed payment up to 4 times over a roughly 3 to 4 week period before marking the subscription as unpaid or canceling it, depending on your settings.
- Configurable in the Dashboard: You can adjust some retry settings in Stripe's Billing settings. You can set the number of retries, the interval between them, and what happens after all retries are exhausted (cancel the subscription, mark it unpaid, or leave it as-is).
On paper, this sounds pretty good. And for some businesses, it is perfectly fine. But once you start digging into the details, the gaps become clear.
The Limitations of Stripe Smart Retries
Stripe's Smart Retries work across the entire Stripe network. That is both their strength and their weakness. They are optimized for the average case, not for your specific business. Here is where they come up short.
No Decline Code Intelligence
When a payment fails, Stripe returns a specific decline code that tells you why it failed. An insufficient_funds decline is completely different from a card_not_supported decline, and they need completely different responses. But Smart Retries does not let you customize behavior based on the decline code. It treats all soft declines with a similar retry approach.
Think about it this way. If a customer's card was declined for insufficient funds, the best time to retry is around payday, maybe the 1st or 15th of the month. If the decline was a network timeout, you should retry in a few hours. If it was a do_not_honor response from the bank, you might want to wait longer and retry at a different time of day. Smart Retries cannot make these distinctions for your specific customer base.
Limited Visibility Into What Is Happening
With Smart Retries, you get a somewhat opaque process. You can see that a payment failed and that Stripe is retrying it, but you do not get deep analytics on retry performance by decline code, by plan type, by customer segment, or by time of day. You are trusting a black box.
For a bootstrapped SaaS doing $10K MRR, maybe that is fine. But once you start scaling and failed payments represent a meaningful chunk of revenue, you need to know exactly what is working and what is not. You need data to make decisions, and Smart Retries does not give you much.
Generic Timing That Misses Your Customer Patterns
Stripe's ML models are trained on aggregate data from all businesses on their platform. That includes everything from $5/month consumer apps to $10,000/month enterprise tools. The retry timing that works for a consumer subscription box is not the same timing that works for a B2B SaaS product.
Your customers have specific payment patterns. Maybe most of your customers are small businesses that get paid on the 1st and 15th. Maybe you serve freelancers who have unpredictable income timing. Maybe you are B2B and invoices get paid on net-30 cycles. Smart Retries does not account for any of this because it cannot. It does not know your business.
No Coordination With Dunning
Smart Retries operates independently from any dunning emails you might send. There is no intelligence linking "we just retried and it failed again" with "we should send the customer a different email now." If you are running dunning emails through Stripe's built-in email system or through your own tool, the retry schedule and the email sequence are operating as two disconnected systems.
In a well-optimized recovery flow, retries and customer communication work together. You retry silently first, and only email the customer if silent retries are not working. Smart Retries cannot orchestrate this because it only handles the retry part.
What Custom Retry Logic Offers
Custom retry logic means you are intercepting Stripe's invoice.payment_failed webhook events and managing the retry schedule yourself. Instead of letting Stripe decide when to retry, you make that decision based on your own rules and data. Here is what that unlocks.
Decline-Code-Based Retry Scheduling
This is the single biggest advantage. When you control the retry logic, you can look at the last_payment_error.decline_code on every failed charge and route it to a specific retry strategy:
insufficient_funds: Retry on likely paydays. For US customers, the 1st and 15th of the month tend to have the highest success rates. Schedule the retry for the next one of those dates, ideally in the morning.processing_erroror network timeouts: These are transient. Retry in 4 to 6 hours. The problem has probably already cleared up.generic_declineordo_not_honor: The bank is being vague. Wait 48 to 72 hours and retry at a different time of day than the original attempt. Sometimes rotating the retry time is enough to get past overzealous fraud filters.expired_cardorcard_not_supported: Do not retry at all. These are hard declines. Retrying wastes API calls and can actually hurt your standing with card networks. Instead, trigger a dunning email immediately asking the customer to update their card.
This approach alone can improve recovery rates by 30% to 40% compared to generic retry timing, because you are matching the retry strategy to the actual reason for the failure.
Configurable Schedules and Rules
With custom logic, you own the schedule completely. You can set different retry intervals for different plan tiers, different customer segments, or different failure patterns. You can say "enterprise customers get 6 retry attempts over 30 days" while "starter plan customers get 4 attempts over 14 days." You can pause retries during holidays when banks process differently. You can accelerate retries during the last few days of a billing cycle.
This level of control simply does not exist with Smart Retries.
Real-Time Analytics and Reporting
When you manage retries yourself, you capture every data point. You know exactly which decline codes you are seeing, which retry attempts succeed, what the average time-to-recovery is, and how much revenue you are recovering per month. You can slice this data by plan, by decline reason, by customer segment, by day of week.
This data is not just nice to have. It tells you where your recovery funnel is leaking and what to optimize next. Maybe you discover that your second retry attempt has a 35% success rate but your third attempt only recovers 5%. That tells you to invest more in getting the second retry right rather than extending to a fifth or sixth attempt.
Coordinated Recovery Flows
Custom logic lets you build a single recovery pipeline where retries, dunning emails, payment update pages, and analytics all work together. You can implement rules like "retry silently twice, then send the first dunning email, then retry once more, then send a more urgent email." The retry attempts and customer communications become one cohesive system instead of two disconnected ones.
Side-by-Side Comparison
| Feature | Stripe Smart Retries | Custom Retry Logic |
|---|---|---|
| Setup effort | Zero. Enabled by default. | Requires webhook handling and retry queue infrastructure. |
| Decline code routing | No. Same approach for all soft declines. | Yes. Different strategy per decline code. |
| Retry timing | ML-based, optimized on aggregate Stripe data. | Fully configurable per decline type, plan, segment. |
| Visibility / analytics | Basic. Limited breakdown in Stripe Dashboard. | Full. Track every metric by any dimension. |
| Dunning coordination | None. Retries and emails are separate. | Unified pipeline. Retries trigger email logic. |
| Hard decline handling | May still retry hard declines unnecessarily. | Skips hard declines, triggers dunning immediately. |
| Customer segmentation | No. Same rules for all customers. | Yes. Different rules per plan, segment, or MRR tier. |
| Typical recovery rate | Recovers ~50-60% of soft declines. | Recovers ~70-85% of soft declines. |
| Maintenance | None. Stripe handles everything. | Requires monitoring, but purpose-built tools handle this. |
| Cost | Free (included with Stripe Billing). | Build cost or subscription to a recovery tool. |
When Stripe Smart Retries Are Enough
To be fair, Smart Retries are not bad. There are situations where they make perfect sense and you should not bother with custom logic:
- You are pre-product-market-fit: If you have fewer than 100 customers and you are still figuring out your product, optimizing payment retries is not the best use of your time. Let Stripe handle it and focus on building something people want.
- Your failure rate is very low: If less than 2% of your charges fail each month, the absolute dollar amount you are losing is probably small enough that custom logic will not move the needle meaningfully.
- You do not have engineering bandwidth: Building custom retry logic from scratch takes a developer a couple of weeks minimum, plus ongoing maintenance. If your team is stretched thin on product work, the opportunity cost might not make sense.
- You are on Stripe Billing's Revenue Recovery feature: Stripe has been expanding their revenue recovery tooling. If you are on a Stripe Billing plan that includes their enhanced recovery features, you might already be getting some of the benefits of smarter retries.
When You Need Custom Retry Logic
For most SaaS businesses past the early stage, custom retry logic pays for itself many times over. Here are the signals that you have outgrown Smart Retries:
- Your MRR is above $20K: At this scale, even a 1-2% improvement in recovery rate translates to hundreds of dollars per month. Over a year, that compounds significantly.
- Your failure rate is above 5%: The higher your failure rate, the more money is at stake, and the more a decline-code-aware system can help.
- You serve different customer segments: If you have a mix of consumer and business customers, or if you serve customers across different geographies with different payment patterns, one-size-fits-all retries are leaving money behind.
- You want to understand your churn: If you care about knowing exactly how much revenue you are losing to failed payments and exactly how much you are recovering, you need the analytics that custom logic provides.
- You are already running dunning emails: If you are sending emails to customers about failed payments, those emails should be coordinated with your retry attempts. Otherwise you are sending "please update your card" emails even when a silent retry might have worked.
Building It Yourself vs Using a Tool
If you decide you need custom retry logic, the next question is build versus buy. Building from scratch means setting up a webhook endpoint for invoice.payment_failed, parsing decline codes, building a retry queue with a scheduler, implementing exponential backoff, handling edge cases like concurrent retries, and building a dashboard to monitor it all. That is a meaningful engineering project.
The edge cases are what get you. What happens when a retry succeeds but a dunning email was already sent? What if the customer updates their card during a retry window? What if Stripe's own retry fires at the same time as yours? These are solvable problems, but solving them takes time and testing.
For teams that want the benefits of custom retry logic without building the infrastructure, ChurnShield handles all of this out of the box. It connects to your Stripe account, classifies every failure by decline code, runs optimized retry schedules, coordinates with dunning emails, and gives you a real-time dashboard showing exactly what is being recovered. The whole setup takes about two minutes.
But whether you build or buy, the core principle is the same: treating all failed payments the same way is leaving money on the table. The decline code matters. The timing matters. The coordination between retries and customer outreach matters.
A Practical Hybrid Approach
One approach that works well for many teams is to start with Stripe Smart Retries as a baseline and layer custom logic on top. Here is how that looks:
- Keep Smart Retries enabled as a safety net. If your custom system misses something, Stripe's retries still run.
- Listen for
invoice.payment_failedwebhooks and classify the decline code. - For soft declines, schedule your own retry at an optimized time. Use
invoices.payto trigger the retry through the API. - For hard declines, skip retries entirely and trigger your dunning email sequence immediately.
- Track everything so you can see which system (yours or Stripe's) is actually recovering the revenue.
Over time, as you collect data on what is working, you can tune your custom logic and potentially disable Smart Retries entirely for the decline codes where your system performs better.
The Bottom Line
Stripe Smart Retries are a solid default. They are free, they require no setup, and they recover a decent chunk of failed payments using ML trained on billions of transactions. For early-stage SaaS businesses, they are fine.
But "fine" and "optimized" are very different things. Custom retry logic that routes based on decline codes, coordinates with dunning, and provides real analytics consistently recovers 20% to 40% more failed payments than default retries alone. For a SaaS doing $50K+ MRR with a 5-7% failure rate, that difference can easily be $1,000 to $3,000 per month in recovered revenue.
The question is not whether custom retry logic works better. It does. The question is whether the delta is worth the investment for your business right now. If you are past the early stage and failed payments are a real line item in your churn, the answer is almost certainly yes.
If you want to dig deeper into the full recovery picture beyond just retries, check out our guide on how to recover failed Stripe payments, which covers the complete five-strategy approach including dunning, prevention, and analytics.