Failed Payment Recovery (Dunning)
The systematic process of recovering failed subscription payments through automated retries, customer communications, and graceful degradation before eventually canceling the subscription.
Description
Dunning is the process of communicating with customers to collect overdue payments, and in SaaS it specifically refers to the automated workflows triggered when a subscription payment fails. Failed payments are one of the largest sources of involuntary churn, often accounting for 20-40% of total churn. An effective dunning flow combines Stripe's automatic payment retries with your own customer communication sequence, in-app notifications, and a graduated access reduction strategy that motivates the customer to fix their payment method without destroying the relationship.
A typical dunning sequence might look like: Day 0 (payment fails) - send an email explaining the payment failed with a direct link to update their card, show an in-app banner; Day 3 (first retry fails) - send a more urgent email, restrict access to premium features; Day 5 (second retry fails) - send a warning that the account will be downgraded, show a blocking modal on login; Day 7 (final retry fails) - downgrade to a free plan or pause the subscription, send a final email with a re-activation link. Each step should be configurable and A/B testable.
The implementation involves a dunning state machine that tracks the current dunning stage, listens for invoice.payment_failed and invoice.paid webhook events, and triggers the appropriate actions. When a payment eventually succeeds (customer updates their card, retry succeeds), the dunning flow should immediately reset: remove banners, restore access, and send a confirmation email. Store dunning history for analytics to identify patterns (which card types fail most, which day of month has highest failure rates, which email template has the best recovery rate).
Prompt Snippet
Build a dunning state machine with states [active, grace_period, restricted, suspended, canceled] driven by invoice.payment_failed and invoice.paid webhook events. On first failure, set a grace_period_ends_at timestamp 7 days out and trigger an automated email sequence via your transactional email provider (SendGrid/Postmark) with a tokenized URL linking directly to stripe.billingPortal.sessions.create() for card update. Implement graduated feature gating by checking the dunning state in your authorization middleware: grace_period allows full access, restricted blocks new resource creation, suspended shows a full-screen payment recovery modal. Track recovery rates by dunning stage in your analytics (recovered_at_stage_1, recovered_at_stage_2, churned) to optimize email timing and copy.
Tags
Related Terms
Payment Retry Logic
Configuring automatic reattempts of failed subscription payments with strategic timing, escalating notifications, and eventual fallback actions when all retries are exhausted.
Subscription Billing (Stripe)
Managing recurring payment cycles using Stripe's Subscription and Price APIs, including plan creation, billing intervals, upgrades/downgrades, and lifecycle event handling.
Customer Portal
A Stripe-hosted or custom-built self-service interface where customers can manage their subscriptions, update payment methods, view invoices, and handle billing-related actions without contacting support.
Payment Webhook Event Handling
Processing asynchronous payment lifecycle events delivered via webhooks, including idempotent handling, event routing, retry logic, and maintaining consistency between Stripe and your application state.