文档概述
- 接口总数:5个
- 环境配置:
- 测试参数:
- app_id: "xxx"
- private_key: "xxx"(应用客户私钥,用于请求签名)
- public_key: "xxx"(应用平台公钥,用于平台响应或回调验签)
- key: "xxxx"(业务参数加密key)
- activity_no: "xxxx"(活动编号)
- sign_type: "RSA"
认证与安全
| 字段名称 |
类型 |
描述 |
示例值 |
| 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 |
公共请求参数
| 字段名称 |
类型 |
描述 |
示例值 |
| ciphertext |
string |
请求业务参数加密串 |
详见 SDK 示例 |
公共响应参数
| 字段名称 |
类型 |
描述 |
| code |
int32 |
200 成功 |
| message |
string |
请求描述 |
| reason |
string |
错误原因,错误时返回 |
| data.ciphertext |
string |
业务响应加密串 |
业务参数加密规则
- 将业务参数去掉“零”值的参数,再由小到大按照字母排序,转成json字符串得到plaintext
- 使用应用key将plaintext字符串加密,支持两种模式:aes(ECB模式)/sm4(CBC模式),得到加密业务参数ciphertext
签名规则
- 拼接签名字符串:分配给开发者的应用ID + 发送请求的时间 + 加密业务参数
- 使用应用私钥将拼接待签名字符串生成签名字符串
回调验签规则
- 获取header头里面的签名信息
- 获取body里面的业务参数data
- 将业务参数data去掉“零”值的参数,再由小到大按照字母排序,转成json字符串得到plaintext
- 使用应用key将plaintext字符串加密[aes/sm4]得到加密得到ciphertext
- 拼接签名字符串:分配给开发者的应用ID + 发送请求的时间 + ciphertext
- 使用应用公钥验签
时间戳规则
时间格式:yyyy-MM-dd HH:mm:ss,请求时间与服务端时间误差不能超过3分钟
接口列表
接口 1:获取券码
- 路径:/openapi/v1/key/order
- 方法:POST
- 描述:申请单个券码/权益,支持幂等
请求参数(业务明文)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
是 |
外部业务号,幂等 |
| activity_no |
string |
是 |
活动编号 |
| account |
string |
否 |
账号,按活动类型透传 |
| notify_url |
string |
否 |
回调通知地址 |
响应参数(解密后)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
是 |
外部业务号 |
| trade_no |
string |
是 |
交易号 |
| key |
string |
否 |
卡密 |
| url |
string |
否 |
链接型活动返回短链接,key/url 不会同时为空 |
| valid_begin_time |
string |
否 |
生效时间 |
| valid_end_time |
string |
否 |
失效时间 |
| usable_num |
uint32 |
是 |
可用次数 |
| usage_num |
uint32 |
是 |
已使用次数 |
| status |
uint32 |
是 |
状态:1 正常,2 已核销,3 已作废 |
| settlement_price |
float |
否 |
结算价 |
| account |
string |
否 |
上报账号 |
示例
{
"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"
}
接口 2:券码查询
- 路径:/openapi/v1/key/query
- 方法:POST
- 描述:查询已申请的券码详情
请求参数(业务明文)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
否 |
外部业务号,与 trade_no 二选一 |
| trade_no |
string |
否 |
交易号,与 out_biz_no 二选一 |
响应参数(解密后)
与“获取券码”响应参数完全一致。
示例
{
"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": "成功"
}
接口 3:券码作废
- 路径:/openapi/v1/key/discard
- 方法:POST
- 描述:作废已申请的券码
请求参数(业务明文)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
否 |
外部业务号,与 trade_no 二选一 |
| trade_no |
string |
否 |
交易号,与 out_biz_no 二选一 |
响应参数(解密后)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
是 |
外部业务号 |
| trade_no |
string |
是 |
交易号 |
| status |
uint32 |
是 |
3 表示已作废 |
示例
{
"code": 200,
"data": {
"out_biz_no": "order_001",
"trade_no": "7251449503000383488",
"status": 3,
"ciphertext": ""
},
"message": "成功"
}
接口 4:批量发卡
- 路径:/openapi/v1/key/batch_order
- 方法:POST
- 描述:批量申请多个券码,返回异步任务状态
请求参数(业务明文)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
是 |
外部业务号,幂等 |
| activity_no |
string |
是 |
活动编号 |
| number |
int32 |
是 |
发卡数量 |
| notify_url |
string |
否 |
回调通知地址 |
响应参数(解密后)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
是 |
外部业务号 |
| trade_no |
string |
是 |
交易号 |
| status |
string |
是 |
任务状态,初始返回 processing |
示例
{
"code": 200,
"data": {
"ciphertext": "加密后的响应报文"
},
"message": "成功"
}
{
"out_biz_no": "batch_001",
"trade_no": "7251449503000383499",
"status": "processing"
}
接口 5:批量查询
- 路径:/openapi/v1/key/batch_query
- 方法:POST
- 描述:查询批量发卡任务的状态和结果
请求参数(业务明文)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
否 |
外部业务号,与 trade_no 二选一 |
| trade_no |
string |
否 |
交易号,与 out_biz_no 二选一 |
响应参数(解密后)
| 参数名 |
类型 |
必填 |
说明 |
| out_biz_no |
string |
是 |
外部业务号 |
| trade_no |
string |
是 |
交易号 |
| status |
string |
是 |
processing / success / failed |
| download_url |
string |
否 |
批量任务成功后返回下载地址 |
| zip_password |
string |
否 |
批量任务成功后返回压缩包密码 |
示例
{
"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"
}
错误码
| 错误码 |
说明 |
处理建议 |
| 500 |
PANIC/其它 系统错误 |
联系平台处理 |
| 400 |
INVALID_PAYLOAD 请求外壳格式错误 |
请检查请求 JSON 结构 |
| 400 |
MISSING_PARAM 缺少必要参数 |
请检查 app_id、timestamp、sign、ciphertext |
| 400 |
INVALID_TIMESTAMP 时间格式错误 |
请检查时间格式 |
| 400 |
DECRYPT_FAILED 业务参数解密失败 |
请检查加密方式与密钥 |
| 400 |
PARAM_FAIL 参数错误 |
请检查业务参数 |
| 400 |
PARAM_DECRYPT_FAIL 明文参数格式错误 |
请检查密文解密后的业务报文 |
| 401 |
APP_NOT_FOUND 应用不存在 |
请检查应用 ID |
| 401 |
INVALID_SIGNATURE 签名错误 |
请检查签名串与私钥 |
| 401 |
EXPIRED_TIMESTAMP 请求已过期 |
请检查客户端时间 |
| 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码不存在 |
请检查订单信息 |
| 429 |
DUPLICATE_REQUEST 重复请求,请稍后重试 |
请避免短时间内重复提交同一业务号 |
回调通知
平台会将异步任务结果推送到请求中指定的notify_url地址,回调验签规则参考上述认证与安全章节的回调验签流程。