可运行样例:/index.html · 静态副本:/doc.html · 判断成功:code === 200

0.通用约定

响应格式

所有 /api/* 接口均返回 JSON,HTTP 状态码一般为 200(以 body 内 code 为准)。

成功code === 200):

{
    "code": 200,
    "data": { },
    "msg": "请求成功"
}

开放 API 响应不含顶层 sign 字段;sign 仅出现在支付成功后的异步通知(见第 4 节)。

失败code !== 200):仅含 codemsg,无 data、无 sign

{
    "code": 400,
    "msg": "签名验证失败"
}
常见错误码
code 说明 示例 msg
200成功请求成功
400业务或签名错误签名验证失败、商户未配置支付通道、商户号有误…
422参数校验失败商户编号缺失、签名缺失…
500服务器异常(生产环境 msg 可能为 Server internal error)

对接时请用 code === 200 判断成功,不要依赖 msg 是否为空,也不要期待 code: 9999 等本系统未定义的码。

对接前置条件

完整对接需同时具备:商户号(shop_number)密钥(secret)、后台已为该商户关联并启用支付通道、可公网访问的 notify_url(接收 JSON 并响应 success)。仅密钥正确但无通道时,接口仍会报错。

API 基址:https://bs12guatou.131aiqa.xmxiawen.asia/api/*。可运行样例页:/index.html(form POST,勿复制页内商户号/密钥)。静态文档副本:/doc.html

用户跳转支付成功 ≠ 商户已收到异步通知;对账与发货请以异步通知/api/pay_result 为准。

最小对接步骤
  1. 确认后台已为商户勾选支付通道;向运营索取 shop_numbersecret
  2. 调用 /api/prices 获取 channels 与价格档位(档位支付时)。
  3. 调用 /api/pay(档位金额)或 /api/direct_pay(自定义金额),code===200 后跳转 data.pay_url
  4. 部署 notify_url:按 JSON 解析 body、按第 4/6 节验签、响应正文 success
  5. (可选)调用 /api/pay_result 查询订单状态。
请求与通知差异(必读)
项目开放 API(/api/*)异步通知(notify_url)
Content-Type推荐 application/x-www-form-urlencoded;亦支持 JSONapplication/json;charset=utf-8
验签字段shop_numbertimestampbiz_contentorder_snshop_numberpay_numberpay_resultpay_timeamountextra_data(非空时)
biz_content 签名须与实际 POST 中 JSON 字符串逐字一致(含字段顺序)不使用
amount请求中为下单意向金额订单实付金额;若启用随机扣减可能与 biz 中 amount 不同
1.获取价格信息

请求地址:
https://bs12guatou.131aiqa.xmxiawen.asia/api/prices

数据来源:本系统「企业数字化轻服务商城」上架商品(mall_products)。同价多商品在列表中合并为一个金额档位;发起 /api/pay 时系统在同价商品中随机选取名义服务。请求方式:POSTapplication/x-www-form-urlencodedapplication/json

请求参数
参数名 类型 必填 是否参与签名 参数说明
shop_number string 平台商户号
timestamp string 请求时间 格式20260722161934
sign string 签名字符串,签名方式参考下方签名/验签
请求返回
{
    "code": 200,
    "data": {
        "channels": [
            {
                "id": 1,
                "channel_name": "厦门夏玟",
                "channel_app_id": "2021006155697017"
            },
            {
                "id": 2,
                "channel_name": "宿州锐科信息科技发展有限公司",
                "channel_app_id": "2021xxxxxxxxxxxx"
            }
        ],
        "source": "mall",
        "prices": [
            {
                "key": "13",
                "amount": "99.00",
                "name": "网站安全检测基础版"
            },
            {
                "key": "24",
                "amount": "399.00",
                "name": "Nginx反向代理配置协助"
            }
        ]
    },
    "msg": "请求成功"
}
                    

key 为商品 ID(同价合并展示时为代表商品);支付时同价商品随机匹配。通道channels 为商户已关联且与 ALIPAY 匹配的启用通道列表;/api/pay/api/direct_pay可不传 channel,系统每次从该列表随机选取一条;若传入 channel(须为 channels[].id),则按指定通道收款。若使用 WECHAT,请确认商户已关联微信通道且 pay_type 与通道类型一致。订单:平台单号建议 OR*,商城单号 MO* 一一关联。

2.发起支付

请求地址:
https://bs12guatou.131aiqa.xmxiawen.asia/api/pay
请求参数
参数名 类型 必填 是否参与签名 参数说明
shop_number string 平台商户号
timestamp string 请求时间 格式20260722161934
biz_content string 业务数据,json字符串,内容为:
{
    "order_sn":"OR202605221200001",//商户订单号,建议 OR 开头(系统不强制)
    "channel":"2",//可选;支付通道 ID(/api/prices 的 channels[].id)。不传则从已关联通道随机
    "key":"24",//商品ID(价格档位;支付时同价随机匹配)
    "amount":"399.00",//须为商城价格档位金额
    "pay_type":"ALIPAY",//仅支持 ALIPAY / WECHAT(大写字符串,禁止传 1/2)
    "notify_url":"https://your-domain/notify",//支付结果异步通知地址(须公网可达)
    "extra_data":{"from":"api","mode":"pay"}//可选;通知中为合并后的 JSON 字符串,见第 4 节
}
                    
sign string 签名字符串,签名方式参考下方签名/验签

业务说明

  • channel(可选)/ key:指定 channel 时须为 /api/prices 返回的 channels[].id;省略时系统从商户已关联通道中随机选取。支付时系统在同价商品中随机匹配,订单 goods_key 可能与请求 key 不同,签名仍以请求 biz_content 为准
  • pay_type:仅允许 ALIPAYWECHAT(大写字符串);不要传数字 1/2,否则会返回 不支持的支付类型
  • extra_data:JSON 对象;异步通知会合并商城字段(mall_order_snmall_product_idpay_mode 等),非 biz 原样。
  • 返回 data.amount 为订单实付金额(含可能的随机扣减),不一定等于 biz 中 amount。
请求返回
{
    "code": 200,//请求状态码 200 为成功,其他为失败
    "data": {
        "order_sn":"OR202605221200001",//用户订单编号
        "pay_number":"PO20260522120001",//平台交易流水号(PO 开头)
        "amount":"399.00",//订单实付金额
        "pay_url":"https://...",//支付链接,跳转收银台
        "mall_order_sn":"MO20260522120001"//商城订单号
    },
    "msg": "请求成功"
}
                    
3.直付支付(自定义金额)

请求地址:
https://bs12guatou.131aiqa.xmxiawen.asia/api/direct_pay

无需先调 /api/prices。金额可与商品标价不一致;系统从商城随机选取一件上架商品作为名义服务(支付宝订单标题为商品名称)。同步创建商城订单 MO*,与商户订单号 OR* 关联。

请求参数
参数名 类型 必填 是否参与签名 参数说明
shop_number string 平台商户号
timestamp string 请求时间 格式20260722161934
biz_content string 业务数据,json字符串,内容为:
{
    "order_sn":"OR202605221300001",//商户订单号,建议 OR 开头
    "channel":"2",//可选;指定通道 ID,不传则随机
    "amount":"128.50",//支付金额
    "pay_type":"ALIPAY",//仅支持 ALIPAY / WECHAT(大写字符串,禁止传 1/2)
    "notify_url":"https://your-domain/notify",//异步通知地址
    "extra_data":{"from":"api","mode":"direct_pay"}//可选,规则同 /api/pay
}
                    
sign string 签名字符串,签名方式参考下方签名/验签

无需 keychannel 可选(规则同 /api/pay)。系统随机选取上架商品作为名义服务并写入订单。返回 amount 规则同第 2 节。

商户直付限额:总后台可为商户配置 pay_amount_min / pay_amount_max(仅本接口生效,/api/pay 不受影响)。未配置则不限制;可只配下限或上限。校验对象为请求 amount(闭区间)。超限返回如 支付金额低于商户限额下限(10.00)

pay_type 取值提醒:ALIPAY / WECHAT,禁止传 1/2

请求返回
{
    "code": 200,//请求状态码 200 为成功,其他为失败
    "data": {
        "order_sn":"OR202605221300001",//用户订单编号
        "pay_number":"PO20260522130001",
        "amount":"128.50",//订单实付金额
        "pay_url":"https://...",
        "mall_order_sn":"MO20260522130001"
    },
    "msg": "请求成功"
}
                    
4.支付结果异步通知

通知请求格式

请求方式:POST

Content-Typeapplication/json;charset=utf-8(与开放 API 的 form 不同,请按 JSON 解析 body)

Body:JSON 对象,字段见下表。

商户响应:HTTP 响应正文返回纯文本 success(建议小写)。未返回时将按间隔重试(见下文)。

回调参数
参数名 类型 必填 是否参与签名 参数说明
order_sn string 用户订单编号
shop_number string 商户编号
pay_number string 平台交易流水号
pay_result string 支付结果 success 支付成功 fail 支付失败
pay_time string 支付时间,格式 yyyy-MM-dd HH:mm:ss
amount string 订单实付金额(如 399.00);若启用随机扣减,可能与 biz_content 中 amount 不同
extra_data string 有非空值时参与 订单 extra_data 的 JSON 字符串(UTF-8)。含商户传入字段及系统合并的商城字段(mall_order_snmall_product_idpay_mode 等), biz 原样。空字符串不参与签名
sign string 签名字符串,验签规则见异步通知验签(与开放 API 的 timestamp+biz_content 不同)

pay_number 为平台流水号(一般以 PO 开头);pay_time 格式为 yyyy-MM-dd HH:mm:ss

回调请求响应说明
收到回调通知后,请返回 success 字符串以确认收到通知,否则则按未收到通知处理,未返回success时,系统将在第一次发送通知后的第10秒、30秒、2分钟、10分钟、30分钟后各发一次通知,若最后一次发送通知仍未收到响应,后续将不再发送通知。
5.支付信息查询

请求地址:https://bs12guatou.131aiqa.xmxiawen.asia/api/pay_result
请求参数
参数名 类型 必填 是否参与签名 参数说明
shop_number string 平台商户号
timestamp string 请求时间 格式20260722161934
biz_content string 业务数据,json字符串,内容为:
{
    "order_sn":"OR202605221200001",//用户订单编号
}
                    
sign string 签名字符串,签名方式参考下方签名/验签
请求返回
{
    "code": 200,//请求状态码 200 为成功,其他为失败
    "data": {
        "order_sn":"OR202605221200001",//用户订单编号
        "shop_number":"202452313486651",//商户编号
        "pay_number":"PO20260522120001",//平台交易流水号(PO 开头)
        "pay_result":"success",//waiting 待支付 success 成功 fail 失败
        "pay_time":"2025-02-24 16:53:54",//支付时间(已支付时返回)
        "amount":"399.00"//订单实付金额
    },
    "msg": "请求成功"//请求信息说明
}
                    

本接口为开放 API,响应不含 sign;请求签名规则同第 6 节(biz_content 仅含 order_sn)。

联调自检
  • 开放 API 签名失败:用实际 POST 的 biz_content 原文字符串对照第 6 节演算 B,勿套用无 extra_data 的演算 A。
  • 通知验签失败:确认按 JSON body 取值;extra_data 须与通知中字符串完全一致(含合并后的商城字段)。
  • 收不到通知:检查 notify_url 是否公网可达、是否返回 success
6.签名/验签

签名算法

参与签名的顶层字段:shop_numbertimestampbiz_content(有则参与)。sign 本身不参与签名。

timestamp 必须为 14 位 yyyyMMddHHmmss(如 20260522143000),不要使用带空格或横杠的时间格式。

1. 除 sign 外,将参与签名的参数按 key 的 ASCII 升序拼接为 key1=value1&key2=value2(空值、null 不参与)。

2. 在拼接串末尾直接追加商户密钥 secret(无额外分隔符),得到待签名字符串 signStr。

3. sign = strtoupper(md5(signStr))

biz_content 在请求中为 JSON 字符串;验签时按原文字符串参与拼接,不要二次解析后再序列化(避免字段顺序变化导致验签失败)。

常见失败原因

  • 用文档演算 A 的 JSON 顺序,与实际请求(如 JSON.stringify)不一致。
  • 请求含 extra_data,却用不含该字段的串算 sign。
  • 将异步通知按开放 API 规则验签(误用 timestamp、biz_content)。
  • 通知按 form 解析,实际为 JSON body。
对接方可直接复制说明(pay_type)
【支付参数规范】
1) pay_type 必须传字符串:ALIPAY 或 WECHAT
2) 不要传数字 1/2(会返回:code=400, msg=不支持的支付类型)
3) 示例:"pay_type":"ALIPAY"
完整演算示例 A(开放 API,指定 channel,不含 extra_data)

下列为一组自洽的演示数据(商户密钥仅用于文档演算,请替换为您在后台配置的密钥后自行核对)。省略 channel 时签名串中不含该字段,服务端将从已关联通道随机选取。

shop_number202452313486651
timestamp20260522143000(14 位,无空格、无横杠)
biz_content 原文
{"channel":"1","key":"24","pay_type":"ALIPAY","amount":"399.00","order_sn":"OR202605221200001","notify_url":"https://example.com/notify"}
演示用 secretMySecretKey2026

步骤 1:按 key 升序拼接(不含 sign),得到 paramStr:

biz_content={"channel":"1","key":"24","pay_type":"ALIPAY","amount":"399.00","order_sn":"OR202605221200001","notify_url":"https://example.com/notify"}&shop_number=202452313486651×tamp=20260522143000

步骤 2:末尾直接追加 secret,得到 signStr:

signStr = biz_content={"channel":"1","key":"24","pay_type":"ALIPAY","amount":"399.00","order_sn":"OR202605221200001","notify_url":"https://example.com/notify"}&shop_number=202452313486651×tamp=20260522143000MySecretKey2026

步骤 3:计算签名:

sign = UPPER(MD5(signStr)) = 7560890832ED5E4E38A97152DB2387B9

请求体示例:shop_number=202452313486651&timestamp=20260522143000&biz_content=...&sign=7560890832ED5E4E38A97152DB2387B9biz_content 需 URL 编码后传输,但验签使用解码后的原文字符串)。

完整演算示例 B(含 extra_data,与 /index.html 键序一致)

下列 biz_content 为整段签名输入(注意字段顺序与嵌套对象):

{"order_sn":"OR202605221200001","channel":"1","key":"24","amount":"399.00","pay_type":"ALIPAY","notify_url":"https://example.com/notify","extra_data":{"from":"api","mode":"pay"}}

paramStr(演示 secret:MySecretKey2026,shop_number / timestamp 同示例 A):

biz_content={"order_sn":"OR202605221200001","channel":"1","key":"24","amount":"399.00","pay_type":"ALIPAY","notify_url":"https://example.com/notify","extra_data":{"from":"api","mode":"pay"}}&shop_number=202452313486651×tamp=20260522143000
sign = UPPER(MD5(paramStr + MySecretKey2026)) = 08E9FA169A0CB89F1F7A6CDF2D28446B
异步通知验签

规则见第 4 节「通知请求格式」。去 sign → 非空字段按 key 升序拼接 → 末尾追加 secret → UPPER(MD5)不使用 timestampbiz_content

参与签名(有值才参与):amountextra_dataorder_snpay_numberpay_resultpay_timeshop_number

完整演算示例(含商城合并字段)(演示 secret:MySecretKey2026):

extra_data={"from":"api","mode":"pay","mall_order_id":1001,"mall_order_sn":"MO20260522120001","mall_product_id":24,"mall_product_name":"示例商品","pay_mode":"pay"}

步骤 1:paramStr:

amount=399.00&extra_data={"from":"api","mode":"pay","mall_order_id":1001,"mall_order_sn":"MO20260522120001","mall_product_id":24,"mall_product_name":"示例商品","pay_mode":"pay"}&order_sn=OR202605221200001&pay_number=PO202605221430001&pay_result=success&pay_time=2026-05-22 14:35:10&shop_number=202452313486651

步骤 2:signStr = paramStr + secret

步骤 3

sign = UPPER(MD5(signStr)) = 949C70116BEC6736A475358751072FD0

实际通知中 extra_data 键序与内容以平台 POST 为准,须逐字一致再验签。无 extra_data 或为空字符串时,paramStr 中不包含 extra_data=