WEBHOOK
Webhook 确认接收
了解如何正确返回确认响应、翠鸟的重试策略,以及投递失败时的处理方式
如何确认接收
翠鸟通过您的端点返回的 HTTP 状态码判断投递是否成功。确认规则如下:
| 响应状态码 | 翠鸟的处理 |
|---|---|
200 - 299 | 投递成功,标记为已确认,不再重试 |
3xx 重定向 | 不跟随重定向,视为失败,触发重试 |
4xx(除 429 外) | 客户端错误,不重试(如 400、401、404) |
429 限速 | 触发重试,遵守 Retry-After Header |
5xx 服务器错误 | 触发重试,按退避策略 |
| 连接超时(>5秒无响应) | 视为失败,触发重试 |
请务必在收到请求后 5秒内 返回响应。不要在返回响应前执行耗时操作(如数据库查询、外部 API 调用)。应立即返回 200,将业务逻辑推入异步队列。
最简确认响应
// 任意格式的 2xx 响应均视为成功
HTTP/1.1 200 OK
Content-Type: application/json
{"received": true}
重试策略
当投递失败时(5xx 或超时),翠鸟按以下时间表自动重试,共重试 5次:
第1次重试 — 首次失败后 1 分钟
短暂等待,处理瞬时网络抖动
第2次重试 — 首次失败后 5 分钟
给服务器更多恢复时间
第3次重试 — 首次失败后 30 分钟
覆盖较长时间的服务中断
第4次重试 — 首次失败后 2 小时
覆盖小时级故障恢复
第5次重试 — 首次失败后 12 小时
最后一次尝试,此后标记为永久失败
每次重试的请求体与原始请求完全相同,X-Cuiniao-Timestamp Header 保持原始时间戳不变(注意签名验证时不要严格校验时间戳的时效性,或者在重试检测场景下放宽时间窗口)。
投递失败处理
若所有重试均失败,该条 Webhook 事件将被标记为「投递失败」。您可以:
- 控制台查看:在「开发者 — Webhook — 投递记录」中查看所有失败事件
- 手动重试:点击失败记录旁的「重试」按钮,手动触发一次新的投递
- API 触发重试:
POST /v1/webhooks/deliveries/{delivery_id}/retry - 批量重试:通过控制台或 API 对指定时间段内的失败事件批量重新投递
# 通过 API 手动触发重试
curl -X POST https://api.cuiniao.com/v1/webhooks/deliveries/del_8vYp3nQs/retry \
-H "Authorization: Bearer ck_live_xxxxxxxxxxxx"
若端点连续失败超过 72小时,翠鸟将自动将该端点状态标记为「已暂停」,并向账号管理员发送告警邮件。需在控制台手动重新激活端点后,才会恢复正常投递。
幂等处理建议
由于重试机制,同一事件可能被多次投递。强烈建议在业务处理层实现幂等逻辑,防止重复执行。
- 将已处理的事件 ID(
event.id)存入 Redis 或数据库,设置 24 小时 TTL - 处理前先查询 ID 是否已存在,若已处理则直接返回 200
- 对于线索创建等写操作,在数据库层设置事件 ID 唯一索引,防止重复写入
// Java 幂等检查示例
String eventId = event.getId();
// 尝试将 eventId 插入去重表(唯一约束)
try {
eventDeduplicationRepo.insert(eventId);
} catch (DuplicateKeyException e) {
// 已处理过该事件,直接返回成功
return ResponseEntity.ok().build();
}
// 执行业务逻辑...