# 蓝色兄弟营销开放API
## 接入流程
1. **注册开发应用账号**:联系平台商务或技术支持,提交接入申请。
2. **获取API密钥**:创建应用成功后,可以在应用详情页获取到API密钥,密钥生成sdk中有集成。
3. **阅读接口文档**:仔细阅读本文档中的API接口说明,了解如何使用API。
4. **集成API**:根据接口文档,将API集成到你的应用中。
5. **测试与验证**:在正式使用前,进行充分的测试以确保API的正确性和稳定性。
### 环境配置
测试环境地址:https://gateway.dev.cdlsxd.cn
正式环境地址:https://market.api.86698.cn
### 测试参数
```YAML
#客户应用id
app_id: "OP001"
#应用客户私钥,正式使用请客户自行保存好私钥,将公钥给到平台
private_key: "xxx"
#应用平台公钥,用于回调验签等
public_key: "xxx"
#业务参数加密key
key: "xxxx"
#活动编号 串码-1734342908 链接-1742884852
activity_no: "xxxx"
#签名类型RSA/SM,目前只开放RSA
sign_type: "RSA"
```
## 概述
### 业务参数
```Plain
将业务参数去掉“零”值的参数再由小到大按照字母排序再转成json字符串得到plaintext
再使用应用key将plaintext字符串加密[aes/sm4]得到加密业务参数ciphertext
```
### 签名规则
```Plain
拼接签名字符串:分配给开发者的应用ID + 发送请求的时间 + 加密业务参数
使用私钥将拼接待签名字符串生成签名字符串
```
### 回调验签
```Plain
获取header头里面的签名信息
获取body里面的业务参数data
将业务参数data去掉“零”值的参数再由小到大按照字母排序再转成json字符串得到plaintext
再使用应用key将plaintext字符串加密[aes/sm4]得到加密得到ciphertext
拼接签名字符串:分配给开发者的应用ID + 发送请求的时间 + ciphertext
使用应用公钥验签
```
备注:相关业务参数加密规则,验签demo等请联系平台技术人员
### SDK
开发者可参考该sdk
```markdown
// go
gitee.com/lansexiongdi/ymt
// Java
https://codeup.aliyun.com/lsxd/marketing/ymt-openapi-java-sdk.git
```
### 公共headers请求参数
| **字段名称** | **类型** | **描述** | **示例值** |
| --- | --- | --- | --- |
| Appid | string | 分配给开发者的应用ID | 123456 |
| Sign-type | string | 签名类型RSA/SM目前暂支持RSA | RSA |
| Timestamp | string | 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss" | 2014-07-24 03:07:50 |
| Sign | string | 商户请求参数的签名串 | 详见sdk示例 |
#### 公共headers请求参数示例
```json
{
"Sign": ["签名字符串"],
"Appid": ["应用ID"],
"Sign-Type": ["签名类型"],
"Timestamp": ["请求时间"],
"Content-Type": ["请求数据格式"]
}
```
### 公共请求参数
| ciphertext | string | 请求参数的集合加密字符串 | 详见sdk示例 |
| --- | --- | --- | --- |
### 公共响应参数
| **字段名称** | **类型** | **描述** |
| --- | --- | --- |
| code | int32 | 200成功 |
| message | string | 请求描述 |
| reason | string | 错误原因,错误是返回 |
| data | object | 业务响应参数,成功时返回 |
### 公共错误码
| code**状态码** | **reason** | **错误原因** | **解决** |
| --- | --- | --- | --- |
| 500 | PANIC/其它 | 系统错误 | 联系平台处理 |
| 400 | SIGNATURE\_FAIL | 签名错误 | 请检查应用签名密钥是否正确 |
| | SDK\_INI\_FAIL | sdk错误 | 请检查应用配置信息是否完整 |
| | PARAM\_FAIL | 参数错误 | 请检查业务参数是否正确 |
| | PARAM\_DECRYPT\_FAIL | 参数错误 | 请检查业务参数加密是否正确 |
### 业务错误码\[汇总\]
备注:若出现其它未知状态码,请联系平台技术人员
| code**状态码** | **reason** | **错误原因** | **解决** |
| --- | --- | --- | --- |
| 503 | KEY\_CREATE\_FAIL | 服务端异常 | 联系平台处理 |
| | MERCHANT\_ORDER\_CREATE\_FAIL | 服务端异常 | 联系平台处理 |
| | MERCHANT\_ORDER\_DISCARD\_FAIL | 服务端异常 | 联系平台处理 |
| | MERCHANT\_ORDER\_DISCARD\_MQ\_FAIL | 服务端异常 | 联系平台处理 |
| 401 | ACTIVITY\_NOT\_AUTH | 活动未授权 | 请检查活动授权状态 |
| | MERCHANT\_NOT\_EXIST | 客户不存在 | 请检查客户是否存在 |
| | MERCHANT\_NOT\_AUTH | 客户冻结 | 请检查客户授权状态 |
| | MERCHANT\_APP\_INCOMPLETE | 客户应用配置未完善 | 请检查客户应用配置 |
| | MERCHANT\_APP\_NOT\_AUTH | 应用不存在 | 请检查客户应用授权状态 |
| 403 | ACTIVITY\_EXPIRE | 活动已结束 | 请检查活动是否有效 |
| | ACTIVITY\_NOT\_AUTH | 1、活动已作废
2、活动待审核
3、活动已驳回
4、活动暂停中
5、活动已失效
6、活动编辑中 | 请检查活动状态 |
| | ACTIVITY\_OUT\_OF\_STOCK | 活动Key码剩余量已不足 | 请检查活动key码总量 |
| 404 | KEY\_NOT\_EXIST | key码不存在 | 请检查key码订单是否有误 |
| | ACTIVITY\_NOT\_EXIST | 活动不存在 | 请检查活动编号是否有误 |
| | MERCHANT\_NOT\_EXIST | 客户不存在 | 请检查客户应用app\_id是否有误 |
| | MERCHANT\_APP\_NOT\_EXIST | 客户应用不存在 | 请检查客户应用app\_id是否有误 |
| | MERCHANT\_ORDER\_NOT\_EXIST | 客户key码记录不存在 | 请检查交易号/外部交易号是否有误 |
| | MERCHANT\_APP\_INCOMPLETE | 客户应用信息未完善 | 请检查客户应用信息是否完善 |
| | MERCHANT\_ORDER\_NOT\_EXIST | 1、交易号不存在
2、外部业务号不存在
3、appId不匹配 | 请检查入参请求交易号/业务号 |
### 获取券码
* 请求方式:`POST`
* Content-Type: application/json
* 请求路由:/openapi/v1/key/order
#### 业务请求参数
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
| --- | --- | --- | --- | --- |
| out\_biz\_no | string | 外部业务号 长度2~32位,幂等 | M | 123456 |
| activity\_no | string | 活动编号 长度32位内 | M | 123456 |
| number | int | 数量,只支持1 | M | 1 |
| account | string | 账号,手机号需短信验证才能兑换,卡密/直充账号领取为该账号 | N | 18666666666 |
| notify\_url | string | 回调通知地址 | N | http://notify.com |
#### 业务响应参数
| **字段名称** | **类型** | 是否必填 | **描述** |
| --- | --- | --- | --- |
| out\_biz\_no | string | M | 外部业务号 |
| trade\_no | string | M | 交易号 |
| key | string | N | key码 |
| usable\_num | uint32 | M | 总兑换次数 |
| status | uint8 | M | 状态 1:正常 2:已核销 3:已作废 |
| url | string | N | 短链接,key/url 不会同时为空 |
| valid\_begin\_time | string | M | key码有效期 |
| valid\_end\_time | string | M | key码有效期 |
| usage\_time | string | N | 核销时间,已核销时返回 |
| discard\_time | string | N | 作废时间,作废时返回 |
| usable\_num | uint32 | M | 可兑换次数 |
| account | string | N | 获取券码上报账号 |
```json
{
"ciphertext": "HJYByD2RVGJgqaXInWUr3QOWukCwT9x8M6hv0wbRBHs+K1WDZ3axg8/lRubhA=="
}
```
#### 响应示例
异常
```JSON
{
"code": 404,
"message": "应用不存在",
"reason": "MERCHANT_APP_NOT_EXIST"
}
```
成功
```JSON
{
"code": 200,
"data": {
"out_biz_no": "lzm1",
"key": "aZKdU9BymzR6qGRzJM",
"trade_no": "7251449503000383488",
"url": "https://gateway.dev.cdlsxd.cn/yxh5/aZKdU9BymzR6qGRzJM",
"valid_begin_time": "2024-10-14 11:20:01",
"valid_end_time": "2026-04-30 23:59:59",
"status": 1,
"usable_num": 10,
},
"message": "成功"
}
```
#### 接口调用流程

### 券码查询
* 请求方式:`POST`
* Content-Type: application/json
* 请求路由:/openapi/v1/key/query
#### 业务请求参数
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
| --- | --- | --- | --- | --- |
| out\_biz\_no | string | 外部业务号 out\_biz\_no/trade\_no二选一 | N | 123456 |
| trade\_no | string | 交易号 out\_biz\_no/trade\_no二选一, 若不为空则优先使用 | N | 123456 |
#### 业务响应参数
| **字段名称** | **类型** | 是否必填 | **描述** |
| --- | --- | --- | --- |
| out\_biz\_no | string | M | 外部业务号 |
| trade\_no | string | M | 交易号 |
| key | string | N | key码 |
| usable\_num | uint32 | M | 总兑换次数 |
| usage\_num | uint32 | M | 已兑换次数 key码使用后返回 |
| status | uint8 | M | 状态 1:正常 2:已核销 3:已作废4:已过期 |
| url | string | N | 短链接 key/url 不会同时为空 |
| valid\_begin\_time | string | M | key码有效期 |
| valid\_end\_time | string | M | key码有效期 |
| usage\_time | string | N | 最后一次核销时间 |
| discard\_time | string | N | 作废时间 |
| account | string | N | 获取券码上报账号 |
#### 请求示例
```JSON
{
"ciphertext": "U4EiooGkfS+XqnUPQ/1ZDAxjgCAJap4/vDqRiyfLCdU0Xu1fekAGq8tEPuTtjKyEw=="
}
```
#### 响应示例
异常
```JSON
{
"code": 404,
"message": "应用不存在",
"reason": "MERCHANT_APP_NOT_EXIST"
}
```
成功
```JSON
{
"code": 200,
"data": {
"out_biz_no": "lzm1",
"key": "aZKdU9BymzR6qGRzJM",
"trade_no": "7251449503000383488",
"url": "https://gateway.dev.cdlsxd.cn/yxh5/aZKdU9BymzR6qGRzJM",
"valid_begin_time": "2024-10-14 11:20:01",
"valid_end_time": "2026-04-30 23:59:59",
"status": 1,
"usable_num": 10,
"usage_num": 5,
},
"message": "成功"
}
```
#### 接口调用流程

