Stripe Webhooks Payment Declined
Stripe webhook events for payment declines in 2026 come in two varieties: synchronous declines (the PaymentIntent fails immediately with a `payment_intent.payment_failed` event) and asynchronous declines (for bank debits and delayed payment methods, the decline arrives hours or days later via webhook). Your integration needs to handle both.
Why This Happens
- Configuration gaps between tools or services
- Missing integrations or manual workarounds that weren't designed to scale
- Changes in vendor behavior, pricing, or API that weren't communicated clearly
What To Check First
- Verify your current setup matches the vendor's latest documentation
- Look for recent changes — platform updates, new team members, configuration drift
- Check if the problem is consistent or intermittent (different root causes, different fixes)
When To Escalate
- The problem is costing you money or customers per week
- You've spent more than 2 hours on it without progress
- A vendor quoted you more than $500 and you're not sure if it's necessary
Dealing with this right now?
The events to handle for declined payments: `payment_intent.payment_failed` (fires for card declines — the `last_payment_error` on the PaymentIntent has the decline code), `charge.failed` (fires alongside payment_intent.payment_failed with more detail), and `invoice.payment_failed` (for subscription renewals that failed). For each failed payment, your webhook handler should: update the payment status in your database, send the customer a notification with a link to retry or update their payment method, and for subscriptions, trigger your dunning flow.