接入指南
完成 接入准备 后,商家/服务商可根据本文指引快速接入 商家分帐。
说明:
整体交互流程图
流程说明
绑定分账关系
分账前,商家需先通过 alipay.trade.royalty.relation.bind(分账关系绑定),将分账收入方添加到分账关系集中,分账关系集最多添加 2 万个,绑定分账关系时,不需要商家确认。
下单支付
需要分账的订单为保证分账时商家支付宝余额的资金不被挪用,下单支付 时,商家可在支付接口中传入冻结标识(extend_params.royalty_freeze
),将交易资金预先冻结在商家支付宝余额中,冻结在不可用余额中,直到商家触发解冻或超时自动解冻(系统默认在冻结 30 天后自动解冻)。
分账
交易成功后,商家通过 alipay.trade.order.settle(统一收单交易结算接口)发起分账请求,一笔订单支持多次分账,总分账金额默认不能超过订单总金额(total_amont)的 30%,若分账请求量较大,可选择异步分账接入。
- 同步分账:royalty_mode 无需设置,分账全部同时成功或失败,不触发异步,通过 alipay.trade.order.settle.query(交易分账查询接口)查询分账状态。
- 异步分账:royalty_mode=async,分账允许部分成功部分失败,商家可通过监听 alipay.trade.order.settle.notify(交易分账结果通知)接口接收异步分账通知,获取分账明细和状态。其中,在结果返回中,msg_type = ASYNC_SETTLE_RESULT 代表此通知为异步分账结果通知。
分账解冻
商家下单支付时如果传递了分账冻结标识,则需要对剩余冻结资金解冻。商家通过 alipay.trade.order.settle(统一收单交易结算接口)发起分账请求时传入分账完结标识(royalty_finish=true),则本次分账成功后会自动将剩余资金解冻;同时,商家也可不传入分账条款,只传入分账完结标识完成剩余资金解冻。
- 若商家不主动发起分账解冻请求,系统默认在 30 天后将剩余资金解冻并将解冻结果进行通知。商家可通过监听 alipay.trade.order.settle.notify(交易分账结果通知)接口接收通知消息,其中 msg_type = AUTO_SETTLE_FINISH 代表超期自动分账解冻。
- 商家发起分账解冻后仍可发起分账,商家支付宝余额账号有资金即可分账成功,若余额不足则分账失败。
分账查询
分账请求提交后,可以同步获取到结果。后续如果有需要,可以通过 alipay.trade.order.settle.query(交易分账查询接口)查询分账/退分账状态。
分账剩余金额查询
分账请求前,可以同步获取分账剩余金额结果。如有需求,可通过 alipay.trade.order.onsettle.query(分账剩余金额查询)查询分账剩余金额。
退分账
若已分账资金需要退回,通过 alipay.trade.refund(统一收单交易退款接口)申请分账资金退回。退款接口允许只退分账,具体传参可查看退款接口入参示例。
业务规则
- 支付宝对于最高分账金额有管控:不能超过订单总金额(total_amont)的 30%。如果有更高分账金额诉求,可单独申请。操作路径:登录 商家平台 > 账号中心 > 签约管理 > 商家分账 > 查看详情 > 修改信息。(可通过 alipay.trade.royalty.rate.query(分账比例查询)查询账户最高分账比例)
- 分账绑定和分账操作要求分账收入方支付宝账户必须实名注册,若未实名或注销账户则操作失败。
- 支付收单后需要等待 30s 再发起分账。单个商家分账请求频率最高 30 qps。基于同一笔订单的多次分账请求,建议间隔 3s。
- 使用分账冻结后,分账、退款时优先从冻结余额出资。若冻结余额不足,先将冻结资金全部解冻,从支付宝余额出资。退款同时退分账场景如下。
-
- 退分账金额<退款金额,则出资顺序:退分账资金优先出资,剩余部分按 冻结资金>可用余额 顺序进行补足。
- 退分账请求金额=退款金额,则出资顺序:退分账金额。
- 若冻结资金已解冻,仍可以从余额户发起分账,只要在分账有效期且分账金额不超过最大可分账金额即可发起分账。
- 分账时若接口返回 ACQ.MERCHANT_RISK_LIMIT(商户交易存在风险),建议商家电话联系 4007585858。
- 分账资金流程:交易金额收款到商家支付宝账户后,商家再进行分账,资金由收款账户分账到分账收入方。
分账关系绑定
分账前,商家需要通过 alipay.trade.royalty.relation.bind(分账关系绑定),将分账收入方添加到分账关系集中,绑定分账关系时,不需要分账接收方账户确认。
注意:
- 分账关系绑定接口请求一次最多绑定 20 个账户。
- 分账关系集:1 个分账支出方最多添加绑定 2万 个分账收入方。
- 分账关系解绑后支持退分账。
分账关系维护接口
接口英文/中文名 | 备注 |
---|---|
alipay.trade.royalty.relation.bind(分账关系绑定) | 将分账收入方添加到分账关系集 |
alipay.trade.royalty.relation.unbind(分账关系解绑) | 将分账收入方从分账关系集中移除 |
alipay.trade.royalty.relation.batchquery(分账关系查询) | 查询分账收入方的绑定关系 |
下单支付
商家调用收单支付接口进行收款,只有交易状态 trade_status=TRADE_SUCCESS(交易成功),该笔订单才支持分账。
注意:
- 商家分账前,请使用 alipay.trade.query(统一收单线下交易查询接口)查询交易状态必须为trade_status(交易状态)=TRADE_SUCCESS(交易成功),否则无法分账。
- 为保证下单收款后,商家分账时支付宝余额的资金不被挪用。下单时可选是否使用冻结能力:
- 下单时传入分账冻结标识:支付接口传入冻结标识 royalty_freeze=true,资金收单结算到商家支付宝余额后,会先处于冻结状态,未分账资金需要通过分账接口传入分账完结标识解冻,若商家一直未发起解冻,系统默认在30 天后自动将剩余资金解冻,解冻后仍可发起分账,支付宝余额账户有资金即可分账成功,若余额不足则分账失败。
- 下单时未传入分账冻结标识:支付接口不需要传入 royalty_freeze,资金结算到商家支付宝可用余额,可按需发起分账操作,账户余额充足即可分账成功,若余额不足则分账失败。
支付接口列表
可在以下支付接口中上传 extend_params.royalty_freez=true
用于冻结,若不冻结资金则无需上传该参数。
场景 | 接口英文名 | 接口中文名 | 备注 |
---|---|---|---|
手机网站支付 | alipay.trade.wap.pay | 手机网站支付接口 2.0 | 手机网站支付 |
APP支付 | alipay.trade.app.pay | app 支付接口 2.0 | 手机 app 支付 |
电脑网站支付 | alipay.trade.page.pay | 统一收单下单并支付页面接口 | 电脑网站支付 |
周期扣款 | alipay.trade.pay | 统一收单交易支付接口 | 周期扣款 |
当面付 | alipay.trade.pay | 统一收单交易支付接口 | 当面付条码支付 |
alipay.trade.precreate | 统一收单线下交易预创建 | 当面付扫码支付 | |
alipay.trade.create | 统一收单交易创建接口 | 当面付创建下单 | |
线上资金预授权 | alipay.trade.pay | 统一收单交易支付接口 | 支付宝预授权转支付接口 |
新当面资金授权 | alipay.trade.pay | 统一收单交易支付接口 | 新当面资金授权转支付接口 |
分账流程
交易收单结算到账后,商家可通过 alipay.trade.order.settle(统一收单交易结算接口)进行请求分账。
注意:
-
分账成功后,资金实时转入分账收入方账号。
-
分账请求需明确分账的收入方,分账收入方只支持已实名(个人/企业)支付宝账户,如果转入方账户注销,分账也会失败。
-
分账请求必须传入具体的分账金额,按传入的分账金额进行分账处理,不支持按比率自动分账。
-
总分账金额不能超过 订单金额 * 分账比例(默认 30%)。
-
分账请求频率说明:
-
- 支付成功后建议 30s 后再发起分账。
- 单个商家分账请求频率最高 30 qps。
分账模式
若分账业务较多,可选择异步模式接入,同步/异步接入模式说明:
- 同步模式:调用分账接口后,支付宝实时进行分账处理,分账接口同步返回分账的最终结果。
- 异步模式:调用分账接口后,支付宝先受理分账请求,异步进行分账处理,分账处理结果请通过分账查询接口或者分账异步通知消息获取最终的分账结果。
注意:同一笔交易,如果发起过异步分账,就不能再调用同步分账。两种分账模式,不能在同一笔交易下混用。
同步模式及异步模式差异说明(其它业务规则、资金流、冻结模式处理两者完全一致):
分账接入模式 | 同步模式 | 异步模式 |
---|---|---|
一笔订单最多可以发起多少次分账请求 | 50 次 | 300 次 |
一笔分账请求最多可以传入多少个分账收款方 | 10 个 | 50 个 |
一笔分账请求传入多个分账收款方时,分账失败处理规则 | 一个收款方失败则全部失败,即只能全部成功或全部失败 | 一个收款方失败,其它仍可成功,即可部分成功、部分失败 |
分账结果获取方式 | 以分账同步返回结果为准 | 以分账查询/异步通知结果为准 |
单商家分账请求频率 | 最高 30tps/s | 最高 500tps/s |
模式特点 | 适用分账请求较少场景,技术集成简单 | 适用分账请求较多,需要高分账性能保障的场景 |
重要入参说明
分账只能从交易的收款账户分出,因此不需要在分账接口中传入支出方账户。若传入系统会进行校验,传入账户与交易收款账户不一致会导致分账失败。
关键字段 | 描述 | 备注 |
---|---|---|
royalty_mode | 分账模式 | 同步执行:sync 异步执行:async 不传默认同步执行。 |
royalty_parameters | 正向分账明细信息 | 复杂类型,需要指定资金处理类型 royalty_type 和目标账户 trans_in。 |
--royalty_type | 分账类型 | 分账场景传入:transfer。可为空,为空时默认为分账。 |
--trans_out_type | 支出方账户类型 | 本场景不需要传入。 |
--trans_out | 支出方账户 | 本场景不需要传入。 |
--trans_in_type | 收入方账户类型 | userId:表示是支付宝账号对应的支付宝唯一用户号。loginName:表示是支付宝登录号。 |
--trans_in | 收入方账户 | trans_in_type 传入 userId:本参数为收入方的支付宝账号对应的支付宝唯一用户号,以2088开头的纯16位数字。trans_in_type 传入 loginName:本参数为收入方的支付宝登录号。 |
--amount | 分账金额 | 本次分账要分出的金额。 |
--desc | 分账描述 | 会在分账收入方支付宝账户 余额明细 备注字段中展示。 |
extend_params | ||
--royalty_finish | 分账完结标识 | 完结:true不完结:false |
示例代码
分账场景,同时上送完结标识,将剩余资金解冻。示例代码如下:
curl -X POST \
https://openapi.alipay.com/v3/alipay/trade/order/settle \
-H "authorization: ALIPAY-SHA256withRSA app_id=${appid},timestamp=${now},nonce=${uuid},expired_seconds=600,sign=${sign}" \
-H "alipay-request-id: ${requestid}" \
-H "Content-Type: application/json" \
-d '{
"out_request_no":"20160727001",
"trade_no":"2014030411001007850000672009",
"royalty_parameters":[
{
"royalty_type":"transfer",
"trans_in_type":"userId",
"trans_in":"2088101126708402",
"amount":0.1,
"desc":"分账给2088101126708402"
}
],
"extend_params":{
"royalty_finish":"true"
}
}'
不分账,单独发起完结请求,将剩余资金解冻。示例代码如下:
curl -X POST \
https://openapi.alipay.com/v3/alipay/trade/order/settle \
-H "authorization: ALIPAY-SHA256withRSA app_id=${appid},timestamp=${now},nonce=${uuid},expired_seconds=600,sign=${sign}" \
-H "alipay-request-id: ${requestid}" \
-H "Content-Type: application/json" \
-d '{
"out_request_no":"20160727001",
"trade_no":"2014030411001007850000672009",
"extend_params":{
"royalty_finish":"true"
}
}'
蚂蚁消息:交易分账结果通知
异步分账发送蚂蚁消息 alipay.trade.order.settle.notify(交易分账结果通知),同步分账不触发该蚂蚁消息。
接入说明
- 商家在应用的产品绑定中添加绑定 商家分账 。
- 在开发设置的 FROM 平台订阅 alipay.trade.order.settle.notify(交易分账结果通知)。
- 本消息接口同时支持 HTTP(S) 方式和支持 WebSocket 长连接,若选择 HTTP 接入模式需额外设置 应用网关地址 作为通知接收地址。
- 验签:商家系统接收到异步通知以后,必须通过验签(验证通知中的 sign 参数)来确保支付通知是由支付宝发送的。
-
- 详细验签规则以及自验签流程参考 异步通知验签。
- HTTP(S) 方式官方 SDK 请求接收验签可参考 SDK 接收以及验签示例代码。
异步通知说明具体详见 订阅消息 指引。
消息示例
ISV_GATEWAY_URL?charset=GBK&biz_content=
{
"out_request_no":"20210727001","settle_no":"20210706002530020036530021395831","operation_dt":"2021-05-1609:59:17","royalty_detail_list":[{"operation_type":"transfer","execute_dt":"2021-07-3012:00:00","trans_out":"2088111111111111","trans_out_type":"userId","trans_in":"2088111111111111","trans_in_type":"userId","amount":10.00,"state":"SUCCESS","error_code":"TXN_RESULT_ACCOUNT_BALANCE_NOT_ENOUGH","error_desc":"分账余额不足"}]
}
&msg_method=alipay.trade.order.settle.notify&utc_timestamp=1516797622752&version=1.1&sign_type=RSA2¬ify_id=d275fec564e62af6bedbcee73f3f05fi5x&app_id=2013121700999429&sign=I+Y/lvqYUEEc10EPdpntRhFIQ==
消息验签
在公钥证书模式下,支付宝开放平台 SDK 提供了 AlipaySignature.rsaCertCheckV1
方法,可以使用该方法对通知报文验签。
以 Java 语言为例,按照服务端 SDK 中提供的工具类,进行接收通知及验签,可查看 公钥证书验签示例代码。
// 回调的待验签字符串
String resultInfo = "buyer_id=208****42&total_amount=0.01&body=***试&trade_no=20190329**941025940236¬ify_time=2019-03-29 19:42:04&subject=**电脑网站支付&sign_type=RSA2&charset=UTF-8&auth_app_id=201****222¬ify_type=trade_status_sync&invoice_amount=0.01&out_trade_no=20190329ygyg45484544100003&trade_status=TRADE_SUCCESS&gmt_payment=2019-03-29 19:42:03&version=1.0&point_amount=0.00&sign=your_sign&gmt_create=2019-03-29 19:42:00&buyer_pay_amount=0.01&receipt_amount=0.01&fund_bill_list=[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]&seller_id=208****5&app_id=2014100***22¬ify_id=20190329002221942040**8";
// 验签支付宝公钥证书路径
String alipayPublicCertPath = "your_alipayPublicCertPath";
// 验签字符集
String charset = "utf-8";
// 对待签名字符串数据通过&进行拆分
String[] temp = resultInfo.split("&");
LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
// 把拆分数据放在 Map 集合内
for (int i = 0; i < temp.length; i++) {
String[] arr = temp[i].split("=", 2); //通过"="号分割成2个数据
String[] tempAagin = new String[arr.length]; //再开辟一个数组用来接收分割后的数据
for (int j = 0; j < arr.length; j++) {
tempAagin[j] = arr[j];
}
map.put(tempAagin[0], tempAagin[1]);
}
System.out.println(map);
// 验签方法
/**
* @param params 参数列表(包括待验签参数和签名值sign) key-参数名称 value-参数值
* @param alipayPublicCertPath 验签支付宝公钥证书路径
* @param charset 验签字符集
**/
boolean signVerified = AlipaySignature.rsaCertCheckV1(params, alipayPublicCertPath, charset);
if (signVerified) {
// TODO 验签成功后
System.out.println("success");
} else {
System.out.println("fail");
}
响应值
响应值 | 描述 | 是否重试 |
---|---|---|
fail | 消息获取失败 | 重试 |
success | 消息获取成功 | 不重试 |
退分账流程
商家通过 alipay.trade.refund(统一收单交易退款接口)进行退款、退分账。
注意:
- 当面付、线上资金预授权、新当面资金授权只支持 按退款比例自动退分账。refund_amount 设置退款金额后,等比例退分账,无需上传 refund_royalty_parameters。
示例:订单 100 元,分账 10 元,商家发起退款 10 元时,支付宝自动按照退款比例,等比例退分账 1 元,不需要商家单独传入退分账条款。 - 其它产品必须指定退分账。
-
- 支持仅退分账:refund_amount 可入参为 0,refund_royalty_parameters 传入退分账信息。
- 支持仅退款:refund_amount 设置退款金额,无需上传 refund_royalty_parameters。
- 支持退款退分账:可根据退款要求,设置 refund_amount 和 refund_royalty_parameters 退款信息。
示例:订单 100 元,分账 10 元,商家发起退款 10 元时,支付宝只处理退款 10 元,不会自动进行退分账。商家若需要退分账需要传入退款金额 10 元、退分账金额 1 元。
- 同一笔退分账请求中,有任意一笔退分账失败,则这次请求的全部退分账处理均会失败。
- 退分账默认从分账收入方账号退回,若分账收入方账号余额不足则退分账失败。
- 判断退分账成功:退款接口返回 fund_change=Y 或者 alipay.trade.fastpay.refund.query(统一收单交易退款查询)返回 refund_status=REFUND_SUCCESS。注意:fund_change 只表示本次接口请求是否资金变动,不是指该笔交易是否资金变动。如果第一次退款成功,返回 Y,但是相同参数(如 out_request_no 不变)第二次请求则会返回 N,因此当 fund_change=N 时,建议通过退款查询接口进一步判断。
重要入参说明
关键字段 | 描述 | 备注 |
---|---|---|
refund_amount | 退款金额 | 退款金额为实际退回买家的金额。需要退款则传入具体退款金额,只退分账则退款金额传入 0 即可。 |
refund_royalty_parameters | 复杂类型 | 退分账信息 |
--royalty_type | 分账类型 | 传入:transfer |
--trans_out_type | 支出方账户类型 | userId:表示是支付宝账号对应的支付宝唯一用户号。loginName:表示是支付宝登录号。 |
--trans_out | 支出方账户 | 分账请求中,trans_in 填写的收款账号,即为本次退分账时的支出账号,填写到该字段。 |
--trans_in_type | 收入方账户类型 | 本场景不需要传入 |
--trans_in | 收入方账户 | 本场景不需要传入 |
--amount | 退分账金额 | 传入本次要退分账的金额 |
示例代码
退分账默认退回到交易的收款账户,因此不需要在分账接口中传入退分账的收入账户。若传入系统会进行校验,传入账户与交易收款账户不一致会导致退分账失败。
仅退款
仅退款,不退分账的场景:
curl -X POST \
https://openapi.alipay.com/v3/alipay/trade/refund \
-H "authorization: ALIPAY-SHA256withRSA app_id=${appid},timestamp=${now},nonce=${uuid},expired_seconds=600,sign=${sign}" \
-H "alipay-request-id: ${requestid}" \
-H "Content-Type: application/json" \
-d '{
"trade_no":"2018040321001004090500070489",
"refund_amount":10,
"out_request_no":"refundttss_201804120000001"
}'
仅退分账
不退款,仅退分账的场景:
curl -X POST \
https://openapi.alipay.com/v3/alipay/trade/refund \
-H "authorization: ALIPAY-SHA256withRSA app_id=${appid},timestamp=${now},nonce=${uuid},expired_seconds=600,sign=${sign}" \
-H "alipay-request-id: ${requestid}" \
-H "Content-Type: application/json" \
-d '{
"trade_no":"2018040321001004090500070489",
"refund_amount":0,
"out_request_no":"refundttss_201804120000001",
"refund_royalty_parameters":[
{
"royalty_type":"transfer",
"trans_out":"kaikai@126.com",
"trans_out_type":"loginName",
"amount":20,
"desc":"从kaikai@126.com退分账20元"
}
]
}'
退款&退分账
当面付、线上资金预授权、新当面资金授权退款时,同时退分账场景:
curl -X POST \
https://openapi.alipay.com/v3/alipay/trade/refund \
-H "authorization: ALIPAY-SHA256withRSA app_id=${appid},timestamp=${now},nonce=${uuid},expired_seconds=600,sign=${sign}" \
-H "alipay-request-id: ${requestid}" \
-H "Content-Type: application/json" \
-d '{
"trade_no":"2018040321001004090500070489",
"refund_amount":10,
"out_request_no":"refundttss_201804120000001"
}'
其它产品退款时,同时退分账场景:
curl -X POST \
https://openapi.alipay.com/v3/alipay/trade/refund \
-H "authorization: ALIPAY-SHA256withRSA app_id=${appid},timestamp=${now},nonce=${uuid},expired_seconds=600,sign=${sign}" \
-H "alipay-request-id: ${requestid}" \
-H "Content-Type: application/json" \
-d '{
"trade_no":"2014112611001004680073956707",
"refund_amount":200.12,
"out_request_no":"HZ01RF001",
"refund_royalty_parameters":[
{
"royalty_type":"transfer",
"trans_out":"2088101126765726",
"trans_out_type":"userId",
"amount":0.1,
"desc": "1.1日服务费退回"
}
]
}'
分账查询
商家通过分账接口 alipay.trade.order.settle(统一收单交易结算接口)分账后,可通过 alipay.trade.order.settle.query(交易分账查询接口)查询分账状态。
重要说明
- settle_no、out_request_no 如果同时存在,优先取 settle_no。
- 退分账后,交易分账查询接口暂不支持查询退分账状态。
重要入参说明
参数 | 描述 | 备注 |
---|---|---|
settle_no | 支付宝分账请求单号传入该字段,无需再传外部请求号和支付宝交易号 | 为分账接口同步返回 settle_no |
out_request_no | 外部请求号,需要和 trade_no 一起传入 | 查询分账:分账接口入参的 out_request_no |
trade_no | 支付宝交易号,需要和 out_request_no 一起传入 | 查询分账:分账接口入参的 trade_no |