用 Webhook 接收日常变化,保留状态检查来确认本地记录与面板一致。如果还没有可靠的公共接收端,可以先使用批量轮询。
应用重启时订单可能已经完成;接收确认丢失后,同一事件也可能到达两次。订单跟踪需要处理这两种情况,避免显示旧信息或重复应用更新。
为每种方式分配明确任务
- 轮询:查询当前状态
- action=status 返回查询时的状态,每次最多可合并 100 个订单 ID。间隔越短,请求越多,即使订单没有变化也一样。
- Webhook:接收所选变化
- NotPanel 将事件发送到已注册的 HTTPS 地址。这不占用客户端的 status 请求额度,但接收端仍需容量和监控。
- 核对:补全缺失信息
- 服务中断后或记录过旧时,查询相关订单。事件可能遗漏,重试次数有限,到达时间也没有保证。
NotPanel API 实际发送什么
本文适用于通过 webhook.add 注册的端点:公共 HTTPS URL 及受支持事件,如 order.processing、order.in_progress、order.completed、order.partial、order.refunded 和 order.refill_completed。妥善保存返回的 secret;webhook.list 不会再次提供它。用 webhook.list 检查状态及失败,用 webhook.remove 删除注册。
API 投递包含 events 数组,即使只有一个事件。每项具有 id、event、timestamp 和 data;外层 deliveryId 标识投递。下方为简化示例,并非真实订单;其中旧时间不能用于验证时效窗口。
{
"events": [
{
"id": "EXAMPLE_EVENT_ID",
"event": "order.completed",
"timestamp": 1700000000,
"data": { "order": 7001, "status_key": "completed" }
}
],
"timestamp": 1700000001,
"deliveryId": "EXAMPLE_DELIVERY_ID"
}从已验证的正文读取事件名,API 批次不要求 X-Webhook-Event。Dashboard 创建的 Webhook 使用不同的单事件格式,不要将两种格式混用。
验证原始请求体上的签名并检查时间戳。
保存已验证的投递后,再返回 2xx 响应。
每个事件只应用一次,并通过状态查询恢复遗漏信息。
安全地接收事件
- 保留原始正文。使用 secret 和 X-Webhook-Timestamp 验证 X-Webhook-Signature,并执行自己设定的时间容差。重新构造正文可能改变已签名的字节。
- 将 X-Webhook-Delivery-Id 与已验证正文中的 deliveryId 比对。先可靠保存再返回 2xx;无法安全接收时,应让发送方重试。
- 每个 events[].id 仅处理一次。去重记录应能在重启后保留,并与订单更新协调完成。同一事件可能经多个端点到达。
- 较慢的工作放在接收后完成。签名证明真实性,不证明到达顺序。延迟事件若与较新状态冲突,应先查询 status,而不是直接覆盖。
接收端不可用时会发生什么
超时或非 2xx 响应计为失败。NotPanel 延长间隔重试,API 端点连续失败 10 次后会暂停;成功投递会清零失败计数。检查 webhook.list:没有收到通知,不代表没有变化。
定期核对未解决或过旧的订单,每批最多 100 个 ID,并遵守响应头与账户限额。修复暂停的接收端后,确认注册处于 active 状态。不要假设所有历史失败投递都会自动重发。
测试成功演示以外的情况
使用模拟消息和自己生成的测试 secret,无需客户真实订单。
- 同一投递发送两次,应只产生一次更新。
- 同一事件进入两个批次,再重启接收端,不应重复更新。
- 修改一个字节或使用旧时间,应按自己的验证策略失败。
- 发生中断并收到延迟事件后,status 应恢复当前订单视图。
选择需要的事件、验证 secret 并及时确认,也见于 GitHub 的 Webhook 建议. 本文的请求头、正文格式和重试限制遵循 NotPanel 的约定。
常见问题
可以只使用轮询吗?
可以。批量查询并按订单量及限额安排间隔。创建和跟踪订单并不强制要求 Webhook。
Webhook 会立即且只到达一次吗?
不会保证。投递可能延迟或重复。验证每次投递,每个事件仅处理一次,并保留状态核对作为恢复方式。
应该检查哪些请求头?
检查 X-Webhook-Signature 和 X-Webhook-Timestamp,再将 X-Webhook-Delivery-Id 与已验证正文中的 deliveryId 比对,处理其中的 events 数组。
Webhook 能保护结果未知的 add 吗?
这是不同问题。重试 add 时保留原 request_id 和相同参数,然后保存找回的订单 ID。
参考资料: Webhook 约定 · 订单状态 · 超时恢复.



