## 请求规范
| 项目 | 要求 |
| ------------ | ------------------ |
| 请求协议 | HTTPS |
| 请求方法 | POST |
| 请求格式 | JSON |
| 响应格式 | JSON |
| 字符编码 | UTF-8 |
| Content-Type | `application/json` |
中国大陆API域名为:
https://vsi-api.shouqianba.com
## 选择签名凭证
| 接口类型 | 签名序列号 | 签名密钥 |
| -------------------------------- | ------------- | -------------- |
| 激活接口 | `vendor_sn` | `vendor_key` |
| 签到、支付、查询和退款等终端接口 | `terminal_sn` | `terminal_key` |
序列号与密钥必须属于同一开发者或同一终端。签到更新密钥后,后续请求必须使用最新`terminal_key`。
## 生成签名
标准接口签名公式:
```text
sign = MD5(body + key)
```
### 序列化请求正文
先构造请求对象,再使用UTF-8序列化一次,得到最终要发送的JSON字符串`body`。
```json
{"terminal_sn":"100000000000000001","client_sn":"ORDER_202609040001"}
```
JSON中的空格、换行、转义方式和字段顺序都会改变参与签名的字节。程序应保存这次序列化结果,不要在签名后重新生成请求正文。
### 计算签名
将`body`与当前接口对应的`key`直接拼接,中间不增加空格、换行或分隔符,再计算MD5。
```text
待签名内容 = body + key
sign = MD5(待签名内容)
```
### 设置Authorization
将签名序列号`sn`与`sign`使用一个半角空格连接:
```http
Authorization: {sn} {sign}
Content-Type: application/json
```
激活接口的`sn`是`vendor_sn`;其他标准终端接口的`sn`是当前`terminal_sn`。
### 发送原始正文
HTTP客户端发送的请求正文必须与计算签名时的`body`完全一致:
```text
请求对象
→ 序列化一次并保存body
→ 计算MD5(body + key)
→ 设置Authorization
→ 原样发送已保存的body
```
不要把对象再次交给HTTP框架自动序列化,否则框架可能改变字段顺序、空格或转义,导致签名不一致。
## 请求示例
以下只演示请求结构,不代表具体接口的完整字段:
```bash
curl --request POST \
--url https://vsi-api.shouqianba.com/{接口路径} \
--header 'Content-Type: application/json' \
--header 'Authorization: {sn} {sign}' \
--data-binary '{签名时使用的原始body}'
```
开发语言中的推荐实现是让“序列化、签名、发送”共用同一个字符串变量。
## 签名错误排查
按以下顺序检查:
- 当前接口是否选择了正确的`sn`和`key`。
- `Authorization`中的序列号与签名之间是否只有一个半角空格。
- 签名时的`body`是否与网络实际发送内容逐字节一致。
- 请求正文是否使用UTF-8编码。
- 签到是否已经更新`terminal_key`,但部分服务节点仍使用旧密钥。
- 终端参数是否错误地绑定到其他门店或设备。
- 日志是否只记录签名输入的哈希或脱敏信息,避免为了排错泄露密钥。
## 特殊接口
- 公众号与内部H5使用的**[跳转支付接口](https://open.shouqianba.com/api-docs/payment/142)**按照页面参数排序、拼接和签名,不能直接套用标准JSON请求签名。
- **[MiniPayPro插件支付接口](https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx55540b288c5ce319&token=930559648&lang=zh_CN)**按照插件文档生成调用参数。
- 插件场景中的激活、签到、查询和退款仍遵循标准接口签名。