Incorrect CVC — The CVC code didn't match what the issuer has on file.
Cardholder mistyped, or the card has been replaced and the new CVC wasn't updated.
| Retry strategy | Don't retry |
|---|---|
| Customer-facing action | Send a card-update flow |
| Recovery rate (retry only) | ~5% |
| Recovery rate (with customer flow) | ~70% |
Don't retry without new input — the CVC won't change between retries. Email the customer to re-enter their card details (which usually means a card-update flow).
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
incorrect_cvc 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.