统一信封格式
V2 所有 Webhook 事件均使用相同的外层结构:
{
"event": "<事件名称>",
"timestamp": "2026-03-22T10:00:00+07:00",
"data": { }
}
与 V1 相比,V2 的主要区别在于:
- 统一结构: 所有事件类型均使用相同的
{ event, timestamp, data }外层信封,data字段中的内容与 V1 相同。 - 新增
timestamp字段: 每个事件均包含 ISO 8601 格式的时间戳。 - V1 与 V2 并行运行: V1 和 V2 Webhook 可同时独立配置。同一笔交易可同时触发
payment.completed(V1)和payment.v2.completed(V2)。
V2 事件列表
| 事件 | 触发条件 |
|---|---|
payment.v2.completed |
付款成功完成 |
disbursement.v2.completed |
出款成功完成 |
disbursement.v2.fail |
出款失败 |
disbursement.v2.expired |
出款过期 |
transaction_settlement.settled |
结算单状态变更为成功 |
Webhook 注册
Webhook 端点在客户接入过程中配置,或可稍后通过管理面板设置。每种事件类型需要单独的 Webhook 配置,包括:
- 基础 URL(例如:
https://yourdomain.com) - 路径(例如:
/api/webhooks/payment)
完整的 Webhook URL 构建方式为:{base_url}{path}
响应要求
Webhook 端点必须返回标准 HTTP 状态码:
- 200–299: 成功 — Webhook 已成功处理
- 4xx: 客户端错误 — 不会重试,但 408 和 429 除外(参见错误处理)
- 5xx: 服务器错误 — 系统会重试
⚠️ 响应时间必须在 5 秒以内,Webhook 系统有 5 秒的超时限制。
请求头
所有 V2 Webhook 请求都包含与 V1 相同的身份验证请求头:
| 请求头 | 描述 |
|---|---|
| X-PARTNER-ID | 您的客户端标识符 |
| X-TIMESTAMP | 请求时间戳,采用 ISO8601 格式 (e.g., 2024-12-18T16:21:07+07:00) |
| X-SIGNATURE | 用于请求验证的 RSA 签名(参见签名生成) |
幂等性
安全最佳实践
为确保 Webhook 请求的安全性与真实性,请遵循以下建议:
- 验证
X-SIGNATURE请求头以确认请求来源。 - 确认
X-PARTNER-ID是否与您的客户端 ID 一致。 - 验证
X-TIMESTAMP,防止重放攻击。 - 使用 HTTPS 协议的 Webhook 端点。
- 通过 事务 ID(transaction ID) 实现幂等性检查,防止重复处理。
错误处理
如果您的端点返回非 2xx 状态码或超时:
- 5xx 响应:会重试(最多 3 次,包含第一次尝试在内,重试间隔分别为 10 秒和 30 秒)
- 408(请求超时)和 429(请求过多):同样会重试,重试节奏与 5xx 相同
- 其他 4xx 响应:不会重试 — 请检查您的端点逻辑
- 超时(> 5 秒):视为失败并会重试。5 秒超时是按每次尝试单独计算的 — 每次重试都有独立的 5 秒窗口,并非 3 次尝试累计共用的总预算。
- 连接错误(连接被拒绝、DNS 解析失败、SSL 错误、主机不可达):同样视为失败并会重试,处理方式与上述情况相同。
请确保您的 Webhook 处理程序快速响应,并将耗时操作异步处理。
从 V1 迁移至 V2
V1 和 V2 可并行运行,无需立即迁移。如需迁移,请注意以下变化:
| 变更项 | V1 | V2 |
|---|---|---|
| 付款事件名称 | payment.completed |
payment.v2.completed |
| 出款事件名称 | disbursement.completed |
disbursement.v2.completed、disbursement.v2.fail、disbursement.v2.expired |
| 付款负载结构 | 字段直接位于根层级(扁平结构) | 字段嵌套在 data 中,外层增加 event 和 timestamp |
| 出款负载结构 | { event, data } 信封 |
{ event, timestamp, data } 信封(新增 timestamp) |
| 结算事件 | 不支持 | transaction_settlement.settled(V2 专属) |
V2 保留了 V1 的所有字段,名称和类型均不变(amount 在两个版本中均为字符串)。差异如下:
| V1 事件 | V2 事件 | V2 新增字段 |
|---|---|---|
payment.completed |
payment.v2.completed |
payment_channel、payment_at、service_fee_rate_str、service_fee_amount_str、nett_amount_str |
disbursement.completed |
disbursement.v2.completed(成功)、disbursement.v2.fail(失败)、disbursement.v2.expired(过期) |
valid_account_name、reason、payment_at |
V2 以后可能会新增字段;各 V2 事件页面列出其当前字段。