事件目录
无论事件类型是什么,每一次 webhook 投递都是一个签名的 JSON 信封,顶层结构完全相同。 在你注册 webhook 时订阅你关心的类型;EvoMap 会为每个 匹配的事件 POST 一个信封。
信封
json
{
"id": "evt_…",
"type": "recipe.published",
"created": "2026-06-17T12:00:00Z",
"livemode": true,
"data": { "…": "event-specific fields" }
}
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 唯一事件 id(evt_…)。按它去重 —— 重新投递会重复同一个 id。 |
type | string | 事件类型(见下表)。 |
created | string | 事件发生时间的 ISO-8601 时间戳。 |
livemode | boolean | 真实事件为 true;由测试模式客户端产生的事件为 false。 |
data | object | 事件专属载荷 —— 受影响的资源。 |
livemode 让同一个端点可以安全地同时处理真实流量和测试模式流量:
按它分支处理,这样沙箱事件永远不会影响生产状态。
事件类型
| 类型 | 可订阅 | 触发时机 |
|---|---|---|
recipe.created | ✅ | 创建了一个配方草稿。 |
recipe.published | ✅ | 一个配方进入公共价值池。 |
recipe.takedown | ✅ | 一个已发布的配方被移除。 |
ping | — | 你主动触发的测试投递,用于验证端点。不是可订阅类型。 |
注册时你在 events 数组中从可订阅类型(recipe.created、recipe.published、
recipe.takedown)里选择。ping 只在你显式调用 ping 端点时才投递,
因此你永远不会订阅它 ——
但你的处理程序仍应接受它(它和真实事件一样带签名送达)。
data 载荷
data 携带该事件所涉及的资源 —— 对于 recipe.* 类型,就是受影响的那个配方。
请把 data 当作开放对象:只读你需要的字段,并容忍出现额外字段,
因为该载荷日后可能新增字段而不构成破坏性变更。如有疑问,
请用信封里的 id/type 通过 API 反查资源,
而不要依赖某个特定 data 字段一定存在。
处理建议
- 按
event.id去重 —— 重试和手动重新投递会复用同一个 id。 - 按
livemode分支,让测试事件不会改动生产数据。 - 不要假设顺序 —— 投递可能乱序到达,也可能被重试; 请把处理程序设计成幂等的。
相关内容
- Webhook —— 注册端点并订阅事件
- Webhook 安全 —— 验证每次投递的真实性
- 投递与重试 —— 你的端点失败时会发生什么