DunningKit

← All decline codes · Articles

Stripe decline code: insufficient_funds

Insufficient funds — The card had a balance below the charge amount when the transaction was attempted.

Common cause

The cardholder's account is overdrawn or near limit. Especially common on debit cards.

Recovery strategy

Retry strategyRetry up to twice
Customer-facing actionNo customer action needed
Recovery rate (retry only)~70%
Recovery rate (with customer flow)~75%

What to do, in order

Retry at +24h and +72h. Most recoveries happen on the first retry. Don't email the customer until after the second retry fails — most teams' recoveries here are silent.

Code example

The recommended Stripe Customer Portal session for the recovery flow:

session = stripe.billing_portal.Session.create(
    customer=customer_id,
    return_url="https://yourapp.com/billing/thanks",
    flow_data={"type": "payment_method_update"},
)
update_link = session.url

Where this fits in the bigger picture

insufficient_funds is one of dozens of decline codes Stripe returns; recovery rates vary by code by 5x or more. The recovery-rate reference covers the full set; the card-update flow article covers the customer-facing side; dunning emails covers how to write the messages.

DunningKit's open-source CLI parses your Stripe failed-charges CSV and gives you the breakdown by code, with recoverable-revenue estimates. pip install dunningkit.

Notify me when v0.1 ships: