952 lines
44 KiB
Markdown
952 lines
44 KiB
Markdown
# 聆界短信平台 HTTP API 参考手册
|
||
|
||
**接口版本:v1 · 文档日期:2026-09-15**
|
||
|
||
## 1. API 概览
|
||
|
||
聆界短信平台 HTTP API 提供单条短信发送、发送结果查询和用户回复查询。平台还可将短信回执和用户回复主动推送到客户系统。
|
||
|
||
### 1.1 服务地址与数据格式
|
||
|
||
| 项目 | 约定 |
|
||
| ------------ | ------------------------------------------- |
|
||
| 接口基础地址 | https://api.lisglo.com/api/openapi/v1 |
|
||
| OpenAPI 定义 | https://api.lisglo.com/api/client-docs-json |
|
||
| 数据格式 | UTF-8 JSON |
|
||
| 发送方式 | POST |
|
||
| 查询方式 | GET,不携带请求体 |
|
||
| 授权方式 | Access Key + HMAC-SHA256 请求签名 |
|
||
| 发送受理 | HTTP 202 |
|
||
| 查询成功 | HTTP 200 |
|
||
|
||
业务接口的成功响应直接返回结果对象;Webhook 正文包含事件信息和 data 业务对象。
|
||
|
||
### 1.2 接口目录
|
||
|
||
| 接口名称 | 方法 | 接口路径 | 成功响应 |
|
||
| -------------------- | ---- | ---------------------------------------- | ----------------- |
|
||
| 单条短信发送接口 | POST | /api/openapi/v1/sms/messages | 202:请求已受理 |
|
||
| 单条短信回执查询接口 | GET | /api/openapi/v1/sms/messages/{messageId} | 200:返回短信状态 |
|
||
| 上行短信列表查询接口 | GET | /api/openapi/v1/sms/uplinks | 200:返回回复列表 |
|
||
| 上行短信详情查询接口 | GET | /api/openapi/v1/sms/uplinks/{uplinkId} | 200:返回指定回复 |
|
||
|
||
上表路径应拼接在 https://api.lisglo.com 后。收到 202 表示平台受理,不代表手机已经收到短信。最终结果通过回执查询或回执回调获取。
|
||
|
||
### 1.3 接入准备
|
||
|
||
1. 联系聆界平台客服创建企业账号和短信应用,开通 HTTP 及相应发送、查询、回调能力,配置调用服务器的 IP 白名单。
|
||
2. 在客户端“接口对接”选择应用,确认接口地址、QPS 和白名单。
|
||
3. 在“访问凭据”创建 Access Key 和 Secret。Secret 仅在创建或轮换时展示一次,请保存在后端安全配置中。
|
||
4. 发送前完成短信签名和模板审核;提交的完整正文应符合本应用的审核与发送要求。
|
||
5. 如需接收回调,在“回调配置”保存公网 HTTPS 地址和各自的回调签名密钥。
|
||
|
||
接口凭据只能用于所属应用,平台登录密码不能代替 Secret。回调验签密钥与接口 Secret 分开保存。轮换请求凭据时先建立新凭据并切换调用,再吊销旧凭据;回调密钥轮换需同步更新接收端。
|
||
|
||
建议先按第 2 节校对签名,再调用上行列表查询接口验证接入;没有回复时返回空列表。
|
||
|
||
### 1.4 怎样使用后面的 cURL 示例
|
||
|
||
HTTP 报文使用演示 Access Key、演示 Secret `DEMO_SECRET_NOT_A_REAL_CREDENTIAL` 和固定时间戳;签名已计算,POST 正文末尾不含换行,游标为格式示例。实际调用使用本应用凭据、当前时间、新 nonce 和上一页返回的游标。
|
||
|
||
示例中的变量按下表准备;它们表示你自己的调用参数,不是平台提供的固定凭据。
|
||
|
||
| 变量 | 准备方法 |
|
||
| ----------- | ---------------------------------------------------------- |
|
||
| $ACCESS_KEY | 填入本应用的 Access Key |
|
||
| $TIMESTAMP | 生成当前 Unix 秒级时间戳 |
|
||
| $NONCE | 为本次调用生成新的 UUID v4 |
|
||
| $SIGNATURE | 按第 2 节规则,使用本次方法、路径、时间戳、nonce 和请求体计算 |
|
||
| $CURSOR | 仅在翻页时使用,完整取自上一响应的 nextCursor |
|
||
|
||
先在本机 Bash 会话中设置相应变量,再执行 cURL。每次调用重新计算,不可直接沿用另一接口或上一次调用的签名。示例使用 Bash 续行语法;PowerShell 请使用 curl.exe 并调整变量及续行写法。
|
||
|
||
POST 示例使用 --data-binary 原样发送文件;保存 sms.json 时采用 UTF-8 无 BOM,签名也读取该文件的同一份字节。cURL 进程成功退出后仍需检查 HTTP 状态和响应。
|
||
|
||
## 2. 授权与请求签名
|
||
|
||
### 2.1 填写请求头
|
||
|
||
| 请求头 | 必填 | 填写方式 |
|
||
| ----------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||
| `X-App-Key` | 是 | 该应用的 Access Key |
|
||
| `X-Timestamp` | 是 | 当前 Unix 时间戳,单位为秒,例如 `1789344000`;不要传毫秒 |
|
||
| `X-Nonce` | 是 | 本次 HTTP 请求的唯一标识,推荐 UUID v4,例如 `550e8400-e29b-41d4-a716-446655440000`;同一次发送的网络重试时,需要重新生成 UUID v4 |
|
||
| `X-Signature` | 是 | 按下文计算的 HMAC-SHA256,小写十六进制字符串 |
|
||
| `Idempotency-Key` | 发送时必填 | 一次业务发送的稳定编号,8~128 字符,允许字母、数字、`.`、`_`、`:`、`-` |
|
||
| `Content-Type` | POST 使用 | `application/json` |
|
||
| `User-Agent` | 否 | 可填写客户端名称和版本,便于排错 |
|
||
|
||
每次调用,包括网络重试,都使用当前秒级时间戳和新的请求唯一标识。默认允许服务器时间前后相差 300 秒,具体以应用配置为准。X-Nonce 推荐 UUID v4,也接受字母、数字、下划线、短横线组成的 8~128 字符。
|
||
|
||
### 2.2 POST 发送请求如何计算签名
|
||
|
||
将请求方法、路径、时间戳、nonce 和原始请求体按以下规则拼接,使用 Secret 计算一次 HMAC-SHA256:
|
||
|
||
```text
|
||
签名原文 = 字节拼接(UTF8(请求方法 + LF + 请求路径 + LF + 时间戳 + LF + nonce + LF), 原始请求体字节)
|
||
X-Signature = HEX(HMAC_SHA256(UTF8(Secret), 签名原文))
|
||
```
|
||
|
||
| 内容 | 规则 |
|
||
| --- | --- |
|
||
| 请求方法 | 大写,例如 POST |
|
||
| 请求路径 | 从 /api 开始,不含域名及问号后的查询参数;路径参数使用实际发送的 URL 编码形式 |
|
||
| 时间戳 | 与 X-Timestamp 完全一致的秒级时间戳 |
|
||
| nonce | 与 X-Nonce 完全一致 |
|
||
| LF | 一个换行字节(0x0A),不能替换成 CRLF |
|
||
| 原始请求体 | 实际发送的 UTF-8 JSON 字节,不预先计算摘要 |
|
||
| Secret | 直接使用 UTF-8 字节作为密钥,不做 Base64 解码 |
|
||
| HEX | 转为 64 位小写十六进制字符串 |
|
||
|
||
前四项后各接一个 LF,再接完整请求体。请求体可以有多行,空格、换行和字段顺序必须与实际发送内容完全一致;不要在签名时额外增加换行。Idempotency-Key 和 URL 查询参数不参与签名。
|
||
|
||
**POST 签名校对示例:**
|
||
|
||
演示 Secret:DEMO_SECRET_NOT_A_REAL_CREDENTIAL。请求体为下面这一整行,开头没有 BOM,末尾没有换行:
|
||
|
||
```text
|
||
{"mobile":"13800138000","content":"【示例签名】您的验证码是123456,5分钟内有效。","clientMessageId":"doc-example-20260914-0001"}
|
||
```
|
||
|
||
完整签名原文:
|
||
|
||
```text
|
||
POST
|
||
/api/openapi/v1/sms/messages
|
||
1789355443
|
||
7921b5d1-3b99-48d4-a068-ea7cf0c998db
|
||
{"mobile":"13800138000","content":"【示例签名】您的验证码是123456,5分钟内有效。","clientMessageId":"doc-example-20260914-0001"}
|
||
```
|
||
|
||
**计算方法(Node.js):**
|
||
|
||
将以下代码保存为 post-signature.cjs,运行 `node post-signature.cjs`。代码使用 Node.js 自带的加密库,只进行本地计算。
|
||
|
||
```javascript
|
||
const { createHmac } = require('node:crypto');
|
||
|
||
const secret = 'DEMO_SECRET_NOT_A_REAL_CREDENTIAL';
|
||
const method = 'POST';
|
||
const path = '/api/openapi/v1/sms/messages';
|
||
const timestamp = '1789355443';
|
||
const nonce = '7921b5d1-3b99-48d4-a068-ea7cf0c998db';
|
||
const body = Buffer.from(
|
||
'{"mobile":"13800138000","content":"【示例签名】您的验证码是123456,5分钟内有效。","clientMessageId":"doc-example-20260914-0001"}',
|
||
'utf8'
|
||
);
|
||
|
||
// 前四项后各接一个 LF,再拼接实际发送的请求体字节。
|
||
const prefix = method + '\n'
|
||
+ path + '\n'
|
||
+ timestamp + '\n'
|
||
+ nonce + '\n';
|
||
const signingBytes = Buffer.concat([
|
||
Buffer.from(prefix, 'utf8'),
|
||
body,
|
||
]);
|
||
|
||
const signature = createHmac('sha256', Buffer.from(secret, 'utf8'))
|
||
.update(signingBytes)
|
||
.digest('hex');
|
||
|
||
console.log(signature);
|
||
```
|
||
|
||
实际从文件发送时,将 body 的赋值改为 `const body = require('node:fs').readFileSync('sms.json');`,签名和发送使用同一份文件字节,不要解析后重新生成 JSON。
|
||
|
||
**输出结果,填入 X-Signature:**
|
||
|
||
```text
|
||
a951451624d37d3e9df24045dc65d94557551dcbeada26988e25b6d49e945124
|
||
```
|
||
|
||
### 2.3 GET 查询请求如何计算签名
|
||
|
||
GET 请求不携带正文。签名只拼接请求方法、请求路径、时间戳和 nonce 四项,相邻项之间用一个 LF 换行符分隔,nonce 后不加换行。
|
||
|
||
**计算公式:**
|
||
|
||
```text
|
||
签名原文 = 请求方法 + LF + 请求路径 + LF + 时间戳 + LF + nonce
|
||
X-Signature = HEX(HMAC_SHA256(UTF8(Secret), UTF8(签名原文)))
|
||
```
|
||
|
||
UTF8 表示将字符串转换为 UTF-8 字节;HMAC_SHA256 表示以 Secret 为密钥对签名原文进行运算;HEX 表示将运算结果转换为 64 位小写十六进制字符串。
|
||
|
||
**本例输入:**
|
||
|
||
| 项目 | 值 |
|
||
| --- | --- |
|
||
| Secret | doc-example-secret |
|
||
| 请求方法 | GET |
|
||
| 请求路径 | /api/openapi/v1/sms/uplinks |
|
||
| 时间戳 | 1789344000 |
|
||
| nonce | 550e8400-e29b-41d4-a716-446655440000 |
|
||
|
||
请求路径不含域名和问号后的查询参数;包含路径参数时,使用实际发送的 URL 编码形式。时间戳和 nonce 必须分别与 X-Timestamp、X-Nonce 一致。Secret 直接作为 UTF-8 密钥使用,不做 Base64 解码;Access Key 和 Idempotency-Key 不参与本公式。
|
||
|
||
**拼接签名原文:**
|
||
|
||
```text
|
||
GET\n/api/openapi/v1/sms/uplinks\n1789344000\n550e8400-e29b-41d4-a716-446655440000
|
||
```
|
||
|
||
上面每个 \n 表示一个 LF 换行字节(0x0A),不是反斜杠和字母 n,也不能替换为 CRLF。签名原文在 nonce 的最后一个字符处结束,不追加 LF、{} 或其他正文。
|
||
|
||
**计算方法(Node.js):**
|
||
|
||
将以下代码保存为 get-signature.cjs,运行 `node get-signature.cjs`。代码使用 Node.js 自带的加密库,只进行本地计算。
|
||
|
||
```javascript
|
||
const { createHmac } = require('node:crypto');
|
||
|
||
const secret = 'doc-example-secret';
|
||
const method = 'GET';
|
||
const path = '/api/openapi/v1/sms/uplinks';
|
||
const timestamp = '1789344000';
|
||
const nonce = '550e8400-e29b-41d4-a716-446655440000';
|
||
|
||
// 四项之间用 LF 分隔,nonce 后不加 LF。
|
||
const signingText = method + '\n'
|
||
+ path + '\n'
|
||
+ timestamp + '\n'
|
||
+ nonce;
|
||
|
||
const signature = createHmac('sha256', Buffer.from(secret, 'utf8'))
|
||
.update(Buffer.from(signingText, 'utf8'))
|
||
.digest('hex');
|
||
|
||
console.log(signature);
|
||
```
|
||
|
||
**输出结果:**
|
||
|
||
```text
|
||
3db9c015c2b1c5365a0ef296a79b419653b0087daed2792cdb5717b0802eec51
|
||
```
|
||
|
||
将该结果填入 X-Signature 请求头。其他语言按相同输入字节调用标准库的 HMAC-SHA256,并输出小写十六进制,结果应一致。
|
||
|
||
本例的固定时间戳和演示密钥仅用于离线校对。实际调用使用本应用 Secret、当前秒级时间戳和新的 nonce,并重新计算签名。
|
||
|
||
## 3. API:单条短信发送
|
||
|
||
### 3.1 接口说明
|
||
|
||
向一个中国大陆手机号发送一条短信。正文填写完整短信签名及已替换变量的内容,平台据此匹配本应用的签名与模板。
|
||
|
||
| 项目 | 内容 |
|
||
| ------------ | -------------------------------------------------- |
|
||
| URL | https://api.lisglo.com/api/openapi/v1/sms/messages |
|
||
| HTTP 方法 | POST |
|
||
| Content-Type | application/json |
|
||
| 是否鉴权 | 是,四个鉴权头见第 2 节 |
|
||
| 业务幂等头 | Idempotency-Key,必填 |
|
||
| 所需能力 | 短信发送 |
|
||
| 成功状态 | 202 Accepted |
|
||
|
||
### 3.2 请求参数
|
||
|
||
| JSON 字段 | 类型 | 必填 | 说明 |
|
||
| ----------------- | ------ | ------------ | ---------------------------------------------------------------- |
|
||
| `mobile` | string | 是 | 单个中国大陆手机号,例如 `13800138000`;不能传数组或逗号分隔号码 |
|
||
| `content` | string | 是 | 完整短信正文,包含签名和已填入的变量值;不能为空 |
|
||
| `clientMessageId` | string | 否,建议提供 | 你的业务系统消息编号,应用内唯一;按不超过 128 字符使用 |
|
||
|
||
只传上述业务字段,不传企业、应用、签名、模板或通道选择字段。Idempotency-Key 为稳定的业务发送编号,8~128 字符,可使用字母、数字、点、下划线、冒号和短横线。
|
||
|
||
**请求体示例:**
|
||
|
||
```json
|
||
{
|
||
"mobile": "13800138000",
|
||
"content": "【示例签名】您的验证码是123456,5分钟内有效。",
|
||
"clientMessageId": "order-20260914-0001"
|
||
}
|
||
```
|
||
|
||
### 3.3 请求示例
|
||
|
||
将上面的 JSON 保存为 UTF-8 无 BOM 的 sms.json。按第 2 节对文件原始字节计算签名,并准备相应变量。发送命令:
|
||
|
||
```bash
|
||
curl --include --max-time 15 --request POST \
|
||
"https://api.lisglo.com/api/openapi/v1/sms/messages" \
|
||
--header "X-App-Key: $ACCESS_KEY" \
|
||
--header "X-Timestamp: $TIMESTAMP" \
|
||
--header "X-Nonce: $NONCE" \
|
||
--header "X-Signature: $SIGNATURE" \
|
||
--header "Content-Type: application/json" \
|
||
--header "Idempotency-Key: sms-order-20260914-0001" \
|
||
--data-binary "@sms.json"
|
||
```
|
||
|
||
**HTTP 请求报文:**
|
||
|
||
```http
|
||
POST /api/openapi/v1/sms/messages HTTP/1.1
|
||
Host: api.lisglo.com
|
||
Accept: */*
|
||
X-App-Key: DEMO_ACCESS_KEY_NOT_REGISTERED
|
||
X-Timestamp: 1789355443
|
||
X-Nonce: 4755e099-ba9a-4e6f-affa-3630261e7feb
|
||
X-Signature: e2a70fdd364cc865e251d475cec722bb949500d255649d215b0039de89f68125
|
||
Content-Type: application/json
|
||
Idempotency-Key: sms-order-20260914-0001
|
||
Content-Length: 154
|
||
|
||
{
|
||
"mobile": "13800138000",
|
||
"content": "【示例签名】您的验证码是123456,5分钟内有效。",
|
||
"clientMessageId": "order-20260914-0001"
|
||
}
|
||
```
|
||
|
||
执行使用有效凭据的发送命令会提交短信请求;文档样例不自动执行。
|
||
|
||
### 3.4 返回结果
|
||
|
||
**受理成功:**
|
||
|
||
```http
|
||
HTTP/1.1 202 Accepted
|
||
Content-Type: application/json; charset=utf-8
|
||
|
||
{
|
||
"code": "ACCEPTED",
|
||
"requestId": "req_11111111-1111-4111-8111-111111111111",
|
||
"messageId": "MSG-22222222-2222-4222-8222-222222222222",
|
||
"clientMessageId": "order-20260914-0001",
|
||
"status": "queued",
|
||
"acceptedAt": "2026-09-14T02:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| --------------- | ----------- | ------------------------------------------- |
|
||
| code | string | ACCEPTED 表示受理成功 |
|
||
| requestId | string | 业务请求编号,用于排障 |
|
||
| messageId | string | 平台短信编号,用于查询 |
|
||
| clientMessageId | string/null | 调用方传入的业务短信编号 |
|
||
| status | string | 当前业务状态,例如 queued 或 pending_review |
|
||
| acceptedAt | string | 受理时间,ISO 8601 |
|
||
|
||
保存 messageId 与客户业务编号的对应关系。202 不等于短信送达;若未取得明确结果,先查询已有记录。
|
||
|
||
**幂等键与正文不一致:**
|
||
|
||
```http
|
||
HTTP/1.1 409 Conflict
|
||
Content-Type: application/problem+json; charset=utf-8
|
||
|
||
{
|
||
"type": "https://cmpp-platform.local/problems/idempotency_conflict",
|
||
"title": "CONFLICT",
|
||
"status": 409,
|
||
"code": "IDEMPOTENCY_CONFLICT",
|
||
"detail": "同一Idempotency-Key对应的请求内容不一致"
|
||
}
|
||
```
|
||
|
||
### 3.5 超时、重试与重复请求
|
||
|
||
| 情况 | 建议处理 |
|
||
| ---------------------------- | ----------------------------------------------------------------- |
|
||
| 网络超时,无法确认受理结果 | 先按 clientMessageId 查询;必要时使用相同幂等键和相同原始正文重试 |
|
||
| 重试一次 HTTP 调用 | 重新生成时间戳、nonce 和签名;业务幂等键及正文保持不变 |
|
||
| 相同幂等键且正文一致 | 已完成时重放原受理响应或已保存的业务失败结果 |
|
||
| 相同幂等键但正文不同 | 返回 IDEMPOTENCY_CONFLICT |
|
||
| 原请求仍处理中 | 返回 REQUEST_PROCESSING;稍后查询,长期不结束联系平台 |
|
||
| 换幂等键但客户短信编号已使用 | 返回 CLIENT_MESSAGE_ID_CONFLICT,核对已有业务 |
|
||
|
||
保存业务幂等键,不通过换键绕过冲突。JSON 空格或字段顺序变化也会被判定为不同正文。
|
||
|
||
## 4. API:单条短信回执查询
|
||
|
||
### 4.1 接口说明
|
||
|
||
查询一条短信的提交状态、回执结果和时间。
|
||
|
||
| 项目 | 内容 |
|
||
| --------- | -------------------------------------------------------------- |
|
||
| URL | https://api.lisglo.com/api/openapi/v1/sms/messages/{messageId} |
|
||
| HTTP 方法 | GET |
|
||
| 请求体 | 无 |
|
||
| 是否鉴权 | 是,按第 2 节 GET 规则签名 |
|
||
| 所需能力 | 短信状态查询 |
|
||
| 成功状态 | 200 OK |
|
||
|
||
### 4.2 路径参数
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| --------- | ------ | ---- | -------------------------------------------------------------- |
|
||
| messageId | string | 是 | 平台短信编号,也支持发送时提交的 clientMessageId;仅限当前应用 |
|
||
|
||
路径参数需 URL 编码,签名使用编码后的实际路径。
|
||
|
||
### 4.3 请求示例
|
||
|
||
```bash
|
||
curl --include --max-time 15 --request GET \
|
||
"https://api.lisglo.com/api/openapi/v1/sms/messages/MSG-22222222-2222-4222-8222-222222222222" \
|
||
--header "X-App-Key: $ACCESS_KEY" \
|
||
--header "X-Timestamp: $TIMESTAMP" \
|
||
--header "X-Nonce: $NONCE" \
|
||
--header "X-Signature: $SIGNATURE"
|
||
```
|
||
|
||
**HTTP 请求报文:**
|
||
|
||
```http
|
||
GET /api/openapi/v1/sms/messages/MSG-22222222-2222-4222-8222-222222222222 HTTP/1.1
|
||
Host: api.lisglo.com
|
||
Accept: */*
|
||
X-App-Key: DEMO_ACCESS_KEY_NOT_REGISTERED
|
||
X-Timestamp: 1789355443
|
||
X-Nonce: 3efb63ee-b99d-47c2-aa87-cbfeb7730a30
|
||
X-Signature: 8843aa140566a16a9fddd81339235a94abc218af125963ca2df365e5454f8212
|
||
|
||
|
||
```
|
||
|
||
### 4.4 返回结果
|
||
|
||
**查询成功:**
|
||
|
||
```http
|
||
HTTP/1.1 200 OK
|
||
Content-Type: application/json; charset=utf-8
|
||
|
||
{
|
||
"messageId": "MSG-22222222-2222-4222-8222-222222222222",
|
||
"clientMessageId": "order-20260914-0001",
|
||
"phoneNumber": "13800138000",
|
||
"status": "delivered",
|
||
"submitStatus": "accepted",
|
||
"receiptStatus": "delivered",
|
||
"errorCode": null,
|
||
"errorMessage": null,
|
||
"queuedAt": "2026-09-14T02:00:00.000Z",
|
||
"submittedAt": "2026-09-14T02:00:01.000Z",
|
||
"deliveredAt": "2026-09-14T02:00:03.000Z",
|
||
"updatedAt": "2026-09-14T02:00:03.100Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| ----------------------------- | ----------- | --------------------------------------------------------------- |
|
||
| `messageId` | string | 平台短信编号 |
|
||
| `clientMessageId` | string/null | 客户消息编号 |
|
||
| `phoneNumber` | string | 接收手机号;注意响应字段不是 mobile |
|
||
| `status` | string | 平台业务状态 |
|
||
| `submitStatus` | string/null | 提交状态,如 queued、accepted、rejected、timeout |
|
||
| `receiptStatus` | string/null | 回执状态,如 delivered、undelivered、unknown;null 表示尚无结果 |
|
||
| `errorCode` / `errorMessage` | string/null | 失败码与说明,未发生或暂无时可为空 |
|
||
| `queuedAt` / `updatedAt` | string | 入队记录时间、最近更新时间 |
|
||
| `submittedAt` / `deliveredAt` | string/null | 提交时间、结果时间,尚无数据时可为空 |
|
||
|
||
常见 `status` 的业务含义:
|
||
|
||
| 状态 | 你应如何理解 |
|
||
| --------------------------------------- | -------------------------------------------------- |
|
||
| `pending_review` | 等待审核,不代表已送出 |
|
||
| `queued` / `submit_queued` | 等待平台处理或向通道提交 |
|
||
| `submitted` | 已提交,等待明确回执 |
|
||
| `delivered` | 已获得送达结果 |
|
||
| `submit_failed` / `failed` / `rejected` | 提交失败、发送失败或业务拒绝,结合错误字段查看原因 |
|
||
| `unknown` / `timeout` | 结果未知或等待超时,不能当成送达 |
|
||
|
||
上述是常见值,不是服务端严格冻结的全部枚举。遇到其他值保留原值并展示“待确认”,不要默认成功。`deliveredAt` 在失败回执中也可能是结果发生时间,不能只看这个字段非空就认为送达。
|
||
|
||
不存在或不属于本应用时返回 404 `MESSAGE_NOT_FOUND`。查询刚超时的发送得到 404 也不能单独证明业务永远不会落库。
|
||
|
||
**记录不存在或不属于当前应用:**
|
||
|
||
```http
|
||
HTTP/1.1 404 Not Found
|
||
Content-Type: application/problem+json; charset=utf-8
|
||
|
||
{
|
||
"type": "https://cmpp-platform.local/problems/message_not_found",
|
||
"title": "NOT_FOUND",
|
||
"status": 404,
|
||
"code": "MESSAGE_NOT_FOUND",
|
||
"detail": "短信记录不存在"
|
||
}
|
||
```
|
||
|
||
## 5. API:上行短信列表查询
|
||
|
||
### 5.1 接口说明
|
||
|
||
查询手机用户回复的短信。无需填写时间参数,默认读取最近 24 小时内已归属本应用的回复。
|
||
|
||
| 项目 | 内容 |
|
||
| --------- | ------------------------------------------------- |
|
||
| URL | https://api.lisglo.com/api/openapi/v1/sms/uplinks |
|
||
| HTTP 方法 | GET |
|
||
| 请求体 | 无 |
|
||
| 是否鉴权 | 是,按第 2 节 GET 规则签名 |
|
||
| 所需能力 | 上行查询 |
|
||
| 成功状态 | 200 OK |
|
||
| 排序 | 接收时间、记录编号倒序 |
|
||
|
||
### 5.2 查询参数
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 / 说明 |
|
||
| ------------ | ------ | ---- | ------------------------------------------------- |
|
||
| mobile | string | 否 | 1 开头的 11 位手机号,精确匹配 |
|
||
| accessNumber | string | 否 | 1–21 位数字接入号,精确匹配 destId |
|
||
| keyword | string | 否 | 筛选正文包含指定关键词的回复 |
|
||
| limit | 正整数 | 否 | 默认 50;按应用最大分页配置裁剪,系统默认上限 100 |
|
||
| cursor | string | 否 | 首次不传;下一页使用上一响应的 nextCursor |
|
||
|
||
不使用的筛选项省略,所有 query 参数都不放入签名原文。
|
||
|
||
### 5.3 请求示例
|
||
|
||
```bash
|
||
curl --include --max-time 15 --get \
|
||
"https://api.lisglo.com/api/openapi/v1/sms/uplinks" \
|
||
--data-urlencode "limit=25" \
|
||
--header "X-App-Key: $ACCESS_KEY" \
|
||
--header "X-Timestamp: $TIMESTAMP" \
|
||
--header "X-Nonce: $NONCE" \
|
||
--header "X-Signature: $SIGNATURE"
|
||
```
|
||
|
||
**HTTP 请求报文:**
|
||
|
||
```http
|
||
GET /api/openapi/v1/sms/uplinks?limit=25 HTTP/1.1
|
||
Host: api.lisglo.com
|
||
Accept: */*
|
||
X-App-Key: DEMO_ACCESS_KEY_NOT_REGISTERED
|
||
X-Timestamp: 1789355443
|
||
X-Nonce: 567a9bdd-7d62-4097-9fa8-50586fa14c32
|
||
X-Signature: 7ca4cb9fe5fb455d9314797d00eeab797257e2671d0a547414122e971f534214
|
||
|
||
|
||
```
|
||
|
||
### 5.4 返回结果
|
||
|
||
**查询成功:**
|
||
|
||
```http
|
||
HTTP/1.1 200 OK
|
||
Content-Type: application/json; charset=utf-8
|
||
|
||
{
|
||
"items": [
|
||
{
|
||
"id": "uplink-example-001",
|
||
"messageId": null,
|
||
"phoneNumber": "13800138000",
|
||
"destId": "106900000000",
|
||
"content": "收到,谢谢",
|
||
"receivedAt": "2026-09-14T02:05:00.000Z"
|
||
}
|
||
],
|
||
"nextCursor": null
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| ---------- | ----------- | --------------------------------- |
|
||
| items | array | 本页上行记录,没有记录时为空数组 |
|
||
| nextCursor | string/null | 下一页凭据;null 表示本次查询结束 |
|
||
|
||
items 中每条记录的字段:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| ----------- | ----------- | ----------------------------------- |
|
||
| id | string | 上行记录编号,用于查询详情 |
|
||
| messageId | string/null | 关联的平台短信编号,未关联时为 null |
|
||
| phoneNumber | string | 回复短信的手机号 |
|
||
| destId | string | 接收回复的短信接入号 |
|
||
| content | string | 用户回复的正文 |
|
||
| receivedAt | string | 接收时间,ISO 8601;Z 表示 UTC |
|
||
|
||
**没有回复:**
|
||
|
||
```json
|
||
{
|
||
"items": [],
|
||
"nextCursor": null
|
||
}
|
||
```
|
||
|
||
HTTP 状态为 200。无总条数或页码字段。
|
||
|
||
**分页参数错误:**
|
||
|
||
```http
|
||
HTTP/1.1 400 Bad Request
|
||
Content-Type: application/problem+json; charset=utf-8
|
||
|
||
{
|
||
"type": "https://cmpp-platform.local/problems/limit_invalid",
|
||
"title": "BAD_REQUEST",
|
||
"status": 400,
|
||
"code": "LIMIT_INVALID",
|
||
"detail": "limit必须为正整数"
|
||
}
|
||
```
|
||
|
||
### 5.5 下一页查询
|
||
|
||
nextCursor 非 null 时,将完整值赋给 $CURSOR,保持首次使用的 limit 和其他筛选不变,重新生成鉴权头。假设第一页使用 limit=25,下一页示例:
|
||
|
||
```bash
|
||
curl --include --max-time 15 --get \
|
||
"https://api.lisglo.com/api/openapi/v1/sms/uplinks" \
|
||
--data-urlencode "limit=25" \
|
||
--data-urlencode "cursor=$CURSOR" \
|
||
--header "X-App-Key: $ACCESS_KEY" \
|
||
--header "X-Timestamp: $TIMESTAMP" \
|
||
--header "X-Nonce: $NONCE" \
|
||
--header "X-Signature: $SIGNATURE"
|
||
```
|
||
|
||
**HTTP 请求报文:**
|
||
|
||
```http
|
||
GET /api/openapi/v1/sms/uplinks?limit=25&cursor=WyIyMDI2LTA5LTE0VDAyOjA1OjAwLjAwMFoiLCJ1cGxpbmstZXhhbXBsZS0wMDEiXQ HTTP/1.1
|
||
Host: api.lisglo.com
|
||
Accept: */*
|
||
X-App-Key: DEMO_ACCESS_KEY_NOT_REGISTERED
|
||
X-Timestamp: 1789355443
|
||
X-Nonce: 2232e6cf-144d-41c6-ac86-df7fb6184d78
|
||
X-Signature: 50869db4ff5a3b2d3ba5e6c1184020fc0ed50fbc594a56ccc6e2a16f7b617657
|
||
|
||
|
||
```
|
||
|
||
直到 nextCursor 为 null 后停止。游标由平台返回,不自行生成或解码;格式错误返回 400 CURSOR_INVALID。每次默认查询范围随当前时间滚动,同一轮翻页应尽快完成,定期采集按 id 去重。历史补查或完整历史同步请联系平台。
|
||
|
||
## 6. API:上行短信详情查询
|
||
|
||
### 6.1 接口说明
|
||
|
||
查看一条用户回复的完整业务信息。
|
||
|
||
| 项目 | 内容 |
|
||
| --------- | ------------------------------------------------------------ |
|
||
| URL | https://api.lisglo.com/api/openapi/v1/sms/uplinks/{uplinkId} |
|
||
| HTTP 方法 | GET |
|
||
| 请求体 | 无 |
|
||
| 是否鉴权 | 是,按第 2 节 GET 规则签名 |
|
||
| 所需能力 | 上行查询 |
|
||
| 成功状态 | 200 OK |
|
||
|
||
### 6.2 路径参数
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| -------- | ------ | ---- | ------------------------------------------------------- |
|
||
| uplinkId | string | 是 | 列表中的 id 或回调中的 uplinkMessageId,按 URL 路径编码 |
|
||
|
||
### 6.3 请求示例
|
||
|
||
```bash
|
||
curl --include --max-time 15 --get \
|
||
"https://api.lisglo.com/api/openapi/v1/sms/uplinks/uplink-example-001" \
|
||
--header "X-App-Key: $ACCESS_KEY" \
|
||
--header "X-Timestamp: $TIMESTAMP" \
|
||
--header "X-Nonce: $NONCE" \
|
||
--header "X-Signature: $SIGNATURE"
|
||
```
|
||
|
||
**HTTP 请求报文:**
|
||
|
||
```http
|
||
GET /api/openapi/v1/sms/uplinks/uplink-example-001 HTTP/1.1
|
||
Host: api.lisglo.com
|
||
Accept: */*
|
||
X-App-Key: DEMO_ACCESS_KEY_NOT_REGISTERED
|
||
X-Timestamp: 1789355443
|
||
X-Nonce: 7229fc46-7526-4726-a42b-a8edfe68fbdf
|
||
X-Signature: 869e57abbd91ceaadb73dbca1a091d0deba083e93acccc58cc4a941d9c18a1c8
|
||
|
||
|
||
```
|
||
|
||
### 6.4 返回结果
|
||
|
||
**查询成功:**
|
||
|
||
```http
|
||
HTTP/1.1 200 OK
|
||
Content-Type: application/json; charset=utf-8
|
||
|
||
{
|
||
"id": "uplink-example-001",
|
||
"messageId": null,
|
||
"phoneNumber": "13800138000",
|
||
"destId": "106900000000",
|
||
"content": "收到,谢谢",
|
||
"receivedAt": "2026-09-14T02:05:00.000Z",
|
||
"tenantId": "tenant-example",
|
||
"applicationId": "application-example"
|
||
}
|
||
```
|
||
|
||
字段与第 5 节单条记录相同,增加 tenantId(本企业 ID)、applicationId(本应用 ID);只返回客户自己的业务信息,不提供通道字段。
|
||
|
||
**查询失败:**
|
||
|
||
```http
|
||
HTTP/1.1 404 Not Found
|
||
Content-Type: application/problem+json; charset=utf-8
|
||
|
||
{
|
||
"type": "https://cmpp-platform.local/problems/uplink_not_found",
|
||
"title": "NOT_FOUND",
|
||
"status": 404,
|
||
"code": "UPLINK_NOT_FOUND",
|
||
"detail": "上行记录不存在"
|
||
}
|
||
```
|
||
|
||
## 7. Webhook:短信回执通知
|
||
|
||
### 7.1 通知说明
|
||
|
||
短信产生回执结果时,平台向客户配置的回执地址发送 receipt 事件。
|
||
|
||
| 项目 | 内容 |
|
||
| ------------ | ------------------------------------- |
|
||
| URL | 客户在回调配置中保存的公网 HTTPS 地址 |
|
||
| HTTP 方法 | POST |
|
||
| Content-Type | application/json |
|
||
| 事件类型 | receipt |
|
||
| 签名密钥 | 回执回调地址对应的密钥 |
|
||
| 成功确认 | 客户返回任意 HTTP 2xx |
|
||
|
||
参数错误或未受理的同步请求不保证生成回调;长短信按业务消息通知。保存发送响应中的编号映射,按 data.messageId 关联业务,回调不保证携带 clientMessageId。
|
||
|
||
### 7.2 请求头
|
||
|
||
| 请求头 | 说明 |
|
||
| ------------ | --------------------------------------- |
|
||
| Content-Type | application/json |
|
||
| X-Event-Id | 事件编号,用于去重 |
|
||
| X-Event-Type | receipt(回执)或 uplink(用户回复) |
|
||
| X-Timestamp | 本次投递的 Unix 秒级时间戳 |
|
||
| X-Signature | sha256= 前缀加 HMAC-SHA256 十六进制签名 |
|
||
|
||
### 7.3 请求字段
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| ---------- | ------ | ---------------------------------- |
|
||
| eventId | string | 同一事件的唯一编号,重复投递时不变 |
|
||
| eventType | string | 事件类型 |
|
||
| occurredAt | string | 事件生成时间,ISO 8601 |
|
||
| data | object | 对应事件的业务数据 |
|
||
|
||
receipt 事件的 data 字段:
|
||
|
||
| data 字段 | 类型 | 说明 |
|
||
| ---------------- | ----------- | -------------------------------------------- |
|
||
| messageId | string | 平台短信编号,与发送响应关联 |
|
||
| gatewayMessageId | string/null | 短信传输编号,可缺省;关联业务使用 messageId |
|
||
| phoneNumber | string | 接收短信的手机号 |
|
||
| receiptStatus | string | 回执结果,delivered 表示送达 |
|
||
| rawStatus | string/null | 原始回执状态,如 DELIVRD;可缺省 |
|
||
| errorCode | string/null | 错误码,可缺省 |
|
||
| errorMessage | string/null | 错误说明,部分失败事件提供 |
|
||
| deliveredAt | string/null | 结果时间,可缺省;时间存在不等于发送成功 |
|
||
|
||
### 7.4 通知示例
|
||
|
||
```http
|
||
POST /webhooks/sms/receipt HTTP/1.1
|
||
Host: customer.example.com
|
||
Content-Type: application/json
|
||
X-Event-Id: evt_receipt_example001
|
||
X-Event-Type: receipt
|
||
X-Timestamp: 1789344000
|
||
X-Signature: sha256=<本次投递的签名>
|
||
|
||
{
|
||
"eventId": "evt_receipt_example001",
|
||
"eventType": "receipt",
|
||
"occurredAt": "2026-09-14T02:00:03.100Z",
|
||
"data": {
|
||
"messageId": "MSG-22222222-2222-4222-8222-222222222222",
|
||
"gatewayMessageId": "example-gateway-id",
|
||
"phoneNumber": "13800138000",
|
||
"receiptStatus": "delivered",
|
||
"rawStatus": "DELIVRD",
|
||
"errorCode": null,
|
||
"deliveredAt": "2026-09-14T02:00:03.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
地址和签名为说明用途,实际平台使用客户配置的地址并生成本次签名。
|
||
|
||
### 7.5 验证通知签名
|
||
|
||
回调验签与接口请求签名不同。回调只对“时间戳、一个 LF 换行、原始请求体”签名,使用该回调地址对应的签名密钥。
|
||
|
||
```text
|
||
签名原文 = UTF8(X-Timestamp) + LF + 原始请求体字节
|
||
期望签名 = "sha256=" + HEX(HMAC_SHA256(回调签名密钥, 签名原文))
|
||
```
|
||
|
||
接收端按以下顺序处理:
|
||
|
||
1. 保留原始请求体字节,不要解析后重新生成 JSON 再验签。
|
||
2. 检查时间戳为秒级时间戳并校验时间偏差;接收端可采用前后 300 秒的策略。
|
||
3. 计算期望签名,使用常量时间比较方法与 X-Signature 比较。
|
||
4. 验签通过后解析 JSON,核对请求头与正文中的事件编号、事件类型一致。
|
||
5. 以 eventId 做持久化唯一约束或原子去重,再保存事件。
|
||
|
||
同一事件重试时,eventId 和事件正文不变,投递时间戳和签名重新生成。已成功保存的重复事件正常确认,不重复执行后续业务。occurredAt 是事件生成时间,短信实际结果或回复时间分别取 data.deliveredAt、data.receivedAt。
|
||
|
||
### 7.6 接收确认与失败重试
|
||
|
||
平台将任意 HTTP 2xx 视为接收成功,不要求固定响应正文。建议验签并可靠保存后及时确认,后续业务异步处理。
|
||
|
||
**接收成功响应示例:**
|
||
|
||
```http
|
||
HTTP/1.1 200 OK
|
||
Content-Type: text/plain; charset=utf-8
|
||
|
||
OK
|
||
```
|
||
|
||
**暂时无法保存时的响应示例:**
|
||
|
||
```http
|
||
HTTP/1.1 503 Service Unavailable
|
||
Content-Type: text/plain; charset=utf-8
|
||
|
||
temporarily unavailable
|
||
```
|
||
|
||
| 接收端结果 | 平台处理 |
|
||
| ----------------------- | ---------------------------------------------------- |
|
||
| 任意 2xx | 视为成功,不再自动重试;即使正文写“失败”也按成功处理 |
|
||
| 网络错误、408、429、5xx | 在应用开启重试且未达到次数上限时安排重试 |
|
||
| 其他 4xx | 视为失败,通常不自动重试 |
|
||
| 3xx | 不跟随重定向 |
|
||
|
||
默认最多尝试 7 次,包含第一次投递。第一次失败后依次等待 1 分钟、5 分钟、15 分钟、1 小时、6 小时、24 小时;这些是相邻尝试之间的等待时间,具体受应用重试配置限制。默认回调超时配置为 10 秒,请尽快完成可靠保存和确认。
|
||
|
||
回调未收到不等于短信发送失败,可使用短信回执查询接口核对结果。回调可能重复或延迟到达,业务系统应按事件编号去重。
|
||
|
||
## 8. Webhook:上行短信通知
|
||
|
||
### 8.1 通知说明
|
||
|
||
收到并确认归属本应用的用户回复后,平台向上行回调地址发送 uplink 事件。
|
||
|
||
| 项目 | 内容 |
|
||
| ------------ | ----------------------------------------- |
|
||
| URL | 客户在回调配置中保存的上行公网 HTTPS 地址 |
|
||
| HTTP 方法 | POST |
|
||
| Content-Type | application/json |
|
||
| 事件类型 | uplink |
|
||
| 签名密钥 | 上行回调地址对应的密钥 |
|
||
| 成功确认 | 客户返回任意 HTTP 2xx |
|
||
|
||
### 8.2 请求字段
|
||
|
||
公共请求头和事件外层字段与第 7 节相同,事件类型为 uplink。data 包含:
|
||
|
||
| data 字段 | 类型 | 说明 |
|
||
| --------------- | ----------- | ---------------------------------------- |
|
||
| applicationId | string | 本应用 ID |
|
||
| phoneNumber | string | 回复者手机号 |
|
||
| destId | string | 接收回复的短信接入号 |
|
||
| content | string | 回复正文 |
|
||
| receivedAt | string | 接收时间,ISO 8601 |
|
||
| uplinkMessageId | string | 上行记录编号,可用于详情查询 |
|
||
| messageId | string/null | 可能提供的关联短信编号;缺省时不强行关联 |
|
||
| manualClaim | boolean | 可选;true 表示该回复经人工确认归属 |
|
||
|
||
### 8.3 通知示例
|
||
|
||
```http
|
||
POST /webhooks/sms/uplink HTTP/1.1
|
||
Host: customer.example.com
|
||
Content-Type: application/json
|
||
X-Event-Id: evt_uplink_example001
|
||
X-Event-Type: uplink
|
||
X-Timestamp: 1789344000
|
||
X-Signature: sha256=<本次投递的签名>
|
||
|
||
{
|
||
"eventId": "evt_uplink_example001",
|
||
"eventType": "uplink",
|
||
"occurredAt": "2026-09-14T02:05:00.100Z",
|
||
"data": {
|
||
"applicationId": "application-example",
|
||
"phoneNumber": "13800138000",
|
||
"destId": "106900000000",
|
||
"content": "收到,谢谢",
|
||
"receivedAt": "2026-09-14T02:05:00.000Z",
|
||
"uplinkMessageId": "uplink-example-001"
|
||
}
|
||
}
|
||
```
|
||
|
||
没有 messageId 时,按 uplinkMessageId 保存用户回复,不强行关联发送记录。
|
||
|
||
### 8.4 验签与确认
|
||
|
||
按第 7.5 节规则验签,但使用上行回调密钥。以 eventId 原子去重并可靠保存后,按第 7.6 节返回 2xx;失败重试规则相同。
|
||
|
||
```http
|
||
HTTP/1.1 200 OK
|
||
Content-Type: text/plain; charset=utf-8
|
||
|
||
OK
|
||
```
|
||
|
||
## 9. HTTP 状态与错误码
|
||
|
||
错误响应示例:
|
||
|
||
```json
|
||
{
|
||
"type": "https://cmpp-platform.local/problems/signature_invalid",
|
||
"title": "UNAUTHORIZED",
|
||
"status": 401,
|
||
"code": "SIGNATURE_INVALID",
|
||
"detail": "请求签名校验失败"
|
||
}
|
||
```
|
||
|
||
| HTTP | code | 处理方法 |
|
||
| ---- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
||
| 400 | `PARAMETER_INVALID` / `LIMIT_INVALID` | 检查字段类型、长度和正整数分页 |
|
||
| 409 | `REQUEST_REQUIRES_REVIEW` | 提供 requestId 核对,不更换幂等键重发 |
|
||
| 400 | `MOBILE_INVALID` / `CONTENT_REQUIRED` | 检查单个手机号和正文 |
|
||
| 400 | `IDEMPOTENCY_KEY_INVALID` | 补齐有效幂等键,检查长度与字符 |
|
||
| 413 | `PAYLOAD_TOO_LARGE` | JSON 请求体超过 2 MiB 限制,减少内容后再提交 |
|
||
| 415 | `UNSUPPORTED_MEDIA_TYPE` | 检查请求体编码及字符集,使用 UTF-8 JSON |
|
||
| 400 | `CURSOR_INVALID` | 使用平台返回的 cursor,保持筛选条件一致 |
|
||
| 401 | `AUTH_HEADERS_MISSING` | 补齐四个鉴权头 |
|
||
| 401 | `CREDENTIAL_INVALID` | 核对应用、Access Key、有效期和吊销状态 |
|
||
| 401 | `NONCE_INVALID` / `NONCE_REPLAYED` | 检查格式,每次调用生成新的 nonce |
|
||
| 401 | `TIMESTAMP_EXPIRED` | 使用秒级时间戳并同步时钟 |
|
||
| 401 | `SIGNATURE_INVALID` | 核对 Secret、签名原文、路径、原始请求体及 GET 末尾无换行 |
|
||
| 403 | `HTTP_API_DISABLED` | 应用未启用或未开通 HTTP,联系平台 |
|
||
| 403 | `IP_NOT_ALLOWED` | 核对调用机器公网出口 IP 和 HTTP 白名单 |
|
||
| 403 | `SEND_NOT_ENABLED` / `MESSAGE_QUERY_NOT_ENABLED` / `UPLINK_QUERY_NOT_ENABLED` | 联系平台开通对应子能力 |
|
||
| 404 | `MESSAGE_NOT_FOUND` / `UPLINK_NOT_FOUND` | 核对编号及凭据所属应用 |
|
||
| 409 | `IDEMPOTENCY_CONFLICT` | 同键 body 不一致,停止盲重试并核对原请求 |
|
||
| 409 | `REQUEST_PROCESSING` | 查询既有业务结果;长期停留联系平台 |
|
||
| 409 | `CLIENT_MESSAGE_ID_CONFLICT` | 查询已有客户编号对应记录,避免重复业务发送 |
|
||
| 422 | `SEND_REJECTED` | 正文、审核或其他业务条件不满足,按说明处理,不盲重试 |
|
||
| 429 | `QPS_LIMIT_EXCEEDED` | 应用共享限流,降低并发、延后并加随机退避;新凭据不能扩大应用额度 |
|
||
| 5xx | `REQUEST_FAILED` / `INTERNAL_ERROR` 等 | 保留请求标识和时间联系平台;发送场景先查询,避免重新创建业务 |
|
||
|
||
遇到未知状态或错误码时,保留原始响应并联系平台;不要默认成功。网络中断也可能没有 HTTP 响应。发送结果不确定时先核对已有记录,避免创建重复业务。
|
||
|
||
联系平台排查时,请提供应用名称、请求时间及时区、接口路径、HTTP 状态、业务 code,以及相关 requestId、messageId、clientMessageId 或 eventId。响应头 X-Request-Id 用于定位本次 HTTP 调用;发送正文 requestId 用于定位该次业务受理。不要提供 Secret 或完整鉴权信息。
|