### 券码作废
* 请求方式:`POST`
* Content-Type: application/json
* 请求路由:/openapi/v1/key/discard
* 只能作废:待使用、已过期券码
#### 业务参数
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
| --- | --- | --- | --- | --- |
| out\_biz\_no | string | 外部业务号 out\_biz\_no/trade\_no二选一 | N | 123456 |
| trade\_no | string | 交易号 out\_biz\_no/trade\_no二选一 若不为空,则优先使用 | N | 123456 |
#### 请求示例
```JSON
{
"ciphertext": "U4EiooGkfS+XqnUPQ/1ZDAxjgCAJap4/vDqRiyfLCdU0Xu1fekAGq8tEPuTtjKyEw=="
}
```
#### 响应示例
异常
```JSON
{
"code": 404,
"message": "应用不存在",
"reason": "MERCHANT_APP_NOT_EXIST"
}
```
成功
```JSON
{
"code": 200,
"data": {},
"message": "成功"
}
```
#### 接口调用流程

### 券码状态通知
* 请求方式:`POST`
* Content-Type: application/json
* 通知地址:客户获取券码上报地址,未上报则使用应用设置回调通知地址
#### 公共参数
| **字段名称** | **类型** | **描述** | 是否必填 | **示例值** |
| --- | --- | --- | --- | --- |
| data | object | 请求业务参数 | M | 详见请求业务参数 |
#### 业务参数data
| **字段名称** | **类型** | 是否必填 | **描述** |
| --- | --- | --- | --- |
| notify\_id | string | M | 回调通知id |
| out\_biz\_no | string | M | 外部业务号 |
| trade\_no | string | M | 交易号 |
| key | string | N | key码 |
| usable\_num | uint32 | M | 总兑换次数 |
| usage\_num | uint32 | M | 已兑换次数 当usable\_num=usage\_num时即为key码次数已使用完 |
| status | uint8 | M | 状态 1:正常 2:已核销 3:已作废 |
| url | string | N | 短链接,key/url 不会同时为空 |
| valid\_begin\_time | string | M | key码有效期 |
| valid\_end\_time | string | M | key码有效期 |
| usage\_time | string | N | 最后一次核销时间,有核销时会返回 |
| discard\_time | string | N | 作废时间,status=3时返回 |
| account | string | N | 获取券码上报账号 |
| order\_info | object | N | 格式{"order\_no":"123456","account":"1866666666","name":"张三"} |
#### 请求示例
```JSON
{
"data": {
"notify_id": "202603030015",
"out_biz_no": "883382742152257537",
"trade_no": "https://gateway.dev.cdlsxd.cn/yxh5/war3PPmrQzDVKv8M",
...
}
}
```
#### 响应示例
#### 响应重试策略
```Plain
非成功响应会进行重试,首次间隔120s,第二次后间隔240s,第三次间隔360s,大于5分钟后间隔5分钟,大于10分钟后间隔10分钟,超过120分钟后不再重试通知
```
* 商家/客户收到回调通知后需返回httpCode=200并且字符串"ok"作为响应