支付接口文档

API 接口文档

POST /api/code/create

创建码商支付订单。根据金额和支付平台匹配可用收款码账号,生成支付链接。

请求

请求方法POST
完整路径{server}/api/code/create
Content-Typeapplication/json

入参

字段类型必填说明
merIdString商户号
signString请求签名(用商户密钥对参数签名)
orderAmtString订单金额。必须为 10 的整数倍,否则返回 0005
payTypeString支付类型:scan(扫码)/ wap(H5)
payPlatString支付平台标识(如 alipaywxpay
orderTitleString订单标题
orderDescString订单描述
notifyUrlString异步通知地址(支付成功后回调)
callbackUrlString同步回调地址(支付完成后浏览器跳转)
merOrderNoString商户订单号(需唯一,重复返回 1002)
ipString客户端 IP
非空校验
Controller 层对所有字段做非空校验,任意字段为空则返回 9999 字段[xxx]长度有误,不会进入业务逻辑。
金额限制

签名规则

使用 MD5 签名算法。将除 sign 外的所有非空参数按字段名字母升序排列,拼接为 key=value&key=value 格式,末尾追加商户密钥,对整体字符串做 MD5 摘要。

签名步骤

  1. 收集所有请求参数,排除 sign 字段本身
  2. 排除值为 null 或空字符串的字段
  3. 按字段名字母升序排列(TreeMap 自然排序)
  4. 拼接为 key1=value1&key2=value2&...&keyn=valuen
  5. 末尾追加 &key=商户密钥
  6. 对整个字符串做 MD5,得到 sign

示例

假设商户密钥为 5BB0B8583BFB46E0941B61F11A5E96FA,请求参数如下:

// 1. 按字段名排序后拼接(排除 sign,非空值) callbackUrl=https://www.baidu.com&ip=192.168.1.1&merId=1000000905&merOrderNo=2019041838920928¬ifyUrl=https://www.baidu.com&orderAmt=100&orderDesc=测试订单&orderTitle=测试订单&payPlat=alipay&payType=scan // 2. 末尾追加商户密钥 ...&payType=scan&key=5BB0B8583BFB46E0941B61F11A5E96FA // 3. 对完整字符串做 MD5,得到 sign 值 sign = MD5("callbackUrl=https://...&payType=scan&key=5BB0B8583BFB46E0941B61F11A5E96FA")
注意

返回值

成功返回 CreateDTO(继承 BaseDTO),失败返回 BaseDTO

成功响应字段

字段类型说明
respCodeString响应码,0000 表示成功
respMsgString响应消息
payNoString系统支付订单号
merOrderNoString商户订单号
jumpUrlString支付跳转 URL,引导用户完成支付
realAmtString实际支付金额

成功示例

{ "respCode": "0000", "respMsg": "请求成功", "payNo": "202608121430251731234567", "merOrderNo": "MER20260812001", "jumpUrl": "https://example.com/codex/api/code/order?id=xxx", "realAmt": "100" }

失败示例

{ "respCode": "0004", "respMsg": "签名错误" }

错误码

respCoderespMsg触发条件
9999字段[{key}]长度有误Controller 层任意参数为空
0002商户不存在merId 未找到对应商户
0012商户已经被停用商户状态为 STOP
0004签名错误sign 与服务端计算结果不一致
0005订单金额格式错误金额非数字 或 非 10 的整数倍
0023最大金额不能超过{max}金额超过商户或系统最大值
0026最小金额不能小于{min}金额低于商户或系统最小值
1002订单号重复merOrderNo 已存在
0021订单并发超限每分钟订单数超过限制
0020暂无可用账号无匹配金额和支付平台的收款码账号
0001请求失败订单保存数据库失败

业务流程

  1. Controller 非空校验所有参数
  2. 验证商户存在(merId)
  3. 验证商户状态(未停用)
  4. 验证签名(用商户密钥重新签名比对)
  5. 验证金额格式(isMoney + isMultipleOfTen)
  6. 验证金额上下限(商户配置或默认 1~5000)
  7. 检查订单号是否重复
  8. 检查每分钟订单并发限制
  9. 匹配可用收款码账号(按金额 + 支付平台)
  10. 创建 CodeOrder 记录并保存
  11. 构建 CreateDTO 返回 jumpUrl / payNo / merOrderNo / realAmt

POST /api/code/query

查询码商订单状态。根据商户订单号获取订单支付状态及详情。

请求

请求方法POST
完整路径{server}/api/code/query
Content-Typeapplication/json

入参

字段类型必填说明
merIdString商户号
signString请求签名(签名规则同 create 接口)
merOrderNoString商户订单号
非空校验
Controller 层对所有字段做非空校验,任意字段为空则返回 9999 字段[xxx]长度有误,不会进入业务逻辑。

签名规则

create 接口完全一致。将除 sign 外的所有非空参数按字段名字母升序拼接,末尾追加商户密钥,做 MD5 摘要。

本接口签名字段仅 2 个(排除 sign 后):merIdmerOrderNo

// 签名串 merId=1000000905&merOrderNo=2019041838920928&key=5BB0B8583BFB46E0941B61F11A5E96FA // sign = MD5(上述字符串)

返回值

成功返回 OrderDTO(继承 BaseDTO),失败返回 BaseDTO

成功响应字段

字段类型说明
respCodeString响应码,0000 表示成功
respMsgString响应消息
payNoString系统支付订单号
merOrderNoString商户订单号
orderTitleString订单标题
orderDescString订单描述
payStatusString支付状态,见下表
payDateString支付时间(格式 yyyy-MM-dd HH:mm:ss,未支付时为 null)
orderAmtString订单金额
realAmtString实际支付金额

payStatus 状态值

说明
0初始状态(待支付)
1支付中
2支付成功
-1超时失败
-2未支付
-3金额未匹配
-4已收款未确认

成功示例

{ "respCode": "0000", "respMsg": "请求成功", "payNo": "202608121430251731234567", "merOrderNo": "MER20260812001", "orderTitle": "测试订单", "orderDesc": "测试订单", "payStatus": "2", "payDate": "2026-08-12 14:35:20", "orderAmt": "100", "realAmt": "100" }

失败示例

{ "respCode": "0018", "respMsg": "无此订单记录" }

错误码

respCoderespMsg触发条件
9999字段[{key}]长度有误Controller 层任意参数为空
0002商户不存在merId 未找到对应商户
0012商户已经被停用商户状态为 STOP
0004签名错误sign 与服务端计算结果不一致
0018无此订单记录merOrderNo 未找到对应订单

业务流程

  1. Controller 非空校验所有参数
  2. 验证商户存在(merId)
  3. 验证商户状态(未停用)
  4. 验证签名(用商户密钥重新签名比对)
  5. 根据 merOrderNo 查询订单
  6. 订单不存在返回 0018,存在则构建 OrderDTO 返回