<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mathieu Chambaud</title>
    <description>The latest articles on DEV Community by Mathieu Chambaud (@freki_managarm).</description>
    <link>https://dev.to/freki_managarm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F593799%2Fc283ae1a-dd8b-4346-b100-e52ec114b16d.jpg</url>
      <title>DEV Community: Mathieu Chambaud</title>
      <link>https://dev.to/freki_managarm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freki_managarm"/>
    <language>en</language>
    <item>
      <title>What Is Involuntary Churn In SaaS</title>
      <dc:creator>Mathieu Chambaud</dc:creator>
      <pubDate>Sun, 21 Jun 2026 11:28:45 +0000</pubDate>
      <link>https://dev.to/freki_managarm/what-is-involuntary-churn-in-saas-38gl</link>
      <guid>https://dev.to/freki_managarm/what-is-involuntary-churn-in-saas-38gl</guid>
      <description>&lt;h2&gt;
  
  
  Why involuntary churn costs more than founders expect
&lt;/h2&gt;

&lt;p&gt;Most SaaS founders obsess over voluntary churn: the customers who decide to leave. They run exit surveys, rebuild onboarding flows, ship new features, and change pricing.&lt;/p&gt;

&lt;p&gt;Meanwhile, a quieter kind of churn drains MRR every month. No cancellation email. No product feedback. No angry support ticket. Just a customer who disappears because their payment failed and nobody followed up.&lt;/p&gt;

&lt;p&gt;That is involuntary churn. It is one of the most fixable retention problems in SaaS because the customer did not choose to leave.&lt;/p&gt;

&lt;p&gt;This guide explains what involuntary churn is, how it differs from voluntary churn, how to measure it correctly, why Stripe payments fail, and the practical workflow that recovers revenue before a failed payment becomes a lost customer.&lt;/p&gt;

&lt;p&gt;If you want to estimate the size of the leak before reading, use the free &lt;a href="https://dev.to/benchmark"&gt;Stripe failed payment benchmark&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is involuntary churn?
&lt;/h2&gt;

&lt;p&gt;Involuntary churn happens when a customer loses access to your product because of a billing failure, not because they chose to cancel.&lt;/p&gt;

&lt;p&gt;Their card expired. Their bank blocked the transaction. They had a temporary cash flow issue. Stripe retried a few times, gave up, and the subscription lapsed.&lt;/p&gt;

&lt;p&gt;The customer did not decide your product was no longer worth paying for. They may not even know they churned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voluntary churn&lt;/strong&gt; = a customer actively decides to cancel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Involuntary churn&lt;/strong&gt; = a customer stops paying because the payment process failed.&lt;/p&gt;

&lt;p&gt;These are two different problems with two different fixes. Voluntary churn usually requires product, pricing, onboarding, or support work. Involuntary churn usually requires better payment visibility, smarter retry logic, clearer customer emails, and timely escalation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Involuntary churn vs delinquent churn
&lt;/h2&gt;

&lt;p&gt;The terms are often used together, but there is a useful distinction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delinquent customer&lt;/strong&gt;: the customer has a failed payment and is inside a recovery or dunning window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Involuntary churned customer&lt;/strong&gt;: the recovery window ended, payment was not collected, and the subscription was cancelled or access was removed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This distinction matters for reporting. If you mark someone as churned the moment their payment fails, you overstate churn and hide recoveries. A better view tracks failed payments, recovered payments, unresolved delinquency, and final involuntary churn separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  How common is involuntary churn?
&lt;/h2&gt;

&lt;p&gt;Many subscription businesses see failed payment rates in the low-to-mid single digits each month. The exact rate depends on customer mix, billing interval, geography, card age, invoice amount, and retry settings.&lt;/p&gt;

