添加 README 文档
This commit is contained in:
parent
071aaf4a67
commit
73678c3b41
|
|
@ -0,0 +1,421 @@
|
|||
# **蓝色兄弟营销开放API V3**
|
||||
|
||||
## 接入流程
|
||||
|
||||
1. **注册开发应用账号**:联系平台商务或技术支持,提交接入申请。
|
||||
2. **获取应用接入信息**:创建应用成功后,可获取应用 ID、应用私钥配置要求、平台公钥及业务加密 Key。
|
||||
3. **阅读接口文档**:仔细阅读本文档中的接口说明,确认请求加密、签名、响应解密方式。
|
||||
4. **联调测试**:在正式使用前,完成单发、查询、作废、批量、异常场景验证。
|
||||
|
||||
### 环境配置
|
||||
|
||||
测试环境地址:https://gateway.dev.cdlsxd.cn
|
||||
|
||||
正式环境地址:https://market.api.86698.cn
|
||||
|
||||
### 测试参数
|
||||
|
||||
# 客户应用id
|
||||
app\_id: "xxx"
|
||||
# 应用客户私钥,用于请求签名
|
||||
private\_key: "xxx"
|
||||
# 应用平台公钥,用于平台响应或回调验签
|
||||
public\_key: "xxx"
|
||||
# 业务参数加密key
|
||||
key: "xxxx"
|
||||
# 活动编号
|
||||
activity\_no: "xxxx"
|
||||
# 签名类型
|
||||
sign\_type: "RSA"
|
||||
|
||||
## 概述
|
||||
|
||||
### v1 接入说明
|
||||
|
||||
v1 版本统一采用 ciphertext 传输业务报文,默认接入方式与现有开放 API 保持一致。
|
||||
|
||||
### 业务参数
|
||||
|
||||
将业务参数去掉“零”值的参数再由小到大按照字母排序再转成json字符串得到plaintext
|
||||
再使用应用key将plaintext字符串加密[aes(ECB模式)/sm4(CBC模式)]得到加密业务参数ciphertext
|
||||
|
||||
### 签名规则
|
||||
|
||||
拼接签名字符串:分配给开发者的应用ID + 发送请求的时间 + 加密业务参数
|
||||
使用私钥将拼接待签名字符串生成签名字符串
|
||||
|
||||
### 回调验签
|
||||
|
||||
获取header头里面的签名信息
|
||||
获取body里面的业务参数data
|
||||
将业务参数data去掉“零”值的参数再由小到大按照字母排序再转成json字符串得到plaintext
|
||||
再使用应用key将plaintext字符串加密[aes/sm4]得到加密得到ciphertext
|
||||
拼接签名字符串:分配给开发者的应用ID + 发送请求的时间 + ciphertext
|
||||
使用应用公钥验签
|
||||
|
||||
备注:相关业务参数加密规则,验签demo等请联系平台技术人员
|
||||
|
||||
### 请求模式
|
||||
|
||||
v1 统一采用 Header 鉴权模式:
|
||||
|
||||
* Header 传:Appid、Timestamp、Sign
|
||||
* Body 传:ciphertext
|
||||
|
||||
### 响应说明
|
||||
|
||||
v1 统一采用严格密文响应模式,业务响应数据通过 ciphertext 返回。
|
||||
|
||||
### 时间戳规则
|
||||
|
||||
时间格式:yyyy-MM-dd HH:mm:ss
|
||||
请求时间与服务端时间误差不能超过 3 分钟
|
||||
|
||||
### SDK
|
||||
|
||||
开发者可参考以下 SDK:
|
||||
|
||||
// Go
|
||||
https://gitee.com/chengdu\_blue\_brothers/ymt-openapi-go-sdk.git
|
||||
// Java
|
||||
https://codeup.aliyun.com/lsxd/marketing/ymt-openapi-java-sdk.git
|
||||
|
||||
### 公共 Header 请求参数
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | **示例值** |
|
||||
| Appid | string | 分配给开发者的应用 ID | 123456 |
|
||||
| Timestamp | string | 发送请求的时间,格式 yyyy-MM-dd HH:mm:ss | 2026-06-22 15:30:00 |
|
||||
| Sign | string | 请求签名串 | 详见 SDK 示例 |
|
||||
| Content-Type | string | 请求数据格式 | application/json |
|
||||
|
||||
#### 公共 Header 请求参数示例
|
||||
|
||||
{
|
||||
"Sign": ["签名字符串"],
|
||||
"Appid": ["应用ID"],
|
||||
"Timestamp": ["请求时间"],
|
||||
"Content-Type": ["application/json"]
|
||||
}
|
||||
|
||||
### 公共请求参数
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | **示例值** |
|
||||
| ciphertext | string | 请求业务参数加密串 | 详见 SDK 示例 |
|
||||
|
||||
#### 公共请求参数示例
|
||||
|
||||
{
|
||||
"ciphertext": "加密后的业务报文"
|
||||
}
|
||||
|
||||
### 公共响应参数
|
||||
|
||||
| | | |
|
||||
| --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** |
|
||||
| code | int32 | 200 成功 |
|
||||
| message | string | 请求描述 |
|
||||
| reason | string | 错误原因,错误时返回 |
|
||||
| data.ciphertext | string | 业务响应加密串 |
|
||||
|
||||
### 公共错误码
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **code状态码** | **reason** | **错误原因** | **解决** |
|
||||
| 500 | PANIC/其它 | 系统错误 | 联系平台处理 |
|
||||
| 400 | INVALID\_PAYLOAD | 请求外壳格式错误 | 请检查请求 JSON 结构 |
|
||||
| 400 | MISSING\_PARAM | 缺少必要参数 | 请检查 app\_id、timestamp、sign、ciphertext |
|
||||
| 400 | INVALID\_TIMESTAMP | 时间格式错误 | 请检查时间格式 |
|
||||
| 400 | DECRYPT\_FAILED | 业务参数解密失败 | 请检查加密方式与密钥 |
|
||||
| 401 | APP\_NOT\_FOUND | 应用不存在 | 请检查应用 ID |
|
||||
| 401 | INVALID\_SIGNATURE | 签名错误 | 请检查签名串与私钥 |
|
||||
| 401 | EXPIRED\_TIMESTAMP | 请求已过期 | 请检查客户端时间 |
|
||||
| 429 | DUPLICATE\_REQUEST | 重复请求,请稍后重试 | 请避免短时间内重复提交同一业务号 |
|
||||
|
||||
### 业务错误码[汇总]
|
||||
|
||||
备注:若出现其它未知状态码,请联系平台技术人员。
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **code状态码** | **reason** | **错误原因** | **解决** |
|
||||
| 401 | ACTIVITY\_NOT\_AUTH | 活动未授权 | 请检查活动授权状态 |
|
||||
| 401 | MERCHANT\_NOT\_EXIST | 客户不存在 | 请检查客户是否存在 |
|
||||
| 401 | MERCHANT\_NOT\_AUTH | 客户冻结 | 请检查客户授权状态 |
|
||||
| 401 | MERCHANT\_APP\_INCOMPLETE | 客户应用配置未完善 | 请检查客户应用配置 |
|
||||
| 401 | MERCHANT\_APP\_NOT\_AUTH | 应用不存在或未授权 | 请检查客户应用授权状态 |
|
||||
| 403 | ACTIVITY\_EXPIRE | 活动已结束 | 请检查活动是否有效 |
|
||||
| 403 | ACTIVITY\_OUT\_OF\_STOCK | 活动剩余量不足 | 请检查活动库存 |
|
||||
| 404 | ACTIVITY\_NOT\_EXIST | 活动不存在 | 请检查活动编号 |
|
||||
| 404 | MERCHANT\_ORDER\_NOT\_EXIST | 订单不存在 | 请检查交易号或外部业务号 |
|
||||
| 404 | KEY\_NOT\_EXIST | key码不存在 | 请检查订单信息 |
|
||||
| 400 | PARAM\_FAIL | 参数错误 | 请检查业务参数 |
|
||||
| 400 | PARAM\_DECRYPT\_FAIL | 明文参数格式错误 | 请检查密文解密后的业务报文 |
|
||||
|
||||
### 获取券码
|
||||
|
||||
* 请求方式:POST
|
||||
* Content-Type:application/json
|
||||
* 请求路由:/openapi/v1/key/order
|
||||
|
||||
#### 业务请求参数
|
||||
|
||||
| | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
|
||||
| out\_biz\_no | string | 外部业务号,幂等 | M | 123456 |
|
||||
| activity\_no | string | 活动编号 | M | ACT20260622001 |
|
||||
| account | string | 账号,按活动类型透传 | N | 18666666666 |
|
||||
| notify\_url | string | 回调通知地址 | N | https://notify.example.com/openapi |
|
||||
|
||||
#### 业务响应参数(解密后)
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | 是否必填 | **描述** |
|
||||
| out\_biz\_no | string | M | 外部业务号 |
|
||||
| trade\_no | string | M | 交易号 |
|
||||
| key | string | N | 卡密 |
|
||||
| url | string | N | 链接型活动返回短链接,key/url 不会同时为空 |
|
||||
| valid\_begin\_time | string | N | 生效时间 |
|
||||
| valid\_end\_time | string | N | 失效时间 |
|
||||
| usable\_num | uint32 | M | 可用次数 |
|
||||
| usage\_num | uint32 | M | 已使用次数 |
|
||||
| status | uint32 | M | 状态:1 正常,2 已核销,3 已作废 |
|
||||
| settlement\_price | float | N | 结算价 |
|
||||
| account | string | N | 上报账号 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
明文业务参数:
|
||||
|
||||
{
|
||||
"out\_biz\_no": "order\_001",
|
||||
"activity\_no": "ACT20260622001",
|
||||
"account": "18666666666",
|
||||
"notify\_url": "https://notify.example.com/openapi"
|
||||
}
|
||||
|
||||
请求体示例:
|
||||
|
||||
{
|
||||
"ciphertext": "加密后的业务报文"
|
||||
}
|
||||
|
||||
#### 响应示例
|
||||
|
||||
异常
|
||||
|
||||
{
|
||||
"code": 401,
|
||||
"message": "Signature verification failed",
|
||||
"reason": "INVALID\_SIGNATURE"
|
||||
}
|
||||
|
||||
成功
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"ciphertext": "加密后的响应报文"
|
||||
},
|
||||
"message": "成功"
|
||||
}
|
||||
|
||||
解密后示例
|
||||
|
||||
{
|
||||
"out\_biz\_no": "order\_001",
|
||||
"trade\_no": "7251449503000383488",
|
||||
"key": "aZKdU9BymzR6qGRzJM",
|
||||
"url": "",
|
||||
"valid\_begin\_time": "2026-06-22 15:30:00",
|
||||
"valid\_end\_time": "2026-12-31 23:59:59",
|
||||
"usable\_num": 1,
|
||||
"usage\_num": 0,
|
||||
"status": 1,
|
||||
"settlement\_price": 9.9,
|
||||
"account": "18666666666"
|
||||
}
|
||||
|
||||
### 券码查询
|
||||
|
||||
* 请求方式:POST
|
||||
* Content-Type:application/json
|
||||
* 请求路由:/openapi/v1/key/query
|
||||
|
||||
#### 业务请求参数
|
||||
|
||||
| | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
|
||||
| out\_biz\_no | string | 外部业务号,与 trade\_no 二选一 | N | order\_001 |
|
||||
| trade\_no | string | 交易号,与 out\_biz\_no 二选一 | N | 7251449503000383488 |
|
||||
|
||||
#### 业务响应参数
|
||||
|
||||
与“获取券码”响应参数一致。
|
||||
|
||||
#### 响应示例
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"out\_biz\_no": "order\_001",
|
||||
"trade\_no": "7251449503000383488",
|
||||
"key": "aZKdU9BymzR6qGRzJM",
|
||||
"url": "",
|
||||
"valid\_begin\_time": "2026-06-22 15:30:00",
|
||||
"valid\_end\_time": "2026-12-31 23:59:59",
|
||||
"usable\_num": 1,
|
||||
"usage\_num": 0,
|
||||
"status": 1,
|
||||
"settlement\_price": 9.9,
|
||||
"account": "18666666666",
|
||||
"ciphertext": ""
|
||||
},
|
||||
"message": "成功"
|
||||
}
|
||||
|
||||
### 券码作废
|
||||
|
||||
* 请求方式:POST
|
||||
* Content-Type:application/json
|
||||
* 请求路由:/openapi/v1/key/discard
|
||||
|
||||
#### 业务请求参数
|
||||
|
||||
| | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
|
||||
| out\_biz\_no | string | 外部业务号,与 trade\_no 二选一 | N | order\_001 |
|
||||
| trade\_no | string | 交易号,与 out\_biz\_no 二选一 | N | 7251449503000383488 |
|
||||
|
||||
#### 业务响应参数
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | 是否必填 | **描述** |
|
||||
| out\_biz\_no | string | M | 外部业务号 |
|
||||
| trade\_no | string | M | 交易号 |
|
||||
| status | uint32 | M | 3 表示已作废 |
|
||||
|
||||
#### 响应示例
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"out\_biz\_no": "order\_001",
|
||||
"trade\_no": "7251449503000383488",
|
||||
"status": 3,
|
||||
"ciphertext": ""
|
||||
},
|
||||
"message": "成功"
|
||||
}
|
||||
|
||||
### 批量发卡
|
||||
|
||||
* 请求方式:POST
|
||||
* Content-Type:application/json
|
||||
* 请求路由:/openapi/v1/key/batch\_order
|
||||
|
||||
#### 业务请求参数
|
||||
|
||||
| | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
|
||||
| out\_biz\_no | string | 外部业务号,幂等 | M | batch\_001 |
|
||||
| activity\_no | string | 活动编号 | M | ACT20260622001 |
|
||||
| number | int32 | 发卡数量 | M | 100 |
|
||||
| notify\_url | string | 回调通知地址 | N | https://notify.example.com/openapi |
|
||||
|
||||
#### 业务响应参数
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | 是否必填 | **描述** |
|
||||
| out\_biz\_no | string | M | 外部业务号 |
|
||||
| trade\_no | string | M | 交易号 |
|
||||
| status | string | M | 任务状态,初始返回 processing |
|
||||
|
||||
#### 响应示例
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"ciphertext": "加密后的响应报文"
|
||||
},
|
||||
"message": "成功"
|
||||
}
|
||||
|
||||
解密后示例:
|
||||
|
||||
{
|
||||
"out\_biz\_no": "batch\_001",
|
||||
"trade\_no": "7251449503000383499",
|
||||
"status": "processing"
|
||||
}
|
||||
|
||||
### 批量查询
|
||||
|
||||
* 请求方式:POST
|
||||
* Content-Type:application/json
|
||||
* 请求路由:/openapi/v1/key/batch\_query
|
||||
|
||||
#### 业务请求参数
|
||||
|
||||
| | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
|
||||
| out\_biz\_no | string | 外部业务号,与 trade\_no 二选一 | N | batch\_001 |
|
||||
| trade\_no | string | 交易号,与 out\_biz\_no 二选一 | N | 7251449503000383499 |
|
||||
|
||||
#### 业务响应参数
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| **字段名称** | **类型** | 是否必填 | **描述** |
|
||||
| out\_biz\_no | string | M | 外部业务号 |
|
||||
| trade\_no | string | M | 交易号 |
|
||||
| status | string | M | processing / success / failed |
|
||||
| download\_url | string | N | 批量任务成功后返回下载地址 |
|
||||
| zip\_password | string | N | 批量任务成功后返回压缩包密码 |
|
||||
|
||||
#### 响应示例
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"ciphertext": "加密后的响应报文"
|
||||
},
|
||||
"message": "成功"
|
||||
}
|
||||
|
||||
解密后示例:
|
||||
|
||||
{
|
||||
"out\_biz\_no": "batch\_001",
|
||||
"trade\_no": "7251449503000383499",
|
||||
"status": "success",
|
||||
"download\_url": "https://oss.example.com/openapi\\_7251449503000383499.zip",
|
||||
"zip\_password": "123456"
|
||||
}
|
||||
|
||||
### 高级能力说明
|
||||
|
||||
如客户有特殊签名套件、加密套件适配需求,可通过商户应用 GatewayConfig 做高级配置。
|
||||
|
||||
默认接入无需关注该项;如需启用,请联系平台技术人员对接。
|
||||
|
||||
### 联调建议
|
||||
|
||||
1. 先验证单发、查询、作废三个基础接口。
|
||||
2. 再验证批量发卡与批量查询。
|
||||
3. 重点验证响应密文解密结果是否正确。
|
||||
4. 批量发卡需验证 processing -> success/failed 状态流转。
|
||||
5. 批量成功后需验证 download\_url、zip\_password 是否可用。
|
||||
Loading…
Reference in New Issue