跳转到正文Skip to content

接收 Webhook

平台发送只包含必要元数据的出站事件。签名规则如下:

项目
X-Signature小写十六进制 HMAC-SHA256
签名字节${X-Webhook-Timestamp}.${原始请求体} 的 UTF-8 字节
X-Webhook-TimestampUnix 秒
X-Webhook-Event-Id稳定 UUID 幂等键
X-Webhook-SequenceAppClient 范围内单调递增的正整数

必须按此顺序处理

  1. 在大小限制内读取原始请求字节,不要先解析 JSON。
  2. 校验必需请求头与时间窗口;官方 SDK 默认允许 300 秒时钟偏差。
  3. 从 Secret Manager 读取签名 secret,对精确字节计算 HMAC-SHA256,并用恒定时间比较。
  4. 签名成功后才解析 JSON,并确认正文 event_id 与请求头一致。
  5. 在产生业务效果前,用持久存储原子认领事件 ID。重复事件返回 2xx,不重复执行效果。
  6. 在 10 秒内完成安全工作或入队并返回 2xx。
ts
const event = await verifier.verify(request.headers, rawBody)
await enqueueSafeEffect(event.event_id, event.type)
return new Response(null, { status: 204 })

TypeScript SDK 的内存重放存储只适合本地测试;生产环境必须实现持久且原子的 claim(eventID)。轮换期间只在明确的到期时间前接受上一把 secret。

非 2xx、连接失败与超时会触发指数退避重试,最长 24 小时;重放会保留原事件 ID 与序列号。不要在错误响应、日志、队列或崩溃报告中复制 secret、签名或完整事件正文。