Open-source toolkit for analyzing and recovering failed Stripe payments.
A pragmatic toolkit for B2B SaaS teams who want to recover the ~50–70% of failed Stripe charges that Smart Retries doesn't catch. Reads your Stripe failed-charge data, surfaces the recoverable portion by decline code, and generates the retry sequences + customer-facing flows that actually convert.
Status: v0.0.1 (CSV analysis + recovery-rate library). Live Stripe API integration and hosted recovery dashboard ship in summer 2026. Public landing at https://dunningkit.quantcalc.app.
Stripe Smart Retries is good but limited. It picks decent retry timing for insufficient_funds and a handful of common decline codes, but it doesn't:
- Email your customer when their card expires (the single largest recovery lever)
- Handle the long-tail decline codes (
do_not_honor,card_velocity_exceeded,authentication_required) well - Give you visibility into what's recoverable vs already lost
The middle ground between "Stripe defaults" and a $99–$299/month recovery service has been thin for a while. DunningKit is the open-source layer that fills it.
pip install dunningkitExport your failed charges from Stripe Dashboard → Payments → filter by Status: Failed → Export to CSV.
$ dunningkit analyze stripe-failed-charges.csv
Period: 2026-04-01 to 2026-04-30
Failed charges: 142 totalling USD 14,820.00
Decline-code breakdown (sorted by frequency):
insufficient_funds 38 USD 3,940.00 ~ USD 2,955.00 recoverable
expired_card 31 USD 3,210.00 ~ USD 2,728.50 recoverable
do_not_honor 22 USD 2,290.00 ~ USD 1,145.00 recoverable
generic_decline 18 USD 1,870.00 ~ USD 748.00 recoverable
...
Recovery summary:
Retries only ~ USD 5,520.00 (37% of total)
+ Customer flows ~ USD 8,420.00 (57% of total)
Customer flows add ~USD 2,900.00 of recovery on top of retries alone.
This is the dunning opportunity Stripe Smart Retries doesn't capture.For machine-readable output:
dunningkit analyze --json stripe-failed-charges.csv- CSV analyzer that reads Stripe Dashboard exports and reports the recoverable portion of failed charges, broken down by decline code.
- Recovery-rate library with aggregate estimates per decline code (
insufficient_fundsrecovers ~70% on retries;expired_cardrecovers ~5% on retries but ~85% with a card-update flow; etc.). - Pure stdlib — no runtime dependencies. Python 3.11+. Works offline; doesn't connect to Stripe or any other service.
- Live Stripe API connection (read failed charges directly without CSV exports)
- Per-code retry sequence executor
- Customer-facing card-update flow generator (Stripe Customer Portal session creation)
- Email/SMS template library with brand variables
- Recovery-attribution dashboard (what we recovered vs what Stripe Smart Retries got)
Apache-2.0. See LICENSE.
The CLI and recovery-rate library are open source. The hosted recovery dashboard, live Stripe integration, automated retry sequences, and team workflow features are commercial.
- What Stripe Smart Retries actually does (and what it doesn't)
- Failed-payment recovery rates by Stripe decline code
- Dunning emails for B2B SaaS: timing, tone, anti-patterns
- Card-update flows that actually convert
- Annual subscriptions and failed payments — the harder game
Issues and PRs are welcome; please file an issue before sending a substantial PR so we can align on direction.