DEVELOPER GUIDE
开发文档
覆盖当前商户签名网关的 24 个接口:支付、退款、分账、回退、代付、收银台、支付宝小程序与预授权。所有资金操作均以验签后的服务端状态为准。
接口清单与接入范围
以下路径均相对于 /api/v1/gateway,统一使用 POST application/json 和 RSA2 签名信封。接口存在不等于商户已获操作权限;实际能力取决于商户、用户组、通道和插件配置。
| 业务 | 接口路径 | 说明 |
|---|---|---|
| 支付 / 查单 / 关单 | /pay/query/close | 创建、确认或关闭支付订单。 |
| 退款 | /refund/refund/query | 全额或部分退款,查询退款结果。 |
| 通道分账 | /split/split/query/split/return/split/return/query | 支付机构侧分账及指定接收方回退。 |
| 商户内部分账 | /merchant-split/merchant-split/query/merchant-split/return/merchant-split/return/query | 平台商户账务内的分账及回退;与通道分账不是同一套业务。 |
| 商户代付 | /transfer/transfer/query/transfer/cancel | 发起普通代付、查询与条件撤销。 |
| 收银台 / 发起支付 | /cashier/session/cashier/session/query/cashier/pay | 创建会话、查询会话、选定方式生成付款订单。 |
| 支付宝小程序 | /alipay/mini/create | 服务器兑换小程序授权码,创建独立 JSAPI_PAY 交易。 |
| 支付宝预授权 | /preauthorization/freeze/preauthorization/query/preauthorization/capture/preauthorization/unfreeze | 冻结用户资金、查询、扣款、解冻;冻结阶段不记商户余额。 |
cashier_url / pay_info,按对应类型引导顾客付款。| 其他入口 | 调用方与用途 |
|---|---|
/bill/session/:session_no 与付款人收银台接口 | 由顾客浏览器完成选支付方式、二维码或表单支付;商户服务端使用上表签名接口,不混用令牌接口与签名响应。 |
/bill/qrcode/:token | 固定码牌收款页,由顾客输入金额。码牌在商户后台取得,当前没有商户签名网关的生成码牌接口。 |
/bill/check/:token 与付款人身份授权入口 | 完成付款人检查和授权;通过检查不是付款成功,使用平台返回的完整链接。 |
| 支付机构通知、同步回跳、投诉与实名回调 | 支付机构或身份服务通知平台,不是商户发起交易的入口。商户接收付款成功通知请实现自己的 notify_url。 |
除“请求信封”和“响应信封”示例外,各接口的 JSON 示例均为 biz_content,发送前必须包装并签名。示例编号、金额、日期和地址仅供说明,不能原样用于正式交易。
接入准备
- 完成商户入驻与必要的实名认证,确认账户、支付权限和所需支付方式已启用。
- 登录商户中心 → RSA 密钥,准备 AppID、商户应用私钥及对应公钥;平台保存应用公钥以验证请求。
- 获取平台公钥,用于验证响应和通知。当前账户的网关及密钥信息见接口资料。
- 准备公网可访问的 HTTPS 通知地址,并按账户要求登记通知、回跳域名及服务端请求 IP。
请求网关
平台尚未配置接口域名,请联系运营人员。不要使用当前页面域名或管理后台地址自行拼接网关。
下文接口路径均追加在上述网关之后。所有商户主动请求使用 POST 和 Content-Type: application/json,由服务端发送。
请求与 RSA2 签名
外层固定为以下 7 个字段,业务参数只放在 biz_content。接口不接受未知业务字段或尾随的第二段 JSON。
{
"app_id": "YOUR_APP_ID",
"version": "1.0",
"sign_type": "RSA2",
"timestamp": 1767225600,
"date": "2026-01-01T00:00:00Z",
"biz_content": {"merchant_order_no":"DEMO_ORDER_001"},
"sign": "BASE64_SIGNATURE"
}
这是结构示例,不可直接发送。替换 AppID、业务参数和当前时间,重新签名。示例中的固定时间已经过期。
| 字段 | 要求 |
|---|---|
app_id | 有效商户应用 ID,字符串。 |
version / sign_type | 固定为字符串 1.0 / RSA2。 |
timestamp | Unix 秒级整数,与服务器时间偏差不得超过 5 分钟。 |
date | RFC3339 时间,须含时区;与 timestamp 表示同一时刻,最多允许 1 秒精度误差。 |
biz_content | JSON 对象,不是包含 JSON 的字符串。 |
sign | RSA2 签名结果的标准 Base64 编码。 |
生成签名原文
- 排除外层
sign,其余字段名按升序排序。sign_type和date参与签名。 - 字符串字段取解码后的原值,不带 JSON 引号;整数保留十进制文本。空字符串值不参与拼接,数值
0不能省略。 biz_content使用待发送或实际收到的原始 JSON,仅删除字符串外的无意义空白;保留字段顺序、转义形式和数字写法,不要解析后重新序列化。- 将字段拼成
key=value,用&连接,不做 URL 编码,不附加换行。 - 对原文 UTF-8 字节使用 SHA-256 + RSA PKCS#1 v1.5 签名,再作 Base64 编码;不是 RSA-PSS。RSA 公钥至少 2048 位。
app_id=YOUR_APP_ID&biz_content={"merchant_order_no":"DEMO_ORDER_001"}&date=2026-01-01T00:00:00Z&sign_type=RSA2×tamp=1767225600&version=1.0
相同签名会被重放保护拒绝。重试须保持原商户订单号与业务参数,刷新时间并重新签名;不要原样重发请求信封。
验证平台响应
签名响应包含 app_id、version、sign_type、timestamp、date、code、msg、biz_content、sign。使用平台公钥按同一规则验签,code 和 msg 也参与签名;验签后校验 AppID、算法、版本和时间,再判断 HTTP 状态与 code。
code=0 表示接口调用成功,不表示订单已支付。鉴权、限流或代理错误可能没有签名信封;无签名、验签失败或网络异常都不能当作支付成功。
{
"app_id": "YOUR_APP_ID",
"version": "1.0",
"sign_type": "RSA2",
"timestamp": 1767225600,
"date": "2026-01-01T00:00:00Z",
"code": 0,
"msg": "ok",
"biz_content": {"trace_id":"TRACE_ID"},
"sign": "BASE64_RESPONSE_SIGNATURE"
}
上例只展示外层结构;实际 biz_content 由对应接口决定。响应中的可选字段可能省略,未知新增字段应兼容,但未知业务状态不能当作成功。时间字段为 RFC3339;未发生的事件时间可能省略或为零值时间,不能仅凭时间字段推断成功。
金额、时间与幂等
金额与手续费使用币种最小单位的整数,人民币为分,不接受小数元或数字字符串。支付金额程序上限为 9000000000000,实际商户/通道限额通常更低。expire_seconds 为整数秒:省略或 0 使用平台默认;未配置时基础默认 1800 秒、范围 60~86400 秒。平台可调整默认值与范围,通道限制再取交集;默认值会调整到有效范围,显式负数或越界值会报错,以响应 expired_at 为准。
网络超时、HTTP 5xx 或响应无法验签表示“结果未知”,不等于扣款或退款失败。先按原业务单号查单;只有确认结果后才能决定后续操作。重试保留原业务编号及业务参数,刷新时间并重新签名;同一编号不能用于不同业务。
收银台接入
推荐流程:商户服务端创建会话 → 验签后将用户引导到返回的 cashier_url → 等待异步通知或服务端查单。
创建会话 · POST /cashier/session
将下列业务对象放入请求信封的 biz_content:
{
"merchant_order_no": "DEMO_ORDER_001",
"amount": 100,
"currency": "CNY",
"subject": "示例商品",
"pay_type": "wxpay",
"notify_url": "https://merchant.example.com/pay/notify",
"return_url": "https://merchant.example.com/pay/return"
}
| 业务字段 | 要求 |
|---|---|
merchant_order_no | string,必填,同一商户内唯一,最长 64 字节;重试使用原编号。 |
amount | int64,必填,正整数,单位分;100 表示人民币 1 元,不能传小数金额。 |
subject | string,必填,商品标题,最长 128 个字符。 |
currency | string,选填,默认 CNY;须为通道支持的三字母货币代码。 |
pay_type | string,选填,如支付宝 alipay、微信 wxpay;不传时由用户选择已开通方式。 |
notify_url / return_url | string,选填,分别为服务端通知、浏览器回跳地址,各最长 2048 字节。建议始终配置 notify_url,使用已登记的公网 HTTPS 地址。 |
description | string,选填,订单说明,最长 512 个字符。 |
expire_seconds | int64,选填,秒;不传或为 0 使用平台默认值,允许范围受平台和通道共同限制。 |
scene / client_ip | string,选填,scene 默认 web_cashier;client_ip 传付款用户的真实 IPv4/IPv6,可留空,不会代替商户服务端的白名单来源 IP。 |
响应业务对象如下。保存会话号,核对金额与订单信息,原样使用已验签的收银台地址,不自行拼接或更换域名。
{"session_no":"SESSION_NO_FROM_RESPONSE","merchant_order_no":"DEMO_ORDER_001","amount":100,"currency":"CNY","subject":"示例商品","scene":"web_cashier","pay_type":"wxpay","cashier_url":"https://cashier.example.com/bill/session/SESSION_NO_FROM_RESPONSE","status":"created","trace_id":"TRACE_ID","expired_at":"2026-01-01T00:30:00Z","created_at":"2026-01-01T00:00:00Z","updated_at":"2026-01-01T00:00:00Z"}
| 会话响应字段 | 类型与含义 |
|---|---|
session_no / merchant_order_no | string,会话令牌与商户订单号。 |
order_no | string,可选,生成支付订单后关联的平台订单号,不表示已付款。 |
amount / currency | int64 / string,金额分与币种。 |
subject / description / scene | string,标题、可选说明、业务场景。 |
pay_type / selected_pay_type | string,可选,创建时限定方式 / 已选择的付款方式。 |
cashier_url / status / trace_id | string,收银台链接、会话状态、排障追踪号。链接和令牌应视为敏感信息。 |
expired_at / created_at / updated_at | RFC3339 string,过期、创建、更新时间。 |
查询会话 · POST /cashier/session/query
{"session_no":"SESSION_NO_FROM_RESPONSE"}
唯一请求字段 session_no:string,必填,仅可查询当前签名商户的会话。响应字段与创建会话一致。
这里展示的是 biz_content,仍需完整签名信封。会话状态包括 created、paying、paid、expired、closed;产生支付订单后返回 order_no。会话查询读取平台记录,不等同于上游主动查单;支付结果确认使用下方 /query 或有效通知。
重复创建返回原会话,不延长有效期、不重置状态;改变 expire_seconds、scene 或 client_ip 不会更新已存在的会话。订单号、应用、金额、币种、标题、说明、支付方式、通知与回跳地址须与原会话匹配。
直接下单 · POST /pay
适合需要自行展示付款入口的商户;不再调用会话创建接口。pay_type 必填,pay_mode 不传默认 native,实际场景须由商户通道支持。
{
"merchant_order_no": "DEMO_ORDER_002",
"pay_type": "alipay",
"pay_mode": "native",
"subject": "示例商品",
"amount": 100,
"currency": "CNY",
"notify_url": "https://merchant.example.com/pay/notify"
}
以上为业务对象;订单号、金额、标题、通知与有效期等规则同前。不要传内部插件或通道编码。可选场景如 page、wap、native、jspay、app,以实际开通能力为准。
| 请求字段 | 类型 / 必填 | 规则 |
|---|---|---|
merchant_order_no | string / 是 | 同商户唯一,最长 64 字节。 |
pay_type | string / 是 | 平台开通的支付方式编码,如 alipay、wxpay。 |
pay_mode | string / 否 | 默认 native;须由通道支持。与业务 scene 不是同一字段。 |
subject / description | string / 标题必填 | 标题最长 128 字符,说明最长 512 字符。 |
amount / currency | int64 / string | 金额必填,正整数分;币种选填,默认 CNY。 |
expire_seconds | int64 / 否 | 有效秒数,省略或 0 使用平台/通道策略。 |
notify_url / return_url | string / 否 | 通知/浏览器回跳,各最长 2048 字节;建议使用已登记的公网 HTTPS 地址。 |
scene | string / 否 | 商户业务场景标识,直接下单未填写时为空;不要伪造平台注册缴费等保留场景。 |
client_ip | string / 否 | 付款用户真实 IPv4/IPv6;不是商户服务端白名单来源。 |
device_id | string / 否 | 业务设备标识;不用于替代身份认证。 |
code_plate_id | string / 否 | 已有的、属于当前商户且获准使用的码牌记录标识;不是扫码地址中的固定令牌,不需要关联码牌时不传。 |
| pay_info_type | pay_info 处理方式 |
|---|---|
url | 完整付款地址,验签后引导用户访问。 |
qr | 二维码内容,按返回内容生成二维码。 |
mini_program / app | 对应平台的支付参数,需按该平台 SDK 和支付场景对接。 |
form | 包含 action、fields 的 JSON 表单数据;必须转义字段后构造 POST 表单,不把返回内容当作 HTML 执行。不做表单适配时请使用统一收银台。 |
响应还包含 order_no、merchant_order_no、amount、currency、status。支付地址可能承载身份检查或授权步骤,通过检查、浏览器回跳和客户端提示均不能替代服务端付款确认。
支付订单响应字段
/pay、/query、/close、/cashier/pay 共用以下 biz_content 结构;字段是否出现取决于当前状态。
{"order_no":"PLATFORM_ORDER_NO","merchant_order_no":"DEMO_ORDER_002","pay_type":"alipay","pay_mode":"native","subject":"示例商品","amount":100,"currency":"CNY","fee_amount":0,"status":"paying","pay_info":"https://pay.example.com/DEMO_TOKEN","pay_info_type":"url","trace_id":"TRACE_ID","expired_at":"2026-01-01T00:30:00Z","created_at":"2026-01-01T00:00:00Z","updated_at":"2026-01-01T00:00:00Z"}
| 字段 | 类型与含义 |
|---|---|
order_no / merchant_order_no | string,平台 / 商户订单号。 |
channel_order_no | string,可选,上游支付机构订单号。 |
pay_type / pay_mode | string,最终支付方式 / 场景。 |
subject / description | string,标题 / 可选说明。 |
amount / fee_amount | int64,原支付金额 / 手续费,均为分;不能用手续费判断是否付款。 |
currency / status | string,币种 / 支付订单状态。 |
pay_info / pay_info_type | string,可选,付款内容及类型;已关闭、受限制或不可展示时可能为空,不要缓存后绕过状态继续付款。 |
trace_id | string,排障追踪号。 |
expired_at / created_at / updated_at / paid_at | RFC3339 string,过期/创建/更新/支付时间;paid_at 是事件时间,不取代 status。 |
payer_id / payer_id_type | 可选 string;支付通道核实的付款账号及支付类型(alipay / wxpay),全部纳入 RSA2 签名。 |
payer_scope / payer_id_source | 可选 string;付款身份所属应用范围,以及核实来源 auth / notify / query。未提供范围时不省略其他已核实字段。 |
付款账号只在当前商户的签名响应、查单及支付成功通知中返回。微信 OpenID 受应用范围限制,支付宝 UID 不应当作微信 OpenID 使用;不使用其他应用的登录身份或商户自行上传的账号补全。没有可靠付款身份时原生接口省略这些字段,客户端付款账号保持 null,不猜测或填入其他身份。付款人公开收银台接口不返回这些商户身份字段。
查询订单 · POST /query
{"merchant_order_no":"DEMO_ORDER_002"}
请求字段 merchant_order_no、order_no 均为 string,两者至少提供一个;同时提供时必须指向同一订单,只能查询当前商户的订单。响应见支付订单响应字段。creating、paying、closing 等适用状态会在插件支持时主动向上游查单;authorizing 通常只返回当前记录,到期订单可能先执行本地过期处理。不支持主动查询时返回平台已有状态,不能把“查询成功”理解为上游已确认付款。
验签后核对订单号、金额、币种与支付方式。仅将 status=paid 作为付款成功处理,并保证本地交付幂等。
| 状态 | 商户处理 |
|---|---|
creating、authorizing、paying、closing | 创建、身份授权或支付处理中,继续完成授权、等待通知或适度查单,不重复发起新的交易。 |
paid | 已付款,验签及业务核对后仅交付一次。 |
reviewing | 待复核,不自动交付,联系平台处理。 |
closed、failed、refunded | 不可按成功新单交付;结合现有本地订单记录处理。遇到未知状态须保留记录并人工核查。 |
关闭未支付订单
关闭订单 · POST /close
取消尚未完成付款的订单。关单不是退款:已付款订单请使用退款接口。请求与响应都使用前述 RSA2 签名信封,下例仅展示 biz_content。
{
"merchant_order_no": "DEMO_ORDER_001"
}
| 业务字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
order_no | string | 二选一 | 平台订单号,使用下单或查单返回的原值。 |
merchant_order_no | string | 二选一 | 商户原订单号;同传两个编号时必须指向当前商户的同一订单,不能传其他商户的订单。 |
允许关闭的状态
仅允许 creating(创建中)、paying(待支付)、authorizing(付款人授权中)且没有付款时间、没有冻结资金、未删除的订单。资金状态还须为空或 none。已支付、已退款、已关闭、关闭处理中或受资金限制的订单会被拒绝。
尚未向通道发起支付的授权订单可直接关闭并使授权支付流程失效;其他订单要求原支付插件具备关单能力。插件或通道不支持时,不能用本接口强行关闭。
成功响应业务对象
{
"order_no": "ACG_DEMO_ORDER_001",
"merchant_order_no": "DEMO_ORDER_001",
"pay_type": "wxpay",
"pay_mode": "jspay",
"subject": "示例商品",
"amount": 1000,
"currency": "CNY",
"fee_amount": 6,
"status": "closed",
"trace_id": "TRACE_DEMO_ORDER_001",
"expired_at": "2026-09-30T12:30:00+08:00",
"paid_at": "0001-01-01T00:00:00Z",
"created_at": "2026-09-30T12:00:00+08:00",
"updated_at": "2026-09-30T12:01:00+08:00"
}
返回结构与下单、查单的订单对象一致。可选字段可能不出现;即使返回了历史支付信息,订单关闭后也不得继续展示或使用。
| 响应字段 | 类型 | 含义 |
|---|---|---|
order_no / merchant_order_no | string | 平台订单号 / 商户订单号。 |
channel_order_no | string,可选 | 通道订单号;尚未向通道发起支付时可能没有。 |
pay_type / pay_mode | string | 订单支付方式 / 支付场景模式。 |
subject / description | string | 原订单标题 / 说明;说明为空时省略。 |
amount / fee_amount | integer(int64) | 原订单金额 / 订单手续费,人民币均为分;关单不会扣取示例所示金额。 |
currency | string | 订单币种,如 CNY。 |
status | string | 成功关闭为 closed。 |
pay_info / pay_info_type | string,可选 | 原支付信息及类型,关闭后不再作为可付款凭据。 |
trace_id | string | 订单追踪编号,排查问题时提供。 |
expired_at | string(RFC3339) | 原订单支付截止时间。 |
paid_at | string(RFC3339) | 未付款可能返回零时间 0001-01-01T00:00:00Z;不可将字段存在视为已付款。 |
created_at / updated_at | string(RFC3339) | 订单创建 / 最后更新时间。 |
超时与重复关单
平台在请求通道前保存 closing。超时或“正在确认关闭结果”不代表关闭失败,也不代表已关闭;请使用 /query 查明最终状态,若实际已付款应进入退款流程。关闭中的订单不能立即重复关单;已关闭订单再次关单也会返回状态限制错误,所以不要要求重复调用必须返回成功,更不要因此创建新的支付订单。
退款与退款查询
支持按商户退款单号跟踪每一次退款。平台接受全额或部分退款申请,但是否支持部分退款、可退期限及其他通道限制取决于原订单使用的支付插件和通道,不能假定所有插件都支持。以下金额均为整数,人民币单位为分。
申请退款 · POST /refund
{
"merchant_order_no": "DEMO_ORDER_001",
"merchant_refund_no": "DEMO_REFUND_001",
"amount": 400,
"currency": "CNY",
"reason": "退回部分商品"
}
| 业务字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
order_no | string | 二选一 | 平台原支付订单号,与 merchant_order_no 至少传一个。 |
merchant_order_no | string | 二选一 | 商户原支付订单号;两个编号都传时必须指向当前商户的同一订单。 |
merchant_refund_no | string | 是 | 当前商户内唯一的退款业务编号,去除首尾空白后非空,最长 64 字节。一次退款从申请、超时到查询都沿用该编号;不同的部分退款使用不同编号。 |
amount | integer(int64) | 是 | 本次退款金额,必须大于 0、不超过原支付金额和当前可退款余额。示例 400 表示 4 元,不可传 4.00 或字符串。 |
currency | string | 否 | 省略或空字符串时使用原订单币种;提供时去除首尾空白并转大写后必须与原订单一致。 |
reason | string | 否 | 退款原因,去除首尾空白后最长 255 个字符,默认空。建议填写方便核对;同一退款编号重试时不可修改原因。 |
受理与幂等规则
- 原订单须为已支付状态,且资金没有被冻结;商户 API 不允许直接退审核中订单。原订单标记为
refunded也仍需校验剩余可退款金额,不代表可以再次全额退款。 - 同一商户、同一
merchant_refund_no、相同订单、金额、币种和原因,返回已有退款记录,不会再次发起退款。改变任一业务参数会被拒绝;已终结失败的编号也不会因为重复请求而重新发起。 - 请求成功只代表拿到了退款记录,必须继续判断
status。网络超时、5xx 或其他错误可能发生在通道受理之后,不能仅凭错误就换新退款编号。 - 遇到结果不确定时,先按原
merchant_refund_no查询。若需要重试申请,保持原业务参数,只刷新外层时间并重新签名。持续未知时请联系平台核对,避免重复退款。
申请成功响应业务对象(处理中示例)
{
"refund_no": "RF_DEMO_001",
"merchant_refund_no": "DEMO_REFUND_001",
"order_no": "ACG_DEMO_ORDER_001",
"channel_refund_no": "CHANNEL_REFUND_DEMO_001",
"amount": 400,
"currency": "CNY",
"reason": "退回部分商品",
"status": "processing",
"trace_id": "TRACE_DEMO_REFUND_001",
"created_at": "2026-09-30T13:00:00+08:00",
"updated_at": "2026-09-30T13:00:00+08:00"
}
查询退款 · POST /refund/query
{
"merchant_refund_no": "DEMO_REFUND_001"
}
| 业务字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
refund_no | string | 二选一 | 平台退款单号,使用申请退款返回的原值。 |
merchant_refund_no | string | 二选一 | 申请时的商户退款单号;同传两个编号时必须属于当前商户的同一退款记录。不要在查询编号中额外添加空白。 |
查到终结退款时返回已保存结果。对于未终结退款,原插件具备查退能力时会尝试向通道刷新;插件未提供查退能力时只返回当前记录,不保证状态会因此推进。查询超时同样不能当作退款失败。
查询成功响应业务对象(已完成示例)
{
"refund_no": "RF_DEMO_001",
"merchant_refund_no": "DEMO_REFUND_001",
"order_no": "ACG_DEMO_ORDER_001",
"channel_refund_no": "CHANNEL_REFUND_DEMO_001",
"amount": 400,
"currency": "CNY",
"reason": "退回部分商品",
"status": "completed",
"trace_id": "TRACE_DEMO_REFUND_001",
"created_at": "2026-09-30T13:00:00+08:00",
"updated_at": "2026-09-30T13:01:00+08:00"
}
退款响应字段
申请与查询返回同一种退款对象,示例中的通道编号和原因属于可选字段。
| 响应字段 | 类型 | 含义 |
|---|---|---|
refund_no | string | 平台退款单号。 |
merchant_refund_no | string | 商户退款单号,也是该次退款的幂等编号。 |
order_no | string | 对应的原支付平台订单号。 |
channel_refund_no | string,可选 | 通道退款流水号;空时省略,存在并不代表退款已完成。 |
amount | integer(int64) | 本次申请退款金额,人民币单位为分;不是订单累计退款金额。 |
currency | string | 原订单币种。 |
reason | string,可选 | 退款原因,空时省略。 |
status | string | 退款状态,见下表;不是原支付订单的状态。 |
trace_id | string | 该退款记录的追踪编号。 |
created_at / updated_at | string(RFC3339) | 退款记录创建 / 最后更新时间,不等同于银行最终入账时间。 |
退款状态与后续动作
| status | 解释 | 商户处理 |
|---|---|---|
creating | 本地退款意图已创建,结果尚未确定。 | 继续按原退款编号查询,不能创建重复退款。 |
processing / pending | 通道受理或处理中;通道返回空状态也按 processing 保存。 | 继续查询,不能标记退款成功。 |
unknown | 结果不确定,例如通道请求超时。 | 保留原业务编号,查询或联系平台核实;该金额仍占用可退款余额。 |
success / refunded / completed / finished | 平台接受的退款成功终态;不同插件可能返回不同名称。 | 验签并核对退款编号、原订单、金额和币种后,幂等更新本地退款结果。 |
failed / closed | 本次退款失败或关闭,终态。 | 核实原因。确需再次申请时才创建新的退款编号,重复原编号仍返回原记录。 |
部分退款、分账与资金占用
- 部分退款完成后,原支付订单通常仍为
paid;只有累计成功退款金额达到原支付金额才标记refunded。不能只靠原订单状态判断某一笔部分退款是否完成。 - 已成功及尚未终结的退款都会占用原订单的可退款额度;通道分账也占用同一笔订单金额,已完成的通道分账回退会减少分账净占用。必须确保本次退款不超过剩余可退款余额。
- 已经分出的通道资金如需退给顾客,应先按通道能力完成相应分账回退,再申请退款。用于微信分账代付的订单还受专门限制,完成相应分账回退前不能直接退款。
- 平台商户之间的内部余额分账不同于通道分账,退款时由平台账务处理相应回收;不要把两套分账编号或回退接口混用。退款处理中可能锁定原订单及相关分账资金,未结束前新的退款申请可能被资金冻结限制拦截。
/refund/query 结果确认退款状态;站内消息、短信或邮件提醒不能替代接口查退。通道分账:支付机构侧资金分配
本节接口实际调用原支付通道的分账能力,将支付机构侧的资金分给该机构的接收账号。它不是平台内商户之间的余额划拨;后者使用商户内部分账。下列均为追加到请求网关的签名 POST 接口,请求示例只展示 biz_content,仍需完整外层参数及 RSA2 签名。
发起通道分账 · POST /split
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
order_no | string / 是 | 平台支付订单号;本接口不接受 merchant_order_no。 |
merchant_split_no | string / 是 | 商户侧通道分账请求号,去首尾空白后 1–64 UTF-8 字节;当前商户内唯一,用于查询及防重复。 |
amount | int64 / 建议必填 | 分账总金额,币种最小单位,CNY 为分。应为正整数;省略或不大于 0 时当前实现按原订单总金额处理,并非剩余可分金额,建议始终明确填写。 |
currency | string / 否 | 省略或空字符串取原订单币种;非空会去首尾空白并转大写,必须与原订单一致。 |
receivers | object[] / 是 | 1–100 项,具体插件可能更严格;微信官方插件单次最多 50 项。各项金额之和必须等于 amount。 |
receivers[] 字段:
| 字段 | 类型 / 必填 | 规则 |
|---|---|---|
receiver_id | string / 是 | 接收项标识,1–128 UTF-8 字节,本次请求内不可重复;查询结果及回退均使用此值。 |
receiver_type | string / 依通道必填 | 接收账号类型,取值见下文,不可把平台商户 ID 当作支付机构账号类型。 |
account | string / 依通道必填 | 支付机构接收账号,最多 255 UTF-8 字节;支付宝、微信官方插件均要求非空。 |
name | string / 条件必填 | 接收方名称,最多 128 UTF-8 字节;微信商户号类型必须填写商户全称,其他类型按支付机构要求。 |
amount | int64 / 是 | 该接收项分配金额,币种最小单位,必须大于 0 且不超过本次总额。 |
share_bps | int64 / 否 | 比例元数据,默认 0;100 BPS = 1%。手工调用此接口不会按该比例替你计算金额,实际以 amount 为准,可省略。 |
memo | string / 否 | 说明,最多 255 UTF-8 字节,默认空;微信插件传给支付机构时最多保留 80 UTF-8 字节,空值使用“订单通道分账”。 |
target_type | string / 否 | 本商户接口只允许 merchant,省略或空值即为此值。platform 仅供后台已审核规则使用,本接口不能指定。 |
merchant_id | string / 否 | 接收项的账务归属,仅可为空或等于订单所属商户 ID;为空由系统补齐。它不是支付机构接收账号,也不能指定其他平台商户。 |
status / success_amount | 结果字段 / 不要提交 | 接收项处理结果及成功金额,由插件响应更新;请求中应省略,不可自行宣告成功。 |
当前官方插件的常用 receiver_type:支付宝使用 user_id(支付宝用户 ID)、login_name(登录账号)或 open_id;微信使用 merchant_id(微信商户号,需全称)或 personal_openid。不同插件不可混用类型;开通和绑定关系请在平台通道配置中完成。本接口不接受 rule_id,不能通过请求创建或修改后台分账规则。
{
"order_no": "ACGP_DEMO_001",
"merchant_split_no": "CHANNEL_SPLIT_001",
"amount": 200,
"currency": "CNY",
"receivers": [{
"receiver_id": "ALIPAY_RECEIVER_01",
"receiver_type": "user_id",
"account": "2088000000000000",
"name": "示例接收方",
"amount": 200,
"memo": "订单分账",
"target_type": "merchant"
}]
}
示例表示向支付宝接收账号分配 2.00 元,所有编号、账号须替换为已开通的真实配置;并非测试收款账号。
金额与状态限制
- 总额不得大于原支付金额,且不得超出通道允许比例:
amount × 10000 ≤ 原支付金额 × 通道分账上限 BPS。 - 商户接收项合计不能超过:原支付金额 − 手续费 − 已完成商户内部分账金额 − 退款占用 − 通道分账净占用,低于 0 按 0 处理。回退是否释放占用以已确认成功的回退记录为准。
- 退款及分账处理中、结果未知的金额仍可能占用额度,不可当作失败重新分配;原订单已被微信订单资金代付占用时,不能再发起普通通道分账。
- 通道分账尚未回退的部分会影响原路退款可退金额。需要退款时,先核对剩余可退额,必要时完成分账回退后再发起退款;分账回退本身不会退款给付款人。
查询通道分账 · POST /split/query
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
split_no | string / 二选一 | 平台通道分账号。 |
merchant_split_no | string / 二选一 | 当前商户提交的通道分账请求号;两个编号同时填写时必须指向同一记录。 |
{"merchant_split_no":"CHANNEL_SPLIT_001"}
已完成、失败或关闭的记录直接返回本地结果。非终态记录会在原插件支持查分账时尝试向支付机构刷新;不支持查询或该次通道查询失败时,可能仍返回原本地状态。查到记录并不代表已分账成功。
发起 / 查询分账的响应业务字段
以下字段位于已验签响应的 biz_content:
| 字段 | 类型 | 含义 |
|---|---|---|
split_no / merchant_split_no / order_no | string | 平台分账号、商户分账请求号、原平台支付订单号。 |
amount / currency | int64 / string | 申请分账总金额(最小单位)及币种;总金额不等于每个接收项已成功的总额。 |
status | string | 分账总体状态,见下方状态说明。 |
receivers | object[] | 上述完整接收项;receiver_id、receiver_type、account、name、amount、share_bps、memo 会返回;可附带 target_type、merchant_id、status、success_amount,空或零的可选结果可能省略。逐项检查状态及成功金额,不能仅看总体成功。 |
trace_id | string | 本次请求追踪号,供排查使用。 |
created_at / updated_at | string | RFC3339 时间,包含时区,可含小数秒。 |
{
"split_no": "SP_DEMO_001", "merchant_split_no": "CHANNEL_SPLIT_001",
"order_no": "ACGP_DEMO_001", "amount": 200, "currency": "CNY", "status": "success",
"receivers": [{
"receiver_id": "ALIPAY_RECEIVER_01", "receiver_type": "user_id",
"account": "2088000000000000", "name": "示例接收方", "amount": 200,
"share_bps": 0, "memo": "订单分账", "target_type": "merchant",
"merchant_id": "MERCHANT_ID", "status": "success", "success_amount": 200
}],
"trace_id": "TRACE_DEMO_001",
"created_at": "2026-09-30T12:00:00+08:00", "updated_at": "2026-09-30T12:00:01+08:00"
}
通道分账回退 · POST /split/return
从原分账的一名接收方退回指定金额;原分账总体状态必须为 success 或 finished,原订单插件必须实现分账回退。回退仍受支付机构侧规则约束。
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
split_no | string / 是 | 平台通道分账号;本接口不能以商户分账请求号替代。 |
merchant_return_no | string / 是 | 当前商户内唯一的回退请求号,去首尾空白后 1–64 UTF-8 字节。 |
receiver_id | string / 是 | 原分账存在的接收项标识,去首尾空白后 1–128 UTF-8 字节。 |
amount | int64 / 是 | 正整数,币种最小单位;不能超过该接收项原分账金额减去已有回退占用。非 failed / closed 的回退记录均计入占用。 |
currency | string / 否 | 省略或空值取原分账币种,非空去首尾空白并转大写后必须一致。 |
reason | string / 否 | 回退原因,去首尾空白后最多 255 个 Unicode 字符,默认空。 |
{
"split_no": "SP_DEMO_001", "merchant_return_no": "CHANNEL_RETURN_001",
"receiver_id": "ALIPAY_RECEIVER_01", "amount": 100, "currency": "CNY", "reason": "退回部分分账"
}
查询通道分账回退 · POST /split/return/query
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
return_no | string / 二选一 | 平台通道分账回退号。 |
merchant_return_no | string / 二选一 | 当前商户的回退请求号;两个编号同时填写时必须指向同一记录。 |
{"merchant_return_no":"CHANNEL_RETURN_001"}
unknown / processing,应联系平台核对机构结果,不要更换请求号重复回退。本组接口没有可填写的回调 URL,也未提供商户分账 / 回退专用异步通知。发起 / 查询回退的响应业务字段
| 字段 | 类型 | 含义 |
|---|---|---|
return_no / merchant_return_no | string | 平台回退号及商户回退请求号。 |
split_no / order_no / receiver_id | string | 原平台分账号、支付订单号、接收项标识。 |
amount / currency | int64 / string | 回退金额(最小单位)及币种。 |
reason | string / 可省略 | 回退原因。 |
channel_return_no | string / 可省略 | 支付机构回退单号,尚未返回时省略。 |
status / trace_id | string | 回退状态及本次请求追踪号。 |
created_at / updated_at | string | RFC3339 时间。 |
{
"return_no": "SR_DEMO_001", "merchant_return_no": "CHANNEL_RETURN_001",
"split_no": "SP_DEMO_001", "order_no": "ACGP_DEMO_001", "receiver_id": "ALIPAY_RECEIVER_01",
"amount": 100, "currency": "CNY", "reason": "退回部分分账",
"channel_return_no": "PROVIDER_RETURN_001", "status": "success", "trace_id": "TRACE_DEMO_002",
"created_at": "2026-09-30T12:01:00+08:00", "updated_at": "2026-09-30T12:01:01+08:00"
}
通道分账状态、重试与结果恢复
creating / processing / pending 为未完成;unknown 为结果不确定;success / finished / completed 为完成类;failed / closed 为失败或关闭。共用资金状态解析器也可能保留插件返回的 refunded 完成类状态;它不是“已退款给顾客”的证据。通道分账回退的前置校验目前只接受原分账状态 success 或 finished。
平台在调用支付机构前保存请求。超时、HTTP 错误或调用失败不保证没有发生资金操作:先用原 merchant_split_no / merchant_return_no 查询。相同商户请求号已存在时不会另起操作;参数不一致会拒绝。分账比较订单、金额、币种及完整接收项(包括顺序);回退比较原分账、接收方、金额、币种及原因。接收项结果会被插件更新,恢复结果应优先查单,不要靠重新提交或更换请求号判断成功。
商户内部分账:平台账务划拨
将订单扣除手续费后的净收入,按照已审核规则划入平台内其他商户的资金账户;不会调用支付宝、微信等支付机构的分账接口,也不是付款给顾客。以下均为签名 POST,业务参数放在 biz_content。
paid;商户正常并符合实名认证要求;商户和所在有效用户组都已开启商户分账,用户组设置了有效比例上限。规则须已审核生效、匹配订单应用或适用于全部应用,所有接收方已确认。规则、接收方确认及审核在商户中心和平台后台管理,不由本组开放接口创建。执行商户内部分账 · POST /merchant-split
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
order_no | string / 二选一 | 平台支付订单号,与 merchant_order_no 至少一项非空。 |
merchant_order_no | string / 二选一 | 当前商户原支付订单号;两项同时提交必须指向同一订单。 |
merchant_split_no | string / 是 | 当前商户内唯一请求号,去首尾空白后 1–64 UTF-8 字节。 |
rule_id | string / 否 | 已审核生效的规则 ID。省略时优先选订单应用专用规则,再选全应用规则;相同范围按最近更新时间选择。 |
不能直接传入 amount、currency、receivers 或任意收款账号。系统按规则计算:net_amount = 原支付金额 − 手续费,每项按净金额乘 share_bps / 10000 取整;总分配额取整后的尾差补给规则最后一项。100 BPS = 1%,总比例须不超过用户组上限,最终金额不得超过订单剩余净资金。
{
"merchant_order_no": "DEMO_ORDER_001",
"merchant_split_no": "INTERNAL_SPLIT_001",
"rule_id": "RULE_DEMO_001"
}
每个支付订单最多执行一次商户内部分账(包括自动分账)。同请求号、同订单返回已有结果,不能借重试替换规则;同请求号用于另一订单会拒绝,同订单换一个请求号也会拒绝。订单已自动分账时,应查询已有分账而非再次申请。极小金额按比例取整为 0 时可能不生成分账记录;必须检查返回的 split_no 和 status,不能只看 HTTP 成功。
查询商户内部分账 · POST /merchant-split/query
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
split_no | string / 二选一 | 平台内部商户分账号,不是通道分账号。 |
merchant_split_no | string / 二选一 | 当前商户内部商户分账请求号;两项同时填写须指向同一记录。自动执行的请求号为 AUTO_ 加平台支付订单号。 |
{"merchant_split_no":"INTERNAL_SPLIT_001"}
只允许原分账发起商户通过签名接口查询。查询返回平台账务记录,不请求支付机构。
执行 / 查询商户内部分账的响应业务字段
| 字段 | 类型 | 含义 |
|---|---|---|
split_no / merchant_split_no | string | 平台内部商户分账号及商户请求号;历史记录无请求号时 merchant_split_no 可省略。 |
rule_id / order_no / source_merchant_id | string | 实际使用规则、平台支付订单号、分账来源商户 ID。 |
net_amount / amount | int64 | 原订单净收入及本次实际分账总金额,均为币种最小单位(CNY 为分)。 |
currency / status | string | 订单币种;成功创建账务记录的总体状态为 success,不代表接收方资金已全部可用。 |
items | object[] | 接收商户明细,见下表。 |
trace_id | string | 本次请求追踪号,由网关补充。 |
created_at / updated_at | string | RFC3339 时间。 |
| items[] 字段 | 类型 | 含义 |
|---|---|---|
id / split_no / receiver_merchant_id | string | 明细 ID、平台内部商户分账号、平台接收商户 ID。 |
share_bps | int64 | 规则分配比例,100 BPS = 1%。 |
amount / recovered_amount | int64 | 原分配金额、已回退 / 已追回金额,均为最小单位;剩余为两者差额。 |
account_code | string | 当前资金账户,例如 merchant_pending 待结算、merchant_available 可用、merchant_frozen 冻结。 |
freeze_from | string / 可省略 | 冻结前所属账户,非冻结时可省略。 |
status | string | 通常为 pending(未到可用时间)或 available;风控 / 资金控制可更新为冻结状态,结合账户字段判断。 |
available_at | string | 预计可用时间,RFC3339;来源于原订单结算安排,非接口自行指定。 |
released_at | string / 可省略 | 实际从待结算转为可用的时间。 |
created_at / updated_at | string | 明细创建及更新时间,RFC3339。 |
{
"split_no": "MS_DEMO_001", "merchant_split_no": "INTERNAL_SPLIT_001",
"rule_id": "RULE_DEMO_001", "order_no": "ACGP_DEMO_001", "source_merchant_id": "MERCHANT_ID",
"net_amount": 9900, "amount": 1980, "currency": "CNY", "status": "success", "trace_id": "TRACE_DEMO_003",
"items": [{
"id": "MSI_DEMO_001", "split_no": "MS_DEMO_001", "receiver_merchant_id": "RECEIVER_MERCHANT_ID",
"share_bps": 2000, "amount": 1980, "recovered_amount": 0,
"account_code": "merchant_pending", "status": "pending",
"available_at": "2026-10-01T12:00:00+08:00",
"created_at": "2026-09-30T12:00:00+08:00", "updated_at": "2026-09-30T12:00:00+08:00"
}],
"created_at": "2026-09-30T12:00:00+08:00", "updated_at": "2026-09-30T12:00:00+08:00"
}
商户内部分账回退 · POST /merchant-split/return
将一名平台接收商户的指定分账金额回退至来源商户账务;原内部商户分账须为 success,接收商户必须存在于该笔分账中。它不发起支付机构分账回退,也不退款给顾客。
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
split_no | string / 是 | 平台内部商户分账号。 |
merchant_return_no | string / 是 | 当前商户内唯一请求号,去首尾空白后 1–64 UTF-8 字节。 |
receiver_merchant_id | string / 是 | 分账明细中的平台接收商户 ID;不是展示用商户号、支付机构账号或通道接收项 ID。 |
amount | int64 / 是 | 正整数,币种最小单位;不得超过该接收商户明细的 amount − recovered_amount。 |
reason | string / 否 | 原因,去首尾空白后最多 255 个 Unicode 字符,默认空。 |
币种由原分账确定,不要发送 currency。接收方余额不足时,当前账务实现会将不足部分记入应收账户,不是简单以余额不足拒绝;实际扣回及后续追偿由平台账务处理。
{
"split_no": "MS_DEMO_001", "merchant_return_no": "INTERNAL_RETURN_001",
"receiver_merchant_id": "RECEIVER_MERCHANT_ID", "amount": 500, "reason": "回退部分分账"
}
查询商户内部分账回退 · POST /merchant-split/return/query
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
return_no | string / 二选一 | 平台内部商户分账回退号。 |
merchant_return_no | string / 二选一 | 原发起商户的回退请求号;同时填写两个编号时须指向同一记录。 |
{"merchant_return_no":"INTERNAL_RETURN_001"}
发起 / 查询内部回退的响应业务字段
| 字段 | 类型 | 含义 |
|---|---|---|
return_no / merchant_return_no | string | 平台回退号及商户请求号;自动追回记录的商户请求号可省略。 |
split_no / order_no / merchant_id | string | 平台内部商户分账号、原支付订单号、分账来源商户 ID。 |
receiver_merchant_id | string / 可省略 | 本次回退的平台接收商户 ID;跨接收方的自动追回记录可省略。 |
refund_no | string / 可省略 | 关联退款号,仅退款触发的自动追回记录可能出现。 |
amount / currency | int64 / string | 回退金额(最小单位)及币种。 |
status | string | 成功写入账务的回退记录为 success。 |
trace_id | string | 本次请求追踪号,由网关补充。 |
reason | string / 可省略 | 回退原因。 |
created_at / updated_at | string | RFC3339 时间。 |
{
"return_no": "MSB_DEMO_001", "merchant_return_no": "INTERNAL_RETURN_001",
"split_no": "MS_DEMO_001", "order_no": "ACGP_DEMO_001", "merchant_id": "MERCHANT_ID",
"receiver_merchant_id": "RECEIVER_MERCHANT_ID", "amount": 500, "currency": "CNY",
"status": "success", "reason": "回退部分分账", "trace_id": "TRACE_DEMO_004",
"created_at": "2026-09-30T12:01:00+08:00", "updated_at": "2026-09-30T12:01:00+08:00"
}
重试与退款联动
内部划拨在账务事务内完成。响应丢失先按原商户请求号查询,不要换号重复执行。内部回退重复请求会校验原分账、接收商户及金额,匹配时返回原记录;改变原因不会更新原记录。查询仅支持原发起商户,不存在本组接口的专用异步通知。
原订单退款成功后,平台会按退款情况自动追回关联内部商户分账,并更新 recovered_amount;人工回退也会累计到该字段,不能再次回退已追回部分。不要把内部商户分账回退误当作顾客退款成功,更不能用通道分账号调用本组接口。
商户代付
代付从商户可用余额预留本金与手续费,由已开通的代付通道向收款账户转账;不是支付订单退款,也不是商户直接调用支付机构的接口。以下三个接口均使用商户 RSA2 签名信封,示例仅展示 biz_content。
创建代付 · POST /transfer
{
"request_no": "DEMO_TRANSFER_001",
"method": "alipay_account",
"recipient_account": "payee@example.com",
"recipient_name": "张三",
"amount": 100,
"title": "商户结算",
"remark": "示例代付"
}
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
request_no | string / 是 | 去首尾空白后非空,最长 128 字节;同一商户内唯一的代付请求号。 |
method | string / 是 | 代付方式,转小写并去首尾空白;必须由用户组开放,且有已启用、授权有效并支持该能力的通道。下表列出当前内置适配方式,不代表本商户均已开通。 |
recipient_account | string / 是 | 去首尾空白后非空,原始字段最长 255 字节;具体账号格式取决于方式与通道。 |
recipient_name | string / 条件必填 | 原始字段最长 128 字节;支付宝官方银行卡代付必填;微信官方余额转账金额达到 200000 分时必填。其他方式按通道要求提供。 |
amount | int64 / 是 | 正整数,人民币分,不支持小数;不得超过平台和用户组单笔限额、用户组当日笔数及金额限额,另受通道限制。微信官方余额转账至少 10 分。 |
title | string / 否 | 空值默认「商户代付」;去首尾空白、替换换行后最多保留 128 个字符。通道可能进一步限制。 |
remark | string / 否 | 转账说明,去首尾空白;填写简短内容并遵守通道限制。微信官方转账说明最多取 32 个字符。 |
代付币种固定 CNY,通道由平台选择。请通过 /transfer/query 查询原代付单,确认最终结果。
| method | 用途与收款账户 |
|---|---|
alipay_account | 支付宝账户。支付宝官方通道支持支付宝登录账号、2088 开头的数字用户 ID 或 OpenID;其他通道按其开户配置确定账号形式。 |
alipay_bank | 支付宝官方银行卡代付,提供银行卡号与收款人姓名。 |
wechat_balance | 微信余额转账;微信官方通道需要对应 AppID 下的收款 OpenID,且通道已配置转账场景和报备信息。其他通道须遵守该通道的账号要求。 |
wechat_profit_share | 微信订单分账代付。平台选择同 AppID 的可分账订单作为资金来源,不是客户端指定来源订单,也不等同于下单后的通道分账接口。 |
qq_wallet / bank_card | 由支持该能力的聚合通道提供 QQ 钱包 / 银行卡代付,账号和姓名按通道要求填写。 |
审核、限额与资金
- 人工审核创建后为
status=pending_review、review_status=pending;审核通过后才提交通道。自动模式为review_mode=automatic,创建时即尝试提交。 - 手续费由平台用户组配置计算:固定费加比例费,比例部分向上取整到分,再应用最低 / 最高手续费。以响应
fee_amount为准,不在请求里自行指定。 - 每日额度按服务器所在时区的当天、同商户记录计算;失败、拒绝和已撤销记录不占该统计,待审核、处理中、待确认、未知及成功记录计入。
- 本金与手续费在创建时预留;成功后结算,失败、审核拒绝或确认撤销后释放。
unknown不能视为失败或重新打款依据。
幂等与超时处理
同一商户重复 request_no 会返回已存在的代付单,不会修改旧单,也不会重新提交;当前实现不比较重试时的账号、金额等新参数。因此必须由商户固定请求号与原业务的对应关系,核对返回数据,严禁将旧请求号用于另一笔转账。命中原单前仍会校验当前平台、商户及用户组权限。
提交超时、接口报错或结果未知时,代付单和资金预留可能已经建立。先用原 request_no 查询,再依原单状态处理;不要更换请求号再创建。重试签名信封须更新时间并重新签名。人工审核期间无需重复提交代付。
查询代付 · POST /transfer/query
{"request_no":"DEMO_TRANSFER_001"}
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
transfer_no | string / 二选一 | 平台代付单号,去首尾空白后查询,仅限当前商户的商户代付单。 |
request_no | string / 二选一 | 原商户代付请求号;未提供 transfer_no 时使用。 |
至少填写一项,建议只传其中一个。两项同时提供时以 transfer_no 为准,当前实现不校验 request_no 是否与其一致。待审核单和已终结单直接返回平台记录;其他状态会尝试查询通道,微信订单分账代付会查询或推进其来源订单的处理。查询失败可能将原单记录为 unknown,应继续核查原单。
撤销代付 · POST /transfer/cancel
{"transfer_no":"TF_DEMO_001"}
请求字段、类型、二选一要求与 /transfer/query 相同。返回同一代付对象。只有实际返回 status=cancelled 才能确认已撤销,接口调用成功本身不代表撤销成功。
pending_review可在平台直接撤销并释放预留资金。- 已终结的
success、failed、rejected、cancelled原样返回;成功代付不能借此撤回。 - 进入提交阶段后取决于原通道是否实现撤销;不支持时必须查询原结果。微信订单分账代付提交后不支持撤销,只能查单确认。
- 通道撤销报错时可能记录为
unknown,不能直接按已撤销处理,也不能立即重新转账。
代付响应对象
上述三个接口均返回以下结构。先验证外层签名及 code,再核对业务对象;示例为等待人工审核的真实响应结构,编号、金额和时间仅用于说明:
{
"trace_id": "TRACE_ID",
"transfer_no": "TF_DEMO_001",
"request_no": "DEMO_TRANSFER_001",
"method": "alipay_account",
"recipient_account_masked": "pa************com",
"recipient_name_masked": "张*",
"amount": 100,
"fee_amount": 0,
"currency": "CNY",
"title": "商户结算",
"remark": "示例代付",
"status": "pending_review",
"review_mode": "manual",
"review_status": "pending",
"created_at": "2026-09-30T10:00:00+08:00",
"updated_at": "2026-09-30T10:00:00+08:00",
"submitted_at": "0001-01-01T00:00:00Z",
"paid_at": "0001-01-01T00:00:00Z"
}
| 响应字段 | 类型 | 含义 |
|---|---|---|
trace_id | string | 请求追踪号,用于排查。 |
transfer_no / request_no | string | 平台代付单号 / 原商户请求号。 |
method | string | 实际代付方式。 |
recipient_account_masked / recipient_name_masked | string | 脱敏账号 / 姓名,姓名为空时可省略;不返回收款明文。 |
amount / fee_amount | int64 | 本金 / 手续费,均为整数分。 |
currency | string | 固定 CNY。 |
title / remark | string | 标题 / 说明;remark 为空可省略。 |
status | string | 代付状态,见下表。 |
review_mode | string | manual 人工 / automatic 自动。 |
review_status | string | pending 待审、automatic 自动、approved 已通过、rejected 已拒绝、cancelled 已撤销。 |
review_note | string,可省略 | 审核说明。 |
channel_transfer_no | string,可省略 | 通道代付单号,通道提供后返回。 |
confirm_info / confirm_info_type | string,可省略 | 收款人确认参数及类型。url 为确认地址;wechat_package 为包含 mchId、appId、package 的 JSON 字符串。只按已验签结果和对应场景处理,勿在公开日志记录。 |
fail_reason | string,可省略 | 失败或未知原因,不能仅凭其文本判断交易终态。 |
funding_mode | string,可省略 | 订单分账代付返回 order_profit_sharing。 |
funding_order_count | int,可省略 | 使用的来源订单数量,0 时可省略。 |
funding_success_amount | int64,可省略 | 来源订单中已成功分账的合计金额,整数分;0 时可省略。整体成功仍以 status 为准。 |
created_at / updated_at | string | RFC3339 时间,带时区,可含小数秒。 |
submitted_at / paid_at | string | 首次提交通道 / 成功时间。未发生时可能为零时间 0001-01-01T00:00:00Z;客户端须同时结合状态,兼容字段缺省。 |
| status | 含义与处理 |
|---|---|
pending_review | 等待平台审核,尚未向通道付款。 |
processing | 通道处理中,继续查询原单。 |
confirming | 等待收款人确认;确认链接打开或 SDK 确认完成不等于到账。 |
unknown | 结果未知,不是失败;保留原单继续查单,不新建重复代付。 |
success | 平台已确认代付成功;核对原请求号和金额后更新本地记录。 |
failed / rejected / cancelled | 失败 / 审核拒绝 / 已撤销,为终态。 |
选择收银台支付方式
发起会话支付 · POST /cashier/pay
这是商户服务端主动为已有收银台会话选择支付方式、创建支付订单的签名接口,适用于自有付款方式选择页面。直接引导用户访问 cashier_url 的普通接入,不必再调用本接口;平台收银台会完成选择。发起支付不表示付款成功。
{
"session_no": "SESSION_NO_FROM_RESPONSE",
"pay_type": "alipay",
"pay_mode": "native",
"client_ip": "203.0.113.10"
}
| 业务字段 | 类型 / 必填 | 规则 |
|---|---|---|
session_no | string / 是 | 原样使用创建会话返回的 session_no;必须属于签名商户,尚未过期且状态为 created。 |
pay_type | string / 条件必填 | 如 alipay、wxpay,须已开通。会话未限定方式时必填;会话已限定方式时可省略并继承该值,提供时必须与会话相同。 |
pay_mode | string / 否 | 默认 native;可用模式与直接下单相同,取决于商户路由和插件实际支持。不要仅根据客户端自行假定可用场景。 |
client_ip | string / 否 | 真实付款人 IPv4 或 IPv6;未传或空串则沿用会话 client_ip。示例保留地址只说明格式,应替换为实际地址。 |
金额、币种、商户订单号、标题、通知地址和回跳地址继承原会话,不能通过本接口修改。支付订单仅使用会话剩余有效期,不会重新获得完整有效期。商户、码牌权限及相关通道能力仍须有效。
返回业务对象
返回支付订单对象,与 /pay、/query 同结构,不是收银台会话对象。示例展示成功发起、尚未支付的响应:
{
"order_no": "ACGP_DEMO_001",
"merchant_order_no": "DEMO_ORDER_001",
"pay_type": "alipay",
"pay_mode": "native",
"subject": "示例商品",
"amount": 100,
"currency": "CNY",
"fee_amount": 0,
"status": "paying",
"pay_info": "https://pay.example.com/DEMO_ONLY",
"pay_info_type": "qr",
"trace_id": "TRACE_ID",
"expired_at": "2026-09-30T10:10:00+08:00",
"paid_at": "0001-01-01T00:00:00Z",
"created_at": "2026-09-30T10:00:00+08:00",
"updated_at": "2026-09-30T10:00:00+08:00"
}
响应字段:order_no、merchant_order_no、pay_type、pay_mode、subject、currency、status、trace_id 为字符串;amount、fee_amount 为整数分;expired_at、created_at、updated_at、paid_at 为 RFC3339 时间。可选字符串为 channel_order_no、description、pay_info、pay_info_type。未付款时 paid_at 可为零时间;过期或不可用的表单支付信息可能被隐藏。付款入口处理和状态说明见直接下单、查询订单。
支付宝小程序 JSAPI
小程序下单 · POST /alipay/mini/create
商户服务端使用平台签名信封调用本接口。小程序先调用 my.getAuthCode({ scopes: 'auth_base' }),将 authCode 交给自己的商户服务端。平台在所选支付通道的小程序 AppID 下兑换授权码,使用 JSAPI_PAY 创建交易,兼容新版 OpenID 和旧版 UID;通道 AppID 必须与客户端小程序一致。小程序支付与支付宝内网页的 jspay 是独立场景。
{"merchant_order_no":"MINI_ORDER_001","subject":"小程序商品","amount":100,"currency":"CNY","expire_seconds":600,"auth_code":"AUTH_CODE_FROM_MY_GETAUTHCODE","mini_app_id":"YOUR_ALIPAY_MINI_APP_ID","notify_url":"https://merchant.example.com/notify"}
| 字段 | 类型 / 必填 | 规则 |
|---|---|---|
auth_code | string / 是 | my.getAuthCode 返回的一次性授权码,最多 2048 字符。平台不接受商户自报 buyer_id 或 OpenID。 |
mini_app_id | string / 是 | 当前小程序 AppID,必须与路由选中通道的 AppID 一致;通道需开通 JSAPI 支付并启用 miniapp。 |
merchant_order_no、subject、amount | string、string、integer / 是 | 商户订单号最多 64 字符,标题最多 128 字符,金额为正整数分;沿用 /pay 的金额上限及幂等规则。 |
currency、expire_seconds、description、scene、client_ip、device_id、code_plate_id、notify_url、return_url | 沿用 /pay / 否 | 币种默认 CNY;通知与回跳域名、商户权限、路由、风险规则仍须通过。pay_type、pay_mode 由接口固定为 alipay、miniapp。 |
返回与 /pay 相同的签名订单业务对象,其中 pay_mode=miniapp、pay_info_type=mini_program,pay_info 与 channel_order_no 是支付宝交易号。商户服务端验平台签名后把交易号交给小程序,调用 my.tradePay({ tradeNO: tradeNo })。私钥、平台签名和上游授权凭据只能由服务端保管。客户端 success 或 resultCode=9000 不能直接交付,最终以平台支付成功通知或 /query 的 paid 为准。
支付结果通知
支付成功后,平台以 POST application/json 请求商户的 notify_url。这是平台主动通知商户,不是需要商户调用的平台接口。
通知沿用平台签名响应信封,外层 code=0,业务对象包括:
{
"notify_id": "PAY_PLATFORM_ORDER_NO_SUCCESS",
"notify_type": "payment.success",
"order_no": "PLATFORM_ORDER_NO",
"merchant_order_no": "DEMO_ORDER_002",
"channel_order_no": "CHANNEL_ORDER_NO",
"pay_type": "alipay",
"pay_mode": "native",
"subject": "示例商品",
"amount": 100,
"currency": "CNY",
"fee_amount": 0,
"status": "paid",
"paid_at": "2026-01-01T00:00:00Z",
"trace_id": "TRACE_ID"
}
- 保留原始通知 JSON,使用可信平台公钥验签;核对外层 AppID、版本、算法及事件类型。
- 核对商户订单号、平台订单号、金额、币种与支付方式,确认
notify_type=payment.success且status=paid。 - 在本地事务中更新订单并执行幂等交付,用
notify_id或平台订单号与事件建立唯一约束。 - 本地事务成功后,返回 HTTP 2xx,正文为纯文本
success;已处理的重复通知也返回 success。
金额与手续费均为整数分。不要用手续费倒推或替代应付金额。验签失败、金额不符或本地处理失败时,不返回成功确认。
当前公开 HTTP 业务通知为 payment.success。退款、通道分账及回退、商户内部分账、代付没有本页以外的专用商户 HTTP 通知协议,请使用相应查询接口核对结果;不要等待不存在的事件,或将站内消息当作验签后的资金结果。
支付成功通知可携带与查单一致的 payer_id、payer_id_type、payer_scope、payer_id_source,均属于签名 biz_content。易支付对接插件把已核实付款账号映射为 buyer;无身份时保持 null。管理员手动回调会重新读取当前订单并签名,notify_id 保持不变,商户仍须按订单和事件幂等处理。删除回调历史只隐藏已结束记录,不删除订单、账务或原通知幂等任务;执行中或等待重试的记录不可删除。
错误处理与排查
先看 HTTP 状态,再判断签名响应的 code、msg 和业务 status。下表为常见 HTTP 分类;中间件、代理可能返回非签名错误,客户端不能只按固定中文报错文本分支。
| HTTP 状态 | 常见原因与处理 |
|---|---|
400 | 参数、JSON、时间或业务条件不符。修正前不要循环提交;涉及已发起资金操作时,先按原编号查结果。 |
401 / 403 | 应用、签名、IP、域名、商户权限或能力受限。核对密钥、权限和平台配置,不绕过鉴权重试。 |
404 | 路径或当前商户下的业务记录不存在。确认网关与原编号;一次查无记录不能单独证明资金操作没有发生。 |
409 | 幂等参数冲突、状态变化或并发操作冲突。查询原业务记录,不立即换号再次交易。 |
429 | 触发频率限制。降低频率、退避并错开查询;如有 Retry-After 则遵循提示。 |
5xx / 超时 | 服务暂不可用或结果未知。保留原单号,退避查询并重新签名;不自动新建重复支付、退款、分账或代付。 |
| 现象 | 排查方向 |
|---|---|
| 签名无效 | 检查 AppID 与密钥是否配对,是否误用平台公钥签请求,biz_content 是否在签名后被重排或重新转义。 |
| 时间无效或请求过期 | 校准服务器时间,timestamp 用秒;date 用带时区的 RFC3339,不用无时区日期字符串。 |
| 重复请求被拒绝 | 不要复用原签名。先查原订单,再以原业务编号和参数刷新时间、重新签名。 |
| 订单号已存在但参数不同 | 确认没有把已使用的订单号分配给另一笔交易;不确定付款结果时先查单。 |
| 支付方式不可用 | 确认账户、支付权限、支付方式及场景已开通,通道配置完整。 |
| 未收到通知 | 检查公网连通、TLS、域名登记与防火墙;确认响应没有重定向或附带 HTML,并使用 /query 补偿。 |
求助时提供脱敏订单号、请求时间和 trace_id,不要提供私钥、完整签名请求或付款链接。