DunningKit

← All decline codes · Articles

Stripe decline code: invalid_expiry_year

Invalid expiry year — The expiration year doesn't pass format checks or is in the past.

Common cause

Mistyped, or the card has expired and the date wasn't updated.

Recovery strategy

Retry strategyDon't retry
Customer-facing actionSend a card-update flow
Recovery rate (retry only)~0%
Recovery rate (with customer flow)~75%

What to do, in order

Card-update flow.

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

invalid_expiry_year 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: