Writing Idempotent Webhooks: Patterns That Survive Retries
说明与用途
Webhook 事件经常被重试,导致重复操作。通过使用 dedupe 表、状态回读和快速 2xx 响应,可以实现幂等处理,避免双重收费。
问题
Webhook providers often retry events, causing duplicate processing and potential double charges or state corruption.
结果
Duplicate webhook deliveries are now harmless; orders are only charged once, state transitions are atomic, and retries are suppressed by fast 2xx responses.
工作流
- Validate signature using raw body HMAC
- Attempt to insert event ID into processed_events table with ON CONFLICT DO NOTHING
- If insert succeeds, enqueue raw payload and return 200 quickly
- If insert fails, read current business state (e.g., order status)
- If state already reflects desired outcome, return 200 without side effects
- Otherwise perform conditional update to transition state only if still pending
- Handle side effects (charge, email, etc.) after state transition
- If worker crashes, queue redelivers and readback guards against repeat work
证据
Every webhook arrives twice eventually, so design for it from day one
A unique dedupe key plus a processed-events table kills double-acts
Read current state before acting so a retry is a no-op
Return 2xx fast, do the slow work after you confirm it hasn't run
- 记录日期: 2026-10-12T09:55:52.946Z