> ## Documentation Index
> Fetch the complete documentation index at: https://docs.subotiz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 概述

在与 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 | 签名字符串.            |

### 请求体结构

<Tabs>
  <Tab title="V1">
    | **属性**  | **类型** | **描述**                    | **示例**               |
    | ------- | ------ | ------------------------- | -------------------- |
    | id      | uint64 | 事件 id                     | 545440011265267736   |
    | type    | string | 事件类型                      | payment.success      |
    | created | string | 创建时间                      | 2025-07-01T10:25:25Z |
    | data    | object | 具体事件的业务对象，事件类型不同会有不同的数据结构 |                      |
  </Tab>

  <Tab title="V2">
    | **属性**  | **类型** | **描述**                    | **示例**               |
    | ------- | ------ | ------------------------- | -------------------- |
    | id      | string | 事件 id                     | 545440011265267736   |
    | type    | string | 事件类型                      | payment.success      |
    | created | string | 创建时间                      | 2025-07-01T10:25:25Z |
    | data    | object | 具体事件的业务对象，事件类型不同会有不同的数据结构 |                      |
  </Tab>
</Tabs>

## 事件处理规范

### 可靠性验证

接收事件前需通过以下步骤验证请求合法性：

1. **提取参数**：从请求头获取 X-Timestamp 时间戳（记为`timestamp`），并获取原始请求体内容（记为`body`）；

2. **构造签名原串**：格式为`${timestamp}.${body}`；

3. **计算签名**：使用 Subotiz 分配的 `API Key` 作为密钥，通过 HMAC-SHA256 算法计算签名值；

   示例代码: GO

   ```go theme={null}
   // 计算签名
   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))
   }
   ```

4. **比对验证**：将计算得到的签名与请求头中的 X-Signature 值比对，一致则为合法请求。

### 密钥轮换期间的处理

发起密钥轮换后，Subotiz 在**过渡期内会使用旧密钥**对 Webhook 请求进行签名；旧密钥过期后自动切换至新密钥。

**建议在过渡期内，接收端同时支持新旧两个密钥验签**，处理流程如下：

1. 先使用**旧密钥**计算签名，与 X-Signature 比对；
2. 若旧密钥验签失败，再使用**新密钥**重新验签；
3. 两者均失败时，视为非法请求拒绝处理。

这样可确保密钥切换过渡期间 Webhook 事件不丢失。

## 处理要求

* **幂等性**：基于事件 id（唯一标识）实现重复事件的幂等处理，避免重复操作；
* **事件过滤**：根据事件 type 字段识别关注的事件类型，非关注类型直接返回 200 状态码；
* **顺序无关性**：系统不保证事件顺序，关键业务需通过 API 主动查询同步最新状态。

## 响应与重试机制

* **成功响应**：事件处理完成后需返回 HTTP 200 状态码，标识事件处理成功；
* **失败重试**：若响应状态码非 200 或超时，系统将在 48 小时内执行 16 次退避重试（起始间隔时间为 1 min，每次间隔时间翻倍，最大间隔 4 小时）。
