Webhook 参考
概述
注册一个 HTTPS 端点,让 Elim 在订单或其支付状态发生变化时主动回调你的系统,无需轮询查询状态。本页说明事件类型、管理端点、载荷结构、签名校验和重试策略。
关于 Webhook 在订单生命周期中的位置,参见订单指南和订单 API 参考。
所有端点均需 JWT 认证(Authorization: Bearer <token>)或 API 密钥(x-api-key)。
事件
| 事件 | 触发时机 |
|---|---|
order.updated | 订单 status 变化:平台同步、定时同步或取消订单 |
payment.updated | payment_status 变化:发起支付请求、撤回请求、审批通过、驳回、平台支付成功/失败或退款 |
只会收到已订阅的事件,通常两个都订阅。
订阅管理端点
前缀 /v1/webhooks。
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/webhooks | GET | 列出现有订阅 |
/v1/webhooks | POST | 创建订阅——仅返回一次 secret |
/v1/webhooks/:id | PATCH | 修改 url、events 或 is_active |
/v1/webhooks/:id | DELETE | 删除订阅 |
/v1/webhooks/:id/rotate-secret | POST | 轮换 secret——仅返回一次新值 |
/v1/webhooks/:id/deliveries | GET | 最近的投递日志 |
/v1/webhooks/:id/test | POST | 向已注册的 url 发送一次测试投递 |
创建请求体
{
"url": "https://your-system.example/webhooks/elim",
"events": ["order.updated", "payment.updated"],
"is_active": true
}
secret 仅在创建或 rotate-secret 之后立即返回。请妥善保存——校验每个请求都需要它。若丢失 secret,调用 rotate-secret 重新签发(旧签名随即失效)。
载荷结构
两个事件共用同一结构,仅 event 字段不同:
{
"id": "evt_4a1f2c...",
"event": "payment.updated",
"created_at": "2026-06-19T00:00:00.000Z",
"data": {
"order": {
"id": "ORD0000000123",
"platform": "taobao",
"order_id": "123456789",
"status": "paid",
"payment_status": "paid",
"platform_payment_status": "success",
"total_amount_cny": 123.45,
"updated_at": "2026-06-19T00:00:00.000Z"
}
}
}
| 字段 | 说明 |
|---|---|
id | 事件 id,形如 evt_...——用于去重 |
event | order.updated 或 payment.updated |
created_at | 事件生成时间(ISO 8601) |
data.order.id | 内部订单号 ORD...——在你系统中查订单的键 |
data.order.order_id | 平台订单号(若平台尚未创建则为 null) |
data.order.status | 平台状态——见 status 表 |
data.order.payment_status | Elim 支付状态——见 payment_status 表 |
data.order.platform_payment_status | 平台侧支付结果 |
data.order.total_amount_cny | 订单金额(CNY),可能为 null |
data.order.updated_at | 订单最近更新时间(ISO 8601) |
处理逻辑:用 data.order.id 查订单,更新系统中的订单状态,然后返回 HTTP 2xx。载荷可能乱序到达——始终以较新的 updated_at 为准,忽略比当前状态更旧的事件。
每次投递的请求头
| 请求头 | 值 |
|---|---|
Content-Type | application/json |
User-Agent | elim-api-webhooks/1.0 |
X-Elim-Event | 事件名 |
X-Elim-Delivery | 投递 id(每次重试都会变) |
X-Elim-Timestamp | Unix 时间戳,单位秒 |
X-Elim-Signature | sha256=<hmac> |
签名校验
签名串:"{X-Elim-Timestamp}.{原始JSON请求体}"——使用收到的原始请求体,不要解析后再序列化。
算法:HMAC-SHA256(secret, 签名串),与 X-Elim-Signature 中 sha256= 之后的部分做定时安全比较。
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyElimWebhook(
secret: string,
timestamp: string,
rawBody: string,
signature: string,
): boolean {
const expected = `sha256=${createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')}`;
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
拒绝 X-Elim-Timestamp 与当前时间偏差过大(例如超过 5 分钟)的请求,以降低重放风险。
重试策略
| 条件 | 结果 |
|---|---|
2xx 响应 | 标记为投递成功 |
超时 / 网络错误 / 非 2xx | 安排重试 |
| 总尝试次数 | 3 |
| 各次间隔 | 60 秒,然后 300 秒 |
| 单次请求超时 | 10 秒 |
在 GET /v1/webhooks/:id/deliveries 查看每次投递结果。用 POST /v1/webhooks/:id/test 快速验证接收配置。
安全
- 生产环境 URL 必须为 HTTPS。开发环境可用
localhost。 - 生产环境屏蔽内网 / 私有 / 元数据 IP。
secret仅在创建或rotate-secret之后显示。- 载荷不包含密码、API 密钥、JWT 或平台访问令牌。
尚未配置 Webhook 时
随时用 GET /v1/orders/:id 直接查询状态——每次调用 Elim 都会先从平台同步最新状态再返回。参见订单 API 参考。