## TL;DR

For "still has access in most setups; killing the account on the first failed renewal manufactures the churn you were trying to avoid. The other": if Stripe will retry soon on its own, your first email can be gentle: "we'll try again, or update your card now." 2. Email the customer with a link to update their payment method. If the customer updates the method, you can retry the invoice immediately via the API instead of waiting for the next automatic attempt.

```text
still has access in most setups; killing the account on the first failed renewal manufactures the churn you were trying to avoid. The other trap: ignoring
```

## When to use

You are seeing this: An invoice payment attempt failed: declined card, soft decline, or no payment method on file. Use this skill when you run into "Stripe event: invoice.payment_failed, start dunning, the subscription is not dead yet".

## When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

## Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

## invoice.payment_failed: run your dunning playbook

An invoice payment attempt failed: declined card, soft decline, or no payment method on file. The subscription is now `past_due`, not canceled. There is still time.

## What to do on receipt

1. Read `attempt_count` and `next_payment_attempt` on the invoice. If Stripe will retry soon on its own, your first email can be gentle: "we'll try again, or update your card now."
2. Email the customer with a link to update their payment method. Make it one click. Every extra step here costs you the subscription.
3. Track dunning state yourself: how many failures for this invoice, when the last reminder went out. Escalate the tone as attempts climb.
4. If the customer updates the method, you can retry the invoice immediately via the API instead of waiting for the next automatic attempt.
5. Return 200.

## The trap

Treating this as terminal and deprovisioning. `past_due` still has access in most setups; killing the account on the first failed renewal manufactures the churn you were trying to avoid. The other trap: ignoring `next_payment_attempt` and emailing "final notice" language before Stripe has even retried once.

## Checklist

- Smart Retries and your retry settings in the Dashboard decide the automatic schedule. Your handler should read `next_payment_attempt` rather than assuming a cadence.
- After the final failed attempt, the subscription moves to `canceled` or `unpaid` per your settings, and you get `customer.subscription.deleted`. That is when deprovisioning happens, not here.