&lt;p&gt;The cost becomes real quickly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;MRR&lt;/th&gt;
&lt;th&gt;Estimated monthly failed payments at 5%&lt;/th&gt;
&lt;th&gt;Potentially recoverable at 60%&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$5,000&lt;/td&gt;
&lt;td&gt;$250&lt;/td&gt;
&lt;td&gt;$150&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$10,000&lt;/td&gt;
&lt;td&gt;$500&lt;/td&gt;
&lt;td&gt;$300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$25,000&lt;/td&gt;
&lt;td&gt;$1,250&lt;/td&gt;
&lt;td&gt;$750&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$50,000&lt;/td&gt;
&lt;td&gt;$2,500&lt;/td&gt;
&lt;td&gt;$1,500&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The tragedy is that much of this revenue is recoverable. A customer whose payment failed is often still an active user, still getting value, and still willing to pay if the recovery path is clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why most founders miss it
&lt;/h2&gt;

&lt;p&gt;There are three reasons involuntary churn stays invisible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. It looks like regular churn in the dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most dashboards show churned MRR. They do not always separate a customer who clicked Cancel from a customer whose card failed three times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The customer does not always reach out&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a customer chooses to cancel, they may leave feedback. When a payment fails, they may get a generic processor email, miss it, lose access, and assume something broke.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It feels like a product problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Founders are trained to treat churn as a product signal. But if engaged customers disappear after failed payments, shipping more features will not solve the leak.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5 signals that your churn is involuntary
&lt;/h2&gt;

&lt;p&gt;Look for these patterns:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Active users suddenly disappear&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a customer was using core features and then vanished without a cancellation flow, payment failure is a likely cause.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Churn clusters around billing dates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spikes on the same day each month often correspond to retry schedules or failed billing cohorts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No cancellation feedback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Customers who never touched the cancellation flow may not have chosen to leave.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. High win-back response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If churned customers say "I did not know my account was cancelled," you are seeing involuntary churn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Stripe shows failed invoices before cancellation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If subscription cancellations follow &lt;code&gt;invoice.payment_failed&lt;/code&gt; events, you have a measurable recovery problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is costing you
&lt;/h2&gt;

&lt;p&gt;Say you are at $20,000 MRR. If 5% of recurring payments fail in a month, that is $1,000 at risk. Without a recovery process, Stripe retries may collect some of it, but the rest can quietly turn into churn.&lt;/p&gt;

&lt;p&gt;Over a year, even a few hundred dollars of unrecovered MRR per month becomes thousands of dollars in preventable loss. The cost compounds through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct lost revenue&lt;/strong&gt; - money you earned but did not collect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CAC waste&lt;/strong&gt; - you paid to acquire customers who were still willing to pay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NRR drag&lt;/strong&gt; - failed-payment churn depresses retention even when the product is working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Founder distraction&lt;/strong&gt; - you chase "churn" causes that are actually billing failures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why payments fail
&lt;/h2&gt;

&lt;p&gt;Every failed payment falls into a practical recovery category. The email and retry strategy depends on the category.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure type&lt;/th&gt;
&lt;th&gt;Common Stripe signal&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;First response&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Expired card&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;expired_card&lt;/code&gt; or &lt;code&gt;card_expired&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The customer needs to update card details.&lt;/td&gt;
&lt;td&gt;Send an immediate update link.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Temporary funds issue&lt;/td&gt;
&lt;td&gt;&lt;code&gt;insufficient_funds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The card may work later.&lt;/td&gt;
&lt;td&gt;Wait and retry gently.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bank block&lt;/td&gt;
&lt;td&gt;&lt;code&gt;do_not_honor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The issuer blocked the charge.&lt;/td&gt;
&lt;td&gt;Explain and offer bank approval or another card.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic decline&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;generic_decline&lt;/code&gt; or &lt;code&gt;card_declined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The reason is unclear.&lt;/td&gt;
&lt;td&gt;Use conservative copy and clear options.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication required&lt;/td&gt;
&lt;td&gt;&lt;code&gt;authentication_required&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The bank needs confirmation.&lt;/td&gt;
&lt;td&gt;Send an authentication link.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard decline&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;lost_card&lt;/code&gt;, &lt;code&gt;stolen_card&lt;/code&gt;, &lt;code&gt;fraudulent&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The same card should not be retried aggressively.&lt;/td&gt;
&lt;td&gt;Ask for a different payment method.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the detailed code-by-code playbook, read the &lt;a href="https://dev.to/blog/stripe-failure-codes-the-complete-guide"&gt;Stripe failure codes guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to measure involuntary churn correctly
&lt;/h2&gt;

&lt;p&gt;Use this formula:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Involuntary churn rate = MRR lost to failed payments in period / MRR at start of period&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Avoid three common traps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not include voluntary cancellations.&lt;/li&gt;
&lt;li&gt;Do not double-count recovered invoices.&lt;/li&gt;
&lt;li&gt;Do not declare churn on day 0 if you still have a recovery window.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful companion metric is &lt;strong&gt;recovery rate&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recovery rate = recovered failed payment amount / total failed payment amount&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you run Stripe Billing, start with &lt;code&gt;invoice.payment_failed&lt;/code&gt;, &lt;code&gt;invoice.paid&lt;/code&gt;, subscription status changes, and cancellation reasons. Then group by customer, invoice, failed amount, recovered amount, and days to recovery.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to reduce involuntary churn
&lt;/h2&gt;

&lt;p&gt;Once you can see the leak, there are five levers.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Detect failed payments immediately
&lt;/h3&gt;

&lt;p&gt;Do not wait for someone to check Stripe manually. Push failed payments into a dashboard, Slack channel, or recovery queue. At minimum, track customer, invoice amount, failure code, next retry date, and account value.&lt;/p&gt;

&lt;p&gt;For the operating view, use the &lt;a href="https://dev.to/stripe-failed-payments"&gt;Stripe failed payments guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use failure-code-specific recovery
&lt;/h3&gt;

&lt;p&gt;The default "your payment failed" email flattens every situation into one message. That creates bad recovery timing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;expired_card&lt;/code&gt;: send an immediate update-link email.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;insufficient_funds&lt;/code&gt;: wait before escalating.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;do_not_honor&lt;/code&gt;: explain the bank block and give two options.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authentication_required&lt;/code&gt;: send an authentication link, not a generic billing link.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Time retries based on the failure
&lt;/h3&gt;

&lt;p&gt;Retry logic should match the cause. A network error may deserve a quiet retry soon. An expired card needs customer action. An insufficient-funds decline often performs better after a delay. A hard decline should not be hammered repeatedly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Make the customer action frictionless
&lt;/h3&gt;

&lt;p&gt;Every email should have one secure action link. Do not ask the customer to log in, find billing settings, and figure it out. Reduce the work to one obvious step.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Escalate valuable accounts personally
&lt;/h3&gt;

&lt;p&gt;For accounts that matter, do not rely only on automation. A short founder or support note before the last retry can recover revenue that generic dunning emails miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple recovery sequence
&lt;/h2&gt;

&lt;p&gt;Start with this baseline:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Day 0&lt;/td&gt;
&lt;td&gt;Detect failure and classify code&lt;/td&gt;
&lt;td&gt;Decide whether customer action is needed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 0-1&lt;/td&gt;
&lt;td&gt;Send first email if useful&lt;/td&gt;
&lt;td&gt;Immediate for expired cards and bank blocks, delayed for funds issues.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 3&lt;/td&gt;
&lt;td&gt;Retry or send reminder&lt;/td&gt;
&lt;td&gt;Match retry timing to the failure code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 7&lt;/td&gt;
&lt;td&gt;Final automated reminder&lt;/td&gt;
&lt;td&gt;Add a clear consequence, but keep the tone calm.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 10-14&lt;/td&gt;
&lt;td&gt;Manual escalation or pause access&lt;/td&gt;
&lt;td&gt;Escalate high-value accounts before giving up.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The numbers are not magic. The important part is that the sequence changes based on the failure reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools for recovering involuntary churn
&lt;/h2&gt;

