Only a failed charge starts dunning, and Stripe must agree before dunning acts

FixBillingService
Shipped
September 10, 2026 at 8:27 PM UTC
Author
Kamo
Commit
c2792d7

invoice.finalized carries status=open with an amount due for every auto-charged invoice before the charge is attempted, and the invoice handler started the delinquency clock, and sent the payment-failed letter, on that status alone for any invoice event type. The clock now starts only on invoice.payment_failed. Stripe does not deliver in order. A snapshot that would move an invoice out of paid or void is older than the recorded state, so it is ignored rather than reopening the invoice or starting dunning on a paid one. customer.subscription.* reporting ACTIVE or TRIALING clears a clock still running, so a lost invoice.paid cannot leave a stale stamp for the next genuine failure to inherit (payment_failed only stamps the first). DunningSweep acts only on PAST_DUE or UNPAID subscriptions, and before the irreversible cancellation it re-reads the status from Stripe and holds unless Stripe reports past_due or unpaid.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing