在与 Subotiz 系统集成时,商户可通过配置 Webhook 通知端点,实时接收账户关联事件,以便后端系统触发对应的业务逻辑处理(如支付状态更新、订阅状态变更等)。
通知原理:
当 Subotiz 系统触发特定事件时,将向配置的 Webhook 通知端点发送 HTTPS POST 请求。请求包含以下关键要素:
- 请求负载:符合 JSON 格式规范的结构化事件对象,包含事件标识、类型及具体业务数据;
- 请求头信息:包含用于鉴权与请求标识的特定头部(如 X-Timestamp 时间戳、X-Signature 签名等);
请求组成
请求头部
| Header 名 | 示例值 | 说明 |
|---|---|---|
| X-Timestamp | 1525872629832 | 参与签名计算的毫秒时间戳 |
| Content-Type | application/json | |
| X-Access-No | 100001 | 接入方唯一号access_no |
| X-Signature | 54ea681fed566566c778a9aa1608589cfb34e235c4f326709d20cc00c132bb7b | 签名字符串. |
请求体结构
| 属性 | 类型 | 描述 | 示例 |
|---|---|---|---|
| id | uint64 | 事件 id | 545440011265267736 |
| type | string | 事件类型 | payment.success |
| created | string | 创建时间 | 2025-07-01T10:25:25Z |
| data | object | 具体事件的业务对象,事件类型不同会有不同的数据结构 |
事件处理规范
可靠性验证
接收事件前需通过以下步骤验证请求合法性:
-
提取参数:从请求头获取 X-Timestamp 时间戳(记为
timestamp),并获取原始请求体内容(记为body); -
构造签名原串:格式为
${timestamp}.${body}; -
计算签名:使用 Subotiz 分配的
API Key作为密钥,通过 HMAC-SHA256 算法计算签名值;-
示例代码: GO
-
// 计算签名 func CalcSignature(timestamp int64, body []byte, secret string) string { mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(fmt.Sprintf("%d", timestamp))) mac.Write([]byte(".")) mac.Write(body) return hex.EncodeToString(mac.Sum(nil)) }
-
-
比对验证:将计算得到的签名与请求头中的 X-Signature 值比对,一致则为合法请求。
密钥轮换期间的处理
发起密钥轮换后,Subotiz 在过渡期内会使用旧密钥对 Webhook 请求进行签名;旧密钥过期后自动切换至新密钥。
建议在过渡期内,接收端同时支持新旧两个密钥验签,处理流程如下:
- 先使用旧密钥计算签名,与 X-Signature 比对;
- 若旧密钥验签失败,再使用新密钥重新验签;
- 两者均失败时,视为非法请求拒绝处理。
这样可确保密钥切换过渡期间 Webhook 事件不丢失。
处理要求
- 幂等性:基于事件 id(唯一标识)实现重复事件的幂等处理,避免重复操作;
- 事件过滤:根据事件 type 字段识别关注的事件类型,非关注类型直接返回 200 状态码;
- 顺序无关性:系统不保证事件顺序,关键业务需通过 API 主动查询同步最新状态。
响应与重试机制
- 成功响应:事件处理完成后需返回 HTTP 200 状态码,标识事件处理成功;
- 失败重试:若响应状态码非 200 或超时,系统将在 48 小时内执行 16 次退避重试(起始间隔时间为 1 min,每次间隔时间翻倍,最大间隔 4 小时)。