Appearance
Webhook 事件
日期: 2026-09-18
状态: 支付 Webhook v1 已发布
1. 已发布事件
| 事件 | 含义 |
|---|---|
payment.succeeded | 支付成功 |
payment.failed | 支付失败 |
payment.closed | 支付关闭 |
refund.succeeded | 退款成功 |
refund.failed | 退款失败 |
进件、分账、银行账单、清分和结算事件尚未纳入支付 Webhook v1。它们不会出现在商户工作台的订阅列表中,也不应据此开发生产逻辑。
商户在回调中心主动发起测试时,平台会发送 webhook.test 诊断事件。它只用于验证网络、验签和接收端响应,不表示任何支付或退款状态,也不会由真实业务流程自动产生。
2. 配置端点
端点在 SmartPay 商户工作台的“回调中心”中管理。创建时选择所属应用、填写名称和公网 HTTPS 地址,并勾选需要订阅的事件。平台会校验商户、租户、应用数据范围和操作权限;内网地址、非 HTTPS 地址以及越权应用会被拒绝。
创建成功后返回独立的 Webhook Secret,且只展示一次。该密钥与应用 API Secret 不同,必须分别保管。平台加密保存 Webhook Secret,不在后续列表和投递记录中返回明文。
商户业务系统不应直接调用 SmartPay 控制面的端点管理接口;请通过商户工作台完成配置和失败投递重放。
商户可在回调中心暂停或重新启用端点。暂停后运行时不会领取或发送该端点的待处理投递,既有投递记录不会删除;重新启用后,仍在有效重试窗口内的待处理投递可以继续执行。
具有回调管理权限的商户人员可以修改端点名称、公网 HTTPS 地址和订阅事件。编辑不会更换端点 ID、签名密钥、启停状态,也不会删除既有投递记录。平台会在保存时重新执行公网地址安全校验和事件白名单校验;绑定应用不可通过编辑操作迁移。
3. 请求结构
SmartPay 使用 POST 向已配置地址发送 JSON:
json
{
"eventId": "pay_01J...:payment.succeeded",
"eventType": "payment.succeeded",
"data": {
"eventType": "payment.succeeded",
"orderId": "pay_01J...",
"sessionId": "cs_01J...",
"outTradeNo": "ORDER_202609180001",
"amountFen": 12800,
"channelCode": "WECHAT",
"paidAt": "2026-09-18T08:30:00.000Z"
}
}退款事件的 data 包含 refundId、orderId、outRefundNo、amountFen 和 channelCode。字段应按事件类型解析,并允许未来增加可选字段。
4. 验签
每次通知包含以下请求头:
text
Content-Type: application/json
X-Webhook-Timestamp: 1789718400
X-Webhook-Signature: <64 位小写十六进制字符串>签名原文是时间戳、英文句点和未经重新序列化的原始请求体:
text
signedPayload = X-Webhook-Timestamp + "." + rawRequestBody
signature = hex(HMAC-SHA256(webhookSecret, signedPayload))接收方必须使用原始请求字节验签,并以恒定时间算法比较签名。验签失败时返回非 2xx,且不得更新业务状态。建议同时限制时间戳允许偏差,防止已签名请求被长期重放。
密钥轮换
商户工作台支持为单个端点生成新密钥,并设置 5—1440 分钟的延迟生效时间。新密钥只展示一次,必须立即保存到商户自己的密钥管理系统。
- 生效前,
X-Webhook-Signature仍使用当前密钥;同时发送X-Webhook-Next-Signature,它使用待生效的新密钥。接收方应验证附加签名,确认新密钥已经正确部署。 - 到达生效时间后,
X-Webhook-Signature自动改用新密钥,附加签名不再发送。 - 同一端点一次只能存在一项待生效轮换。轮换不会更改事件 ID,也不会绕过端点暂停、重试或应用权限边界。
5. 投递、重试与幂等
- 连接超时为 10 秒;任意 2xx 响应视为成功,其余响应或网络异常视为失败。
- 投递采用 at-least-once 语义,网络结果不确定时可能重复发送;同一业务事件的
eventId在自动重试期间保持不变。 - 首次失败后的重试间隔依次为:1 分钟、5 分钟、10 分钟、30 分钟、1 小时、2 小时、4 小时、8 小时、12 小时、16 小时、20 小时、24 小时。
- 累计尝试达到 12 次后进入死信状态,不再自动投递。具有回调管理权限的商户人员可在回调中心对失败或死信记录发起重放。
- 接收方必须以
eventId建立唯一约束或等价的幂等记录。建议先验签、落库并快速返回 2xx,再异步处理业务。 - 通知可能乱序到达;业务状态更新必须校验允许的状态迁移,不能仅按到达顺序覆盖。
6. 安全边界
- 仅配置由商户控制的公网 HTTPS 地址,不要把 Webhook Secret 写入 URL、前端代码或日志。
- SmartPay 会在创建和每次投递前执行公网地址安全校验,阻止向内网或不安全目标发送请求。
- 回调失败信息在商户工作台中只展示归一化错误码,不暴露平台内部网络信息。
- 端点暂停/启用、受控测试投递以及延迟生效的签名密钥轮换均已发布。