平台收付通(分账)开发指引
更新时间:2024.12.30# 1. 接口规则
为了在保证支付安全的前提下,带给商户简单、一致且易用的开发体验,我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考APIv3接口规则。
# 2. 开发准备
# 2.1. 搭建和配置开发环境
开发者应当依据自身的编程语言来构建并配置相应的开发环境。
# 2.2. 业务开发配置-分账
需分账的订单,平台在下单时需预先打上分账标识“profit_sharing”,详细可查看各场景下单API(普通支付下单/合单支付下单API)。
# 3. 快速接入
# 3.1. 业务流程图-分账

重要步骤说明:
步骤1 平台通过添加分账接收方API添加需要分账的分账对象(接收方)。
步骤2 平台预先在合单支付/普通支付下单API接口中上传分账标识“profit_sharing”,待订单完成支付后即可调用请求分账API接口发起分账请求。
步骤3 分账完成后,微信会通过分账动账通知API接口,主动通知商户。商户如有需要,可以通过查询分账结果API接口,主动查询分账结果。
步骤4 分账后若产生退款,则需先调用请求分账回退API 接口,请求将已经分给分账方的资金回退,再处理退款。
步骤5 分账回退完成后,微信同样会通过分账动账通知API接口,主动通知商户。商户也可以通过查询分账回退结果API接口,主动查询分账结果。
步骤6: 分账结束后,商户需调用完结分账API接口结束分账订单。
# 3.2. API接入-分账
本文档展示了如何使用微信支付服务端 SDK 快速接入平台收付通产品,完成与微信支付对接的部分。
注意
- 文档中的代码示例是用来阐述 API 基本使用方法,代码中的示例参数需替换成商户自己账号及请求参数才能跑通。
- 以下接入步骤仅提供参考,请商户结合自身业务需求进行评估、修改。
# 3.2.1.【服务端】添加分账接收方
步骤说明: 平台可通过此接口添加分账接收方,建立分账接收方列表。后续通过发起分账请求,将平台下的二级商户结算后的资金,分给分账接收方列表中具体的分账接收方。
1public void AddProfitsharingReceivers() throws Exception{23 //请求URL4 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/receivers/add");5 // 请求body参数6 String reqdata = "{"7 + "\"appid\":\"wx8888888888888888\","8 + "\"type\":\"MERCHANT_ID\","9 + "\"account\":\"190001001\","10 + "\"name\":\"张三网络公司\","11 + "\"relation_type\":\"SUPPLIER\""12 + "}";13 StringEntity entity = new StringEntity(reqdata,"utf-8");14 entity.setContentType("application/json");15 httpPost.setEntity(entity);16 httpPost.setHeader("Accept", "application/json");1718 //完成签名并执行请求19 CloseableHttpResponse response = httpClient.execute(httpPost);2021 try {22 int statusCode = response.getStatusLine().getStatusCode();23 if (statusCode == 200) { //处理成功24 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));25 } else if (statusCode == 204) { //处理成功,无返回Body26 System.out.println("success");27 } else {28 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));29 throw new IOException("request failed");30 }31 } finally {32 response.close();33 }34}
1use GuzzleHttp\Exception\RequestException;2use WechatPay\GuzzleMiddleware\WechatPayMiddleware;3use WechatPay\GuzzleMiddleware\Util\PemUtil;4use GuzzleHttp\HandlerStack;56try {7 $resp = $client->request(8 'POST',9 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/receivers/add', //请求URL10 [11 // JSON请求体12 'json' => [13 "appid" => "wx8888888888888888",14 "type" => "MERCHANT_ID",15 "account" => "190001001",16 "name" => "张三网络公司",17 "relation_type" => "SUPPLIER",18 ],19 'headers' => [ 'Accept' => 'application/json' ]20 ]21 );22 $statusCode = $resp->getStatusCode();23 if ($statusCode == 200) { //处理成功24 echo "success,return body = " . $resp->getBody()->getContents()."\n";25 } else if ($statusCode == 204) { //处理成功,无返回Body26 echo "success";27 }28} catch (RequestException $e) {29 // 进行错误处理30 echo $e->getMessage()."\n";31 if ($e->hasResponse()) {32 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";33 }34 return;35}
更多参数、响应详情及错误码请参见添加分账接收方API接口文档。
# 3.2.2.【服务端】请求分账
步骤说明: 平台,如有订单需要进行分账,可通过此接口完成。
1public void Profitsharing() throws Exception{23 //请求URL4 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders");5 // 请求body参数6 String reqdata = "{"7 + "\"sub_mchid\":\"1900000109\","8 + "\"transaction_id\":\"4208450740201411110007820472\","9 + "\"out_order_no\":\"P20150806125346\","10 + "\"receivers\": ["11 + "{"12 + "\"type\":\"MERCHANT_ID\","13 + "\"receiver_account\":\"1900000110\","14 + "\"receiver_mchid\":\"1900000110\","15 + "\"amount\":100,"16 + "\"description\":\"分给商户1900000110\""17 + "}"18 + "],"19 + "\"finish\":true"20 + "}";21 StringEntity entity = new StringEntity(reqdata,"utf-8");22 entity.setContentType("application/json");23 httpPost.setEntity(entity);24 httpPost.setHeader("Accept", "application/json");2526 //完成签名并执行请求27 CloseableHttpResponse response = httpClient.execute(httpPost);2829 try {30 int statusCode = response.getStatusLine().getStatusCode();31 if (statusCode == 200) { //处理成功32 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));33 } else if (statusCode == 204) { //处理成功,无返回Body34 System.out.println("success");35 } else {36 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));37 throw new IOException("request failed");38 }39 } finally {40 response.close();41 }42}
1try {2 $resp = $client->request(3 'POST',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders', //请求URL5 [6 // JSON请求体7 'json' => [8 "sub_mchid" => "1900000109",9 "transaction_id" => "4208450740201411110007820472",10 "out_order_no" => "P20150806125346",11 "receivers" => [12 [13 "type" => "MERCHANT_ID",14 "receiver_account" => "1900000110",15 "receiver_mchid" => "1900000110",16 "amount" => 100,17 "description" => "分给商户1900000110",18 ],19 ],20 "finish" => true,21 ],22 'headers' => [ 'Accept' => 'application/json' ]23 ]24 );25 $statusCode = $resp->getStatusCode();26 if ($statusCode == 200) { //处理成功27 echo "success,return body = " . $resp->getBody()->getContents()."\n";28 } else if ($statusCode == 204) { //处理成功,无返回Body29 echo "success";30 }31} catch (RequestException $e) {32 // 进行错误处理33 echo $e->getMessage()."\n";34 if ($e->hasResponse()) {35 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";36 }37 return;38}
更多参数、响应详情及错误码请参见请求分账API接口文档。
# 3.2.3.【服务端】分账动账通知
步骤说明: 此功能仅针对分账接收方,当分账动账金额发生变动时,微信会把相关变动结果发送给需要实时关注的分账接收方。
注意
- 支付结果通知是以POST 方法访问商户设置的通知URL,通知的数据以JSON 格式通过请求主体(BODY)传输。通知的数据包括了加密的支付结果详情。
- 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名,并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名,以确认请求来自微信,而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》。
- 支付通知HTTP应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。
- 商户成功接收到回调通知后应返回成功的HTTP应答码为200或204。
- 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
更多参数、响应详情及错误码请参见分账动账通知API接口文档。
# 3.2.4. 【服务端】查询分账结果
步骤说明: 平台可通过此接口实时关注订单的分账请求和分账完结情况。
1public void QueryProfitsharing() throws Exception{23 //请求URL4 HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders?sub_mchid=1900000109&transaction_id=4208450740201411110007820472&out_order_no=P20150806125346");5 httpGet.setHeader("Accept", "application/json");67 //完成签名并执行请求8 CloseableHttpResponse response = httpClient.execute(httpGet);910 try {11 int statusCode = response.getStatusLine().getStatusCode();12 if (statusCode == 200) { //处理成功13 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));14 } else if (statusCode == 204) { //处理成功,无返回Body15 System.out.println("success");16 } else {17 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));18 throw new IOException("request failed");19 }20 } finally {21 response.close();22 }23}
1try {2 $resp = $client->request(3 'GET',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders?sub_mchid=1900000109&transaction_id=4208450740201411110007820472&out_order_no=P20150806125346', //请求URL5 [6 'headers' => [ 'Accept' => 'application/json']7 ]8 );9 $statusCode = $resp->getStatusCode();10 if ($statusCode == 200) { //处理成功11 echo "success,return body = " . $resp->getBody()->getContents()."\n";12 } else if ($statusCode == 204) { //处理成功,无返回Body13 echo "success";14 }15} catch (RequestException $e) {16 // 进行错误处理17 echo $e->getMessage()."\n";18 if ($e->hasResponse()) {19 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";20 }21 return;22}
更多参数、响应详情及错误码请参见 查询分账结果API接口文档。
# 3.2.5. 【服务端】请求分账回退
步骤说明: 订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款。
1public void Demo() throws Exception{23 //请求URL4 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/returnorders");5 // 请求body参数6 String reqdata = "{"7 + "\"sub_mchid\":\"1900000109\","8 + "\"order_id\":\"3008450740201411110007820472\","9 + "\"out_order_no\":\"P20150806125346\","10 + "\"out_return_no\":\"R20190516001\","11 + "\"return_mchid\":\"86693852\","12 + "\"amount\":10,"13 + "\"description\":\"分账回退\""14 + "}";15 StringEntity entity = new StringEntity(reqdata,"utf-8");16 entity.setContentType("application/json");17 httpPost.setEntity(entity);18 httpPost.setHeader("Accept", "application/json");1920 //完成签名并执行请求21 CloseableHttpResponse response = httpClient.execute(httpPost);2223 try {24 int statusCode = response.getStatusLine().getStatusCode();25 if (statusCode == 200) { //处理成功26 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));27 } else if (statusCode == 204) { //处理成功,无返回Body28 System.out.println("success");29 } else {30 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));31 throw new IOException("request failed");32 }33 } finally {34 response.close();35 }36}
1try {2 $resp = $client->request(3 'POST',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/returnorders', //请求URL5 [6 // JSON请求体7 'json' => [8 "sub_mchid" => "1900000109",9 "order_id" => "3008450740201411110007820472",10 "out_order_no" => "P20150806125346",11 "out_return_no" => "R20190516001",12 "return_mchid" => "86693852",13 "amount" => 10,14 "description" => "分账回退",15 ],16 'headers' => [ 'Accept' => 'application/json' ]17 ]18 );19 $statusCode = $resp->getStatusCode();20 if ($statusCode == 200) { //处理成功21 echo "success,return body = " . $resp->getBody()->getContents()."\n";22 } else if ($statusCode == 204) { //处理成功,无返回Body23 echo "success";24 }25} catch (RequestException $e) {26 // 进行错误处理27 echo $e->getMessage()."\n";28 if ($e->hasResponse()) {29 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";30 }31 return;32}
更多参数、响应详情及错误码请参见请求分账回退API 接口文档。
# 3.2.6. 【服务端】查询分账回退结果
步骤说明: 商户需要核实回退结果,可调用此接口查询回退结果;如果分账回退接口返回状态为处理中,可调用此接口查询回退结果。
1public void QueryFallbackProfitsharing() throws Exception{23 //请求URL4 HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/returnorders?sub_mchid=1900000109&out_order_no=P20150806125346&out_return_no=R20190516001");5 httpGet.setHeader("Accept", "application/json");67 //完成签名并执行请求8 CloseableHttpResponse response = httpClient.execute(httpGet);910 try {11 int statusCode = response.getStatusLine().getStatusCode();12 if (statusCode == 200) { //处理成功13 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));14 } else if (statusCode == 204) { //处理成功,无返回Body15 System.out.println("success");16 } else {17 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));18 throw new IOException("request failed");19 }20 } finally {21 response.close();22 }23}
1try {2 $resp = $client->request(3 'GET',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/returnorders?sub_mchid=1900000109&out_order_no=P20150806125346&out_return_no=R20190516001', //请求URL5 [6 'headers' => [ 'Accept' => 'application/json']7 ]8 );9 $statusCode = $resp->getStatusCode();10 if ($statusCode == 200) { //处理成功11 echo "success,return body = " . $resp->getBody()->getContents()."\n";12 } else if ($statusCode == 204) { //处理成功,无返回Body13 echo "success";14 }15} catch (RequestException $e) {16 // 进行错误处理17 echo $e->getMessage()."\n";18 if ($e->hasResponse()) {19 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";20 }21 return;22}
更多参数、响应详情及错误码请参见查询分账回退结果API 接口文档。
# 3.2.7. 【服务端】完结分账
步骤说明: 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给二级商户。
1public void FinishProfitsharing() throws Exception{23 //请求URL4 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/finish-order");5 // 请求body参数6 String reqdata = "{"7 + "\"sub_mchid\":\"1900000109\","8 + "\"transaction_id\":\"4208450740201411110007820472\","9 + "\"out_order_no\":\"P20150806125346\","10 + "\"description\":\"分账完结\""11 + "}";12 StringEntity entity = new StringEntity(reqdata,"utf-8");13 entity.setContentType("application/json");14 httpPost.setEntity(entity);15 httpPost.setHeader("Accept", "application/json");1617 //完成签名并执行请求18 CloseableHttpResponse response = httpClient.execute(httpPost);1920 try {21 int statusCode = response.getStatusLine().getStatusCode();22 if (statusCode == 200) { //处理成功23 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));24 } else if (statusCode == 204) { //处理成功,无返回Body25 System.out.println("success");26 } else {27 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));28 throw new IOException("request failed");29 }30 } finally {31 response.close();32 }33}
1try {2 $resp = $client->request(3 'POST',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/finish-order', //请求URL5 [6 // JSON请求体7 'json' => [8 "sub_mchid" => "1900000109",9 "transaction_id" => "4208450740201411110007820472",10 "out_order_no" => "P20150806125346",11 "description" => "分账完结",12 ],13 'headers' => [ 'Accept' => 'application/json' ]14 ]15 );16 $statusCode = $resp->getStatusCode();17 if ($statusCode == 200) { //处理成功18 echo "success,return body = " . $resp->getBody()->getContents()."\n";19 } else if ($statusCode == 204) { //处理成功,无返回Body20 echo "success";21 }22} catch (RequestException $e) {23 // 进行错误处理24 echo $e->getMessage()."\n";25 if ($e->hasResponse()) {26 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";27 }28 return;29}
更多参数、响应详情及错误码请参见完结分账API接口文档。
# 3.2.8. 【服务端】查询订单剩余待分金额
步骤说明: 分账接口支持对一笔订单进行多次分账,在这过程中,你可以使用该接口查询订单剩余的可进行分账的金额。
1public void QueryProfitsharingAmounts() throws Exception{23 //请求URL4 HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders/4208450740201411110007820472/amounts");5 httpGet.setHeader("Accept", "application/json");67 //完成签名并执行请求8 CloseableHttpResponse response = httpClient.execute(httpGet);910 try {11 int statusCode = response.getStatusLine().getStatusCode();12 if (statusCode == 200) { //处理成功13 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));14 } else if (statusCode == 204) { //处理成功,无返回Body15 System.out.println("success");16 } else {17 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));18 throw new IOException("request failed");19 }20 } finally {21 response.close();22 }23}
1try {2 $resp = $client->request(3 'GET',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders/4208450740201411110007820472/amounts', //请求URL5 [6 'headers' => [ 'Accept' => 'application/json']7 ]8 );9 $statusCode = $resp->getStatusCode();10 if ($statusCode == 200) { //处理成功11 echo "success,return body = " . $resp->getBody()->getContents()."\n";12 } else if ($statusCode == 204) { //处理成功,无返回Body13 echo "success";14 }15} catch (RequestException $e) {16 // 进行错误处理17 echo $e->getMessage()."\n";18 if ($e->hasResponse()) {19 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";20 }21 return;22}
更多参数、响应详情及错误码请参见查询订单剩余待分金额API接口文档。
# 3.2.9. 【服务端】删除分账接收方
步骤说明: 平台发起删除分账接收方请求。删除后,不支持将平台下二级商户结算后的资金,分到该分账接收方。
1public void DeleteProfitsharingReceivers() throws Exception{23 //请求URL4 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/receivers/delete");5 // 请求body参数6 String reqdata = "{"7 + "\"appid\":\"wx8888888888888888\","8 + "\"type\":\"MERCHANT_ID\","9 + "\"account\":\"190001001\""10 + "}";11 StringEntity entity = new StringEntity(reqdata,"utf-8");12 entity.setContentType("application/json");13 httpPost.setEntity(entity);14 httpPost.setHeader("Accept", "application/json");1516 //完成签名并执行请求17 CloseableHttpResponse response = httpClient.execute(httpPost);1819 try {20 int statusCode = response.getStatusLine().getStatusCode();21 if (statusCode == 200) { //处理成功22 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));23 } else if (statusCode == 204) { //处理成功,无返回Body24 System.out.println("success");25 } else {26 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));27 throw new IOException("request failed");28 }29 } finally {30 response.close();31 }32}
1try {2 $resp = $client->request(3 'POST',4 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/receivers/delete', //请求URL5 [6 // JSON请求体7 'json' => [8 "appid" => "wx8888888888888888",9 "type" => "MERCHANT_ID",10 "account" => "190001001",11 ],12 'headers' => [ 'Accept' => 'application/json' ]13 ]14 );15 $statusCode = $resp->getStatusCode();16 if ($statusCode == 200) { //处理成功17 echo "success,return body = " . $resp->getBody()->getContents()."\n";18 } else if ($statusCode == 204) { //处理成功,无返回Body19 echo "success";20 }21} catch (RequestException $e) {22 // 进行错误处理23 echo $e->getMessage()."\n";24 if ($e->hasResponse()) {25 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";26 }27 return;28}
更多参数、响应详情及错误码请参见 删除分账接收方API接口文档。