&lt;p&gt;You have a few options depending on stage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manual workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Monitor failed invoices in Stripe, maintain a spreadsheet, and send emails manually. This works early if you only see a few failures per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe built-in tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stripe Smart Retries and billing emails are a good baseline. The limitation is that the customer communication is generic and the workflow can be hard to tune around failure codes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dedicated dunning tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dedicated recovery tools classify failures, send better emails, track recovery, and escalate valuable accounts. Dunlo is built for Stripe-first SaaS founders who want this workflow without enterprise setup.&lt;/p&gt;

&lt;p&gt;For the dunning sequence itself, see the &lt;a href="https://dev.to/stripe-dunning"&gt;Stripe dunning workflow&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  30-day action plan
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pull 90 days of failed invoice data from Stripe.&lt;/li&gt;
&lt;li&gt;Separate voluntary cancellations from failed-payment churn.&lt;/li&gt;
&lt;li&gt;Group your last 100 failed payments by failure code.&lt;/li&gt;
&lt;li&gt;Turn on Stripe's card account updater if you have not already.&lt;/li&gt;
&lt;li&gt;Rewrite your first three recovery emails by failure type.&lt;/li&gt;
&lt;li&gt;Add manual founder escalation for high-value accounts.&lt;/li&gt;
&lt;li&gt;Review recovery rate weekly until the leak is visible.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is involuntary churn the same as failed payment churn?
&lt;/h3&gt;

&lt;p&gt;They are closely related. Failed payment churn is the payment-specific cause. Involuntary churn is the retention outcome when failed payments are not recovered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does annual billing eliminate involuntary churn?
&lt;/h3&gt;

&lt;p&gt;No. It reduces the number of billing events, but each failed annual renewal is larger. Annual customers may also have older saved cards, so expired-card failures can still happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I retry failed payments forever?
&lt;/h3&gt;

&lt;p&gt;No. After a few well-timed retries over a recovery window, additional retries usually hurt more than they help. Move unresolved accounts to a clean win-back or manual follow-up path.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a healthy recovery rate?
&lt;/h3&gt;

&lt;p&gt;It depends on price point, geography, and customer type. The useful benchmark is your own trend: if recovery improves after you separate failure codes and rewrite emails, the workflow is working.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;Involuntary churn is the most fixable form of churn you have. The customers are not necessarily dissatisfied. They may still want the product. They just need the right payment recovery path at the right moment.&lt;/p&gt;

&lt;p&gt;Start by separating it from voluntary churn. Then classify failed payments, send code-aware emails, retry with intent, and escalate valuable accounts before they disappear.&lt;/p&gt;

&lt;p&gt;Want to see how much involuntary churn might be costing your Stripe account? &lt;a href="https://dunlo.io/benchmark" rel="noopener noreferrer"&gt;Run a free benchmark on Dunlo&lt;/a&gt; and estimate your failed payment rate, recovery rate, and recoverable revenue.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>stripe</category>
      <category>product</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stripe failure codes – the complete guide</title>
      <dc:creator>Mathieu Chambaud</dc:creator>
      <pubDate>Fri, 12 Jun 2026 13:22:26 +0000</pubDate>
      <link>https://dev.to/freki_managarm/stripe-failure-codes-the-complete-guide-10cb</link>
      <guid>https://dev.to/freki_managarm/stripe-failure-codes-the-complete-guide-10cb</guid>
      <description>&lt;h2&gt;
  
  
  What each Stripe failure code means and what to do about it
&lt;/h2&gt;

&lt;p&gt;When a Stripe payment fails, most SaaS founders send the same email to everyone.&lt;/p&gt;

&lt;p&gt;"Your payment failed. Please update your billing information."&lt;/p&gt;

&lt;p&gt;It's the wrong move — and it's costing you recoverable revenue every month.&lt;/p&gt;

&lt;p&gt;Every failed payment in Stripe comes with a reason code. That code tells you exactly what went wrong: whether the card expired, whether the bank blocked the charge, whether it was a temporary funds issue. Each situation calls for a completely different response, different timing, and different tone.&lt;/p&gt;

