api
webhook_reliability
ai_generated
true
Stripe webhook event received multiple times despite 200 response
ID: api/stripe-webhook-duplicate-delivery
88%Fix Rate
90%Confidence
3Evidence
2023-01-01First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| any | active | — | — | — |
Root Cause
Stripe retries webhooks if your endpoint takes >5s to respond 200, even if it eventually succeeds. Docs say 'up to 3 days' but don't clarify the 5s window clearly.
genericWorkarounds
-
95% success Return 200 immediately, then process asynchronously via queue
Receive webhook -> store raw event in DB/queue -> return 200 -> process from queue
-
92% success Implement idempotency using event.id as dedup key
if Event.objects.filter(stripe_event_id=event['id']).exists(): return 200
-
85% success Use Stripe's event retrieval API to verify event authenticity instead of trusting payload
event = stripe.Event.retrieve(event_id) # re-fetch from Stripe API
Dead Ends
Common approaches that don't work:
-
Return 200 after processing the event fully
85% fail
If processing takes >5s, Stripe assumes failure and retries. You get duplicate events with same event ID.
-
Rely on Stripe's 'at-most-once' delivery assumption
90% fail
Stripe explicitly guarantees 'at-least-once' delivery. Duplicates are expected behavior, not a bug.