Skip to content
功能特色定价方案合作伙伴博客帮助关于我们联系我们
免费开始登录
返回博客
guides2026-08-295 分钟阅读

Webhook幂等性:当Stripe将同一佣金事件触发三次

Stripe的at-least-once交付保证意味着生产中约0.3%的事件重复。thMenu的stripe_webhook_events claim模式如何处理重复——包括必须修复的竞态条件。

th

thMenu Team

thmenu.com

14个月间我们记录了thMenu上每个Stripe webhook: 100,000个事件中有312个以相同event_id到达两次或三次。这是Stripe "at-least-once delivery"承诺的具体数字——没有幂等性,佣金账本中就有三条重复记录。

为什么同一事件到达三次

如果Stripe在约10秒内没收到2xx响应,就重试。TCP超时、lambda冷启动、DNS瞬时故障,甚至成功处理后响应写入前连接断开——都会触发重试。Stripe在3天内以指数退避重试。

三个常见场景: Cloudflare Workers冷启动超过10秒,D1 batch事务已提交但连接断开,或在Stripe仪表板手动点击"resend"。

INSERT-Claim模式

thMenu的防御是stripe_webhook_events表,使用event_id PRIMARY KEY。第一个动作: INSERT。Unique约束错误23505 = 重复——200 OK no-op。

关键: claim必须先于业务逻辑,否则会有竞态条件。

竞态条件: 乱序事件

真实生产事件: customer.subscription.updatedcheckout.session.completed早到800ms。UPDATE影响0行。修复: 回滚claim,返回503,Stripe重试。

FAQ

签名验证应在claim之前还是之后?之前。Verify便宜,DB写入昂贵。

幂等表保留多久?Stripe保证30天重试;我们保留90天。

Stripe会永久重试吗?不会,最多3天。

觉得有用?分享给朋友。