&lt;p&gt;This guide covers every Stripe failure code you're likely to encounter, what it means, and precisely what to do — so you can stop treating all failed payments the same way.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Stripe Failure Codes Work
&lt;/h2&gt;

&lt;p&gt;When a charge fails, Stripe returns two pieces of data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;decline_code&lt;/code&gt;&lt;/strong&gt; — the specific reason the card network or bank declined the charge (e.g., &lt;code&gt;card_expired&lt;/code&gt;, &lt;code&gt;insufficient_funds&lt;/code&gt;, &lt;code&gt;do_not_honor&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;failure_code&lt;/code&gt;&lt;/strong&gt; — a broader category code on the charge or PaymentIntent object&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For dunning purposes, &lt;code&gt;decline_code&lt;/code&gt; is what matters. It's the most granular signal you have about what actually went wrong.&lt;/p&gt;

&lt;p&gt;You can access it in two ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Via webhook (recommended):&lt;/strong&gt;&lt;br&gt;
Listen for &lt;code&gt;invoice.payment_failed&lt;/code&gt; events. The charge object inside the event contains &lt;code&gt;failure_code&lt;/code&gt; and &lt;code&gt;last_payment_error.decline_code&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"invoice.payment_failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"last_payment_error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"card_declined"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"decline_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insufficient_funds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your card has insufficient funds."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Via Stripe Dashboard:&lt;/strong&gt;&lt;br&gt;
Go to Payments → find the failed charge → look under "Failure reason" in the charge detail view.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 4 Failure Codes You'll See Most Often
&lt;/h2&gt;

&lt;p&gt;These four codes account for the vast majority of failed payments in SaaS billing. Get these right and you'll recover most of your involuntary churn.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. &lt;code&gt;card_expired&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The expiration date on the card has passed. The card number is still valid, the customer still has the account — they just haven't updated their card details with you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How common:&lt;/strong&gt; Very common. Cards typically expire every 2–3 years, and customers rarely update their details proactively. Expiry-related failures tend to cluster around January (post-holiday card refreshes) and throughout the year as individual cards hit their expiry dates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the customer needs to do:&lt;/strong&gt; Update to a new card. That's it. They almost certainly already have a replacement card from their bank.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The right recovery approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timing:&lt;/strong&gt; Send immediately — within an hour of the failure. The customer is likely at their desk, and this is an easy fix. Don't wait.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tone:&lt;/strong&gt; Friendly, zero pressure. Frame it as a quick admin task, not a billing crisis. "Happens to everyone" goes a long way here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; One clear call to action — a direct link to update their payment method. Don't ask them to log in, navigate to billing, and find the update button. Give them a one-click link.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subject line example:&lt;/strong&gt; &lt;code&gt;Quick note about your [Product] subscription, [Name]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Email template:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey [Name],&lt;/p&gt;

&lt;p&gt;The card we have on file for your [Product] subscription expired at the end of [month] — totally normal, happens to everyone.&lt;/p&gt;

&lt;p&gt;Here's a one-click link to update it: &lt;strong&gt;[Update payment method →]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Takes about 30 seconds. Once updated, your subscription continues without any interruption.&lt;/p&gt;

&lt;p&gt;Let me know if you run into any issues.&lt;/p&gt;

&lt;p&gt;[Your name]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What not to do:&lt;/strong&gt; Don't send an urgent, high-pressure email. The customer didn't do anything wrong — their card just expired. Treat it as a helpful nudge, not a warning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe Smart Retries effectiveness:&lt;/strong&gt; Low. The underlying issue (expiry) doesn't resolve itself, so retries will keep failing until the card is updated. Email outreach is essential here.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;code&gt;insufficient_funds&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The customer's account didn't have enough balance to cover the charge at the time of the attempt. The card itself works fine — it was just a bad moment to charge it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How common:&lt;/strong&gt; Very common, especially for consumer-facing and lower-price-point SaaS. Also spikes at end-of-month when billing cycles from other services have already hit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the customer needs to do:&lt;/strong&gt; Usually nothing. Wait for their account to replenish. The card will work again in a few days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The right recovery approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timing:&lt;/strong&gt; Do NOT send an email immediately. Wait 3 days before reaching out. Emailing someone the same day their card declined for insufficient funds piles on at the worst possible moment and can damage the relationship.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tone:&lt;/strong&gt; Calm, non-judgmental, no urgency. They know what happened. They don't need it spelled out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Let them know there was an issue with their payment, without making them feel bad about it. Offer a retry or a payment link — but don't make the email feel like a collections notice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subject line example:&lt;/strong&gt; &lt;code&gt;A quick note about your [Product] subscription&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Email template:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey [Name],&lt;/p&gt;

&lt;p&gt;Just a heads up — we had a small issue processing your [Product] subscription payment recently.&lt;/p&gt;

&lt;p&gt;It's likely just a timing thing. If you'd like to retry the payment now, you can do that here: &lt;strong&gt;[Retry payment →]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Otherwise, we'll try again automatically in a few days. No action needed if you'd prefer to wait.&lt;/p&gt;

&lt;p&gt;[Your name]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What not to do:&lt;/strong&gt; Don't send an urgent email the same day. Don't tell them their card "was declined for insufficient funds" — they know, and spelling it out is embarrassing. Don't suggest they update their payment method (their card works fine).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe Smart Retries effectiveness:&lt;/strong&gt; High. This is exactly the scenario Smart Retries is designed for — Stripe will wait and retry when the probability of success is higher. Enable Smart Retries and let it do its job before escalating to email.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;code&gt;do_not_honor&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The customer's bank rejected the transaction without giving a specific reason. This is one of the most frustrating codes for customers because it's vague — their card appears to work, and they may not understand why the charge failed.&lt;/p&gt;

&lt;p&gt;Common causes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The bank's fraud detection flagged the transaction (especially common for SaaS subscriptions billed from unfamiliar merchant names or foreign entities)&lt;/li&gt;
&lt;li&gt;The card has international transaction restrictions&lt;/li&gt;
&lt;li&gt;The bank has a temporary hold on the card&lt;/li&gt;
&lt;li&gt;A security freeze the customer may not be aware of&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How common:&lt;/strong&gt; Second most common decline code after &lt;code&gt;insufficient_funds&lt;/code&gt;. Particularly frequent for international customers or businesses with generic merchant names on statements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the customer needs to do:&lt;/strong&gt; Either call their bank to authorize the transaction, or use a different card.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The right recovery approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timing:&lt;/strong&gt; Send within a few hours. This is time-sensitive — the longer you wait, the more likely the customer assumes everything is fine or mentally moves on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tone:&lt;/strong&gt; Explanatory. The customer is likely confused. Your job is to explain what happened in plain language and give them two clear options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Two paths — call your bank, or use a different card. Don't give them one option; some customers can't or won't call their bank, and giving them an alternative increases recovery significantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subject line example:&lt;/strong&gt; &lt;code&gt;Issue with your [Product] payment — here's what happened&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Email template:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey [Name],&lt;/p&gt;

&lt;p&gt;We had an issue processing your [Product] subscription payment, and I wanted to explain what happened.&lt;/p&gt;

&lt;p&gt;Your bank blocked the transaction — this is pretty common with subscription billing and usually isn't caused by anything on your end. Banks occasionally flag recurring charges from unfamiliar merchant names as a precaution.&lt;/p&gt;

&lt;p&gt;You have two options to fix it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1:&lt;/strong&gt; Call the number on the back of your card and ask them to authorize recurring payments from [Your Company/Merchant Name]. Then click here to retry: &lt;strong&gt;[Retry payment →]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2:&lt;/strong&gt; Update to a different card: &lt;strong&gt;[Update payment method →]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Either works. Let me know if you have any questions — happy to help sort this out.&lt;/p&gt;

&lt;p&gt;[Your name]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What not to do:&lt;/strong&gt; Don't just send a generic "update your card" email. The card works — that's not the problem. Customers who try to update to the same card will see it fail again and give up entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe Smart Retries effectiveness:&lt;/strong&gt; Low to moderate. If the bank's fraud filter clears (which sometimes happens automatically), a retry may succeed. But in most cases, the customer needs to take action before the charge will go through.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. &lt;code&gt;card_declined&lt;/code&gt; (generic)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The card was declined, but Stripe didn't receive (or can't share) a more specific reason. This is the catch-all decline code — it covers situations where the bank declines without providing detailed information.&lt;/p&gt;

&lt;p&gt;Possible causes include: card restrictions, account issues, temporary bank holds, or decline policies that banks don't expose to merchants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How common:&lt;/strong&gt; Common, but less informative than the specific codes above. When you see this, you know something went wrong but not exactly what.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the customer needs to do:&lt;/strong&gt; Try a different card, or contact their bank to understand why it was declined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The right recovery approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timing:&lt;/strong&gt; Same day — within a few hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tone:&lt;/strong&gt; Helpful and low-pressure. You don't know exactly what happened, so don't pretend you do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Offer two paths (retry with a different card, or contact support) without creating urgency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subject line example:&lt;/strong&gt; &lt;code&gt;We had trouble processing your [Product] payment&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Email template:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey [Name],&lt;/p&gt;

&lt;p&gt;We had trouble processing your [Product] subscription payment. Unfortunately, we don't have more detail on the specific reason — these things happen occasionally.&lt;/p&gt;

&lt;p&gt;If you'd like to try a different card, you can update your payment method here: &lt;strong&gt;[Update payment method →]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or if you'd prefer to retry with the same card: &lt;strong&gt;[Retry payment →]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Either way, let me know if you need any help sorting this out.&lt;/p&gt;

&lt;p&gt;[Your name]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Stripe Smart Retries effectiveness:&lt;/strong&gt; Variable. Depends on the underlying reason. Smart Retries may succeed if it was a temporary bank issue; it won't succeed if the underlying issue persists.&lt;/p&gt;




&lt;h2&gt;
  
  
  Less Common But Important Failure Codes
&lt;/h2&gt;

&lt;p&gt;You'll see these less frequently, but knowing how to handle them prevents recoverable payments from slipping through.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;card_velocity_exceeded&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The customer exceeded the balance, credit limit, transaction amount limit, or card velocity limit available on their card. Some teams shorten this in notes as &lt;code&gt;card_velocity_exceed&lt;/code&gt;, but Stripe's decline code is &lt;code&gt;card_velocity_exceeded&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Wait at least 24 hours before attempting any retry. Do not email the customer urgently. A calm notification is appropriate, but the main action is on your side: pause retries, let the issuer limit clear, and ask the customer to approve the charge or use another card if the code repeats.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;fraudulent&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The bank has flagged this transaction as potentially fraudulent. In some cases, this may indicate a stolen or compromised card.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; This is one of the few codes where caution is warranted on your end. Don't retry aggressively. Send a single gentle email asking the customer to update their payment method, framed as a security precaution. If you receive multiple &lt;code&gt;fraudulent&lt;/code&gt; codes from the same customer account, consider flagging for manual review.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;lost_card&lt;/code&gt; / &lt;code&gt;stolen_card&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The card has been reported lost or stolen. The bank will not authorize any further charges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; The customer needs to provide a new card. They may not be aware their card was flagged as lost/stolen (bank fraud systems sometimes act before the customer reports it). Send a polite email asking them to update their payment method, without referencing "lost" or "stolen" — that can create unnecessary alarm.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;expired_card&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; Functionally identical to &lt;code&gt;card_expired&lt;/code&gt;. Handle the same way — immediate email, friendly tone, one-click update link.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;processing_error&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; A technical error occurred during processing — not a customer issue, not a card issue. Usually transient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Retry immediately (or let Smart Retries handle it). If the retry succeeds, no email needed. If it fails again with a different code, treat the new code as the primary issue.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;currency_not_supported&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The card doesn't support the currency you're charging in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Email the customer explaining that their current card doesn't support the billing currency, and ask them to update to a card that does. Include your billing currency in the email so they know what to look for.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference: Failure Code Action Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Decline code&lt;/th&gt;
&lt;th&gt;Email timing&lt;/th&gt;
&lt;th&gt;Tone&lt;/th&gt;
&lt;th&gt;Primary action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;card_expired&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Immediate&lt;/td&gt;
&lt;td&gt;Friendly, low pressure&lt;/td&gt;
&lt;td&gt;Update card link&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;insufficient_funds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;D+3&lt;/td&gt;
&lt;td&gt;Calm, no judgment&lt;/td&gt;
&lt;td&gt;Retry link, or wait&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;do_not_honor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Within hours&lt;/td&gt;
&lt;td&gt;Explanatory&lt;/td&gt;
&lt;td&gt;Call bank OR new card&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;card_declined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same day&lt;/td&gt;
&lt;td&gt;Helpful&lt;/td&gt;
&lt;td&gt;New card OR retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;card_velocity_exceeded&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;D+1&lt;/td&gt;
&lt;td&gt;Calm&lt;/td&gt;
&lt;td&gt;Pause retries 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fraudulent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same day&lt;/td&gt;
&lt;td&gt;Security-framed&lt;/td&gt;
&lt;td&gt;Update card&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;lost_card&lt;/code&gt; / &lt;code&gt;stolen_card&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Same day&lt;/td&gt;
&lt;td&gt;Neutral&lt;/td&gt;
&lt;td&gt;Update card (no alarm)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;processing_error&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only if retry fails&lt;/td&gt;
&lt;td&gt;Matter-of-fact&lt;/td&gt;
&lt;td&gt;Retry first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;currency_not_supported&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same day&lt;/td&gt;
&lt;td&gt;Informational&lt;/td&gt;
&lt;td&gt;Card that supports currency&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Implementing Failure-Code-Specific Dunning
&lt;/h2&gt;

&lt;p&gt;The most direct path to implementing this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Build it yourself&lt;/strong&gt;&lt;br&gt;
Listen for &lt;code&gt;invoice.payment_failed&lt;/code&gt; webhooks, parse the &lt;code&gt;last_payment_error.decline_code&lt;/code&gt; field, and trigger the appropriate email sequence via your email provider (Resend, Postmark, etc.). A day or two of development work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Use a dedicated tool&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dunlo.io" rel="noopener noreferrer"&gt;Dunlo&lt;/a&gt; handles this automatically — it reads the failure code from Stripe, routes to the right email sequence, handles timing, and flags high-value accounts for personal escalation. Free during beta.&lt;/p&gt;

&lt;p&gt;Either way, the principle is the same: the failure code is the most valuable signal you have. Use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Stripe tells you exactly why every payment failed. Most founders ignore that information and send the same generic email to everyone.&lt;/p&gt;

&lt;p&gt;The difference between a 20% recovery rate and a 70% recovery rate isn't marketing sophistication or technical complexity. It's reading the failure code and responding appropriately.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;card_expired&lt;/code&gt; → immediate, friendly, one-click link.&lt;br&gt;
&lt;code&gt;insufficient_funds&lt;/code&gt; → wait 3 days, calm email, no urgency.&lt;br&gt;
&lt;code&gt;do_not_honor&lt;/code&gt; → explain what happened, give two options.&lt;br&gt;
&lt;code&gt;card_declined&lt;/code&gt; → same day, helpful, low pressure.&lt;/p&gt;

&lt;p&gt;That's it. Four different responses to four different problems. Start there, and you'll recover most of what you're currently losing.&lt;/p&gt;




&lt;p&gt;Want this handled automatically? &lt;a href="https://dunlo.io" rel="noopener noreferrer"&gt;Dunlo&lt;/a&gt; connects to Stripe, reads every failure code, and sends the right email at the right time — without you having to think about it. Free during beta.&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://dunlo.io/blog/stripe-failure-codes" rel="noopener noreferrer"&gt;dunlo.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>stripe</category>
      <category>saas</category>
      <category>webdev</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
