1. 接口规则
为了在保证支付安全的前提下,带给商户简单、一致且易用的开发体验,我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考APIv3接口规则。
2. 开发准备
2.1. 搭建和配置开发环境
开发者应当依据自身的编程语言来构建并配置相应的开发环境。
2.2. 业务开发配置
1、微信支付分的相关配置参数在商户入驻的过程中都已经配置完成(前往查看配置相关内容),例如授权结果回调URL、service_notify_url、测试白名单、免确认订单模式的权限等。
2、如果发现配置信息有误,请主动联系微信支付分运营同学协助修改,或者点击右侧导航栏进入在线技术客服进行技术咨询。
3. 快速接入
3.1. 业务流程图
业务流程时序图
步骤1 用户在商户侧下单,商户调用后台接口创建支付分订单,通过接口返回获得跳转微信支付分小程序进行订单确认的必填参数“package”
步骤2 调用前端方法跳转至微信,让用户完成确认订单操作
我们通过以下前端方法可调起微信客户端(注意区分场景):
用户确认订单完成,商户系统将收到确认订单回调通知,此时可为用户提供服务;
我们通过以下接口将用户确认订单信息回调通知给商户系统:
在用户确认订单过程中可能出现长时间未收到回调、用户确认失败等情况,商户可先通过后台接口查询订单状态:
根据查询到的订单状态结果,商户可决定是否需要取消当前订单,后台接口为:
步骤3 用户服务结束,商户通过后台接口完结支付分订单;
步骤4 从业机构需要调用微信支付分系统登记扣款信息,之后再调用清算机构受理扣款
如遇到网络、服务器等原因造成无法正常接收扣款成功通知,一般有两种解决方法:
主动查单,通过查询订单API 接口主动查询扣款情况
3.2. API接入(含示例代码)
文档展示了如何使用微信支付服务端 SDK 快速接入商家券产品,完成与微信支付对接的部分。
3.2.1. 【服务端】创建订单
步骤说明: 完成用户授权后,即可创建支付分订单,为用户提供服务了。
1public void CreateServiceOrder() throws Exception{
2
3
4 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/acquiringbank/serviceorder");
5
6 String reqdata = "{"
7 + "\"out_order_no\":\"1234323JKHDFE1243252\","
8 + "\"appid\":\"wxd678efh567hg6787\","
9 + "\"service_id\":\"500001\","
10 + "\"sub_mchid\" : \"10000000\","
11 + "\"sub_appid\":\"wxd678efh567hg6788\","
12 + "\"channel_id\":\"12121212\","
13 + "\"service_introduction\":\"某某酒店\","
14 + "\"post_payments\": ["
15 + "{"
16 + "\"name\":\"就餐费用服务费\","
17 + "\"amount\":4000,"
18 + "\"description\":\"就餐人均100元服务费:100/小时\","
19 + "\"count\":1"
20 + "}"
21 + "],"
22 + "\"post_discounts\": ["
23 + "{"
24 + "\"name\":\"满20减1元\","
25 + "\"description\":\"不与其他优惠叠加\""
26 + "}"
27 + "],"
28 + "\"time_range\": {"
29 + "\"start_time\":\"20091225091010\","
30 + "\"end_time\":\"20091225121010\""
31 + "},"
32 + "\"location\": {"
33 + "\"start_location\":\"嗨客时尚主题展餐厅\","
34 + "\"end_location\":\"嗨客时尚主题展餐厅\""
35 + "},"
36 + "\"risk_fund\": {"
37 + "\"name\":\"ESTIMATE_ORDER_COST\","
38 + "\"amount\":10000,"
39 + "\"description\":\"就餐的预估费用\""
40 + "},"
41 + "\"attach\":\"Easdfowealsdkjfnlaksjdlfkwqoi&wl3l2sald\","
42 + "\"notify_url\":\"https://api.test.com\","
43 + "\"need_user_confirm\":true"
44 + "}";
45 StringEntity entity = new StringEntity(reqdata,"utf-8");
46 entity.setContentType("application/json");
47 httpPost.setEntity(entity);
48 httpPost.setHeader("Accept", "application/json");
49
50
51 CloseableHttpResponse response = httpClient.execute(httpPost);
52
53 try {
54 int statusCode = response.getStatusLine().getStatusCode();
55 if (statusCode == 200) {
56 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
57 } else if (statusCode == 204) {
58 System.out.println("success");
59 } else {
60 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
61 throw new IOException("request failed");
62 }
63 } finally {
64 response.close();
65 }
66 }
3.2.2. 【服务端】查询分订单
步骤说明: 一般在创建订单后、订单完结成功后等关键流程中,商户可能有知晓订单状态的需求,此时即可通过该接口查询订单状态。
1public void QueryServiceOrder() throws Exception{
2
3
4 HttpPost httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/payscore/acquiringbank/serviceorder?service_id=2002000000000558128851361561536&sub_mchid=1900000109&channel_id=1230000109&out_order_no=1234323JKHDFE1243252&query_id=15646546545165651651");
5 httpGet.setHeader("Accept", "application/json");
6
7
8 CloseableHttpResponse response = httpClient.execute(httpGet);
9
10 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) {
15 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 }
更多参数、响应详情及错误码请参见 查询订单接口文档
3.2.3. 【服务端】取消订单
步骤说明: 订单为以下状态时可以取消订单:CREATED(已创单)、DOING(进行中)(包括商户完结支付分订单后,且支付分订单收款状态为待支付USER_PAYING)。
1public void CancelServiceOrder() throws Exception{
2
3 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/acquiringbank/serviceorder/{out_order_no}/cancel");
4
5 String reqdata = "{"
6 + "\"sub_mchid\":\"10000000\","
7 + "\"channel_id\":\"10000000\","
8 + "\"service_id\":\"500001\","
9 + "\"reason\":\"用户投诉\""
10 + "}";
11 StringEntity entity = new StringEntity(reqdata,"utf-8");
12 entity.setContentType("application/json");
13 httpPost.setEntity(entity);
14 httpPost.setHeader("Accept", "application/json");
15
16
17 CloseableHttpResponse response = httpClient.execute(httpPost);
18
19 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) {
24 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}
3.2.4. 【服务端】完结订单
步骤说明: 用户服务结束后,商户通过请求完结支付分订单接口,通过微信支付分进行用户扣款操作。
1public void CompleteServiceOrder() throws Exception{
2
3 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/acquiringbank/serviceorder/{out_order_no}/complete");
4
5 String reqdata = "{"
6 + "\"sub_mchid\":\"10000000\","
7 + "\"channel_id\":\"10000000\","
8 + "\"service_id\":\"500001\","
9 + "\"complete_time\":\"2019-11-11T16:24:05+08:00\","
10 + "\"post_payments\": ["
11 + "{"
12 + "\"name\":\"就餐费用服务费\","
13 + "\"amount\":4000,"
14 + "\"description\":\"就餐人均100元服务费:100/小时\","
15 + "\"count\":1"
16 + "}"
17 + "],"
18 + "\"post_discounts\": ["
19 + "{"
20 + "\"name\":\"满20减1元\","
21 + "\"description\":\"不与其他优惠叠加\","
22 + "\"amount\":4000"
23 + "}"
24 + "],"
25 + "\"total_amount\":3900,"
26 + "\"time_range\": {"
27 + "\"start_time\":\"20091225091010\","
28 + "\"end_time\":\"20091225121010\""
29 + "},"
30 + "\"location\": {"
31 + "\"end_location\":\"嗨客时尚主题展餐厅\""
32 + "}"
33 + "}";
34 StringEntity entity = new StringEntity(reqdata,"utf-8");
35 entity.setContentType("application/json");
36 httpPost.setEntity(entity);
37 httpPost.setHeader("Accept", "application/json");
38
39
40 CloseableHttpResponse response = httpClient.execute(httpPost);
41
42 try {
43 int statusCode = response.getStatusLine().getStatusCode();
44 if (statusCode == 200) {
45 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
46 } else if (statusCode == 204) {
47 System.out.println("success");
48 } else {
49 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
50 throw new IOException("request failed");
51 }
52 } finally {
53 response.close();
54 }
55}
3.2.5. 【服务端】登记扣款信息
1public void RegisterDeductInfo() throws Exception{
2
3 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/payscore/acquiringbank/serviceorder/{out_order_no}/registerdeductinfo");
4
5 String reqdata = "{"
6 + "\"sub_mchid\":\"10000000\","
7 + "\"channel_id\":\"10000000\","
8 + "\"service_id\":\"500001\","
9 + "\"appid\":\"wxd678efh567hg6787\","
10 + "\"out_trade_no\": \"1234323JKHDFE1243252\","
11 + "\"sub_appid\":wxd678efh567hg6999"
12 + "}";
13 StringEntity entity = new StringEntity(reqdata,"utf-8");
14 entity.setContentType("application/json");
15 httpPost.setEntity(entity);
16 httpPost.setHeader("Accept", "application/json");
17
18
19 CloseableHttpResponse response = httpClient.execute(httpPost);
20
21 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) {
26 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}
3.2.6. 【服务端】查询扣款信息
1public void QueryDeduction() throws Exception{
2
3
4 HttpPost httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/payscore/acquiringbank/serviceorder/deduction?service_id=2002000000000558128851361561536&appid=wxd678efh567hg6787&sub_mchid=1900000109&sub_appid=wxd678efh567hg6999&channel_id=1230000109&out_order_no=1234323JKHDFE1243252");
5 httpGet.setHeader("Accept", "application/json");
6
7
8 CloseableHttpResponse response = httpClient.execute(httpGet);
9
10 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) {
15 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 }