Webhook 与签名验证
创建 Webhook 后,事件以 POST 推送到你的回调地址。每个请求带签名头,接收方应验证签名后再处理。
1
创建订阅
POST /api/v1/webhooks,传入回调 URL 与关注的事件。建议带 Idempotency-Key 防重复创建。每个用户最多 5 个 Webhook。
2
轮换签名密钥
PATCH /api/v1/webhooks/{id}/secret 可轮换签名密钥;轮换有过渡期,旧签名短期内仍可验证,便于安全停机更新。
3
验证签名
用 Webhook 签名密钥对请求体计算 HMAC,与签名头比对;不一致应拒绝。也可调用公开的 /api/signing-keys/verify 交叉验证。
4
处理失败投递
GET /api/v1/webhooks/deliveries 查看每次投递的状态与响应码;POST …/deliveries/{id}/resend 手动重投。持续失败会自动退避。
事件类型
当前共 6 种事件。events 字段必须取自下表,写入未知值会返回 422 unknown_events 并回传允许列表。
| 事件 | 触发时机 |
|---|---|
| order.paid | 订单支付成功 |
| order.refunded | 订单发生退款 |
| subscription.expiring | 订阅即将到期(续费提醒窗口) |
| subscription.expired | 订阅已到期 |
| plugin.approved | 插件提交审核通过 |
| plugin.rejected | 插件提交被驳回 |
投递与重试策略
5最大尝试次数
10s单次投递超时
0/60/300/900/3600s逐次退避间隔(秒)
10连续失败达此数自动暂停
接收方守则
回调应在数秒内返回 2xx;长时间处理请先响应再异步执行。重复推送是正常的(at-least-once),请按事件 ID 去重。
签名与时间窗
签名头带时间戳,容忍窗口为 300 秒。窗口外的请求即便签名正确也应拒绝,这是重放攻击的第一道防线。