1. 开发前准备
1.1. 熟悉微信支付接口规则
正式进入开发前,开发者需要先阅读基本规则、如何签名和验签,了解调用微信支付接口的基本规则和签名、验签规则。
1.2. 准备开发参数
在发起接口请求时,开发者还需传入一些必要参数,如服务商商户号、服务商API证书私钥、公钥等,获取方式详见:服务商模式开发必要参数说明。
| 注意事项: 开发联调阶段,调用接口后,建议在日志中保留应答的HTTP头Request-ID值,Request-ID作为请求的唯一标识,在调用接口遇到问题时,可向微信侧提供该值用于快速定位到请求记录,协助排查问题原因。 |
|
2. 整体业务开发流程概览
图片上传:服务商需先调用「图片上传」接口上传入驻申请资料中的图片文件;
资料提交:服务商调用「提交入驻申请」接口提交入驻申请,申请提交成功后将开启管理员授权确认和资料审核两个并行流程;
管理员授权确认:服务商调用「根据业务申请编号查询申请状态」或「根据申请单ID查询申请状态」接口获取管理员授权确认二维码,管理员扫码完成授权确认流程,流程包括以下三个子流程:
管理员信息确认:管理员初次扫授权码需要核对身份信息,签署平台协议;
主体意愿确认:管理员身份与商家主体的法人不一致时,则需要进行主体意愿确认,管理员需联系主体法人操作完成,一般有法人扫码和上行打款两种方式,完成其中任意一项即可;
服务商授权:管理员可选择授权的权限给服务商,服务商后续可代品牌完成对应功能的操作和管理。
资料审核:支付侧人工审核入驻申请资料;
开号:支付侧系统为品牌开号。
整体主业务流程如下图所示:

3. 品牌入驻申请单状态流转图
入驻申请流程分为两条并行线路,状态机呈现为串行,便于理解整体流转顺序,以下为具体流转说明:
1、初步校验阶段:服务商调用「提交入驻申请」接口提交入驻申请资料后,申请单会先流转为“未提交”(applyment_state: APPLYMENT_STATE_UNSUBMITTED)状态,系统会初步校验申请资料是否符合规范:
2、并行处理阶段:申请单进入“待主体意愿确认”状态后,以下两个流程同时启动:
2.1、管理员授权确认:服务商需调用「根据业务申请编号查询申请状态」或「根据申请单ID查询申请状态」接口获取品牌经营管理员授权二维码链接,供管理员进行授权确认。在管理员授权确认流程中有三个子流程:管理员信息确认、意愿确认和服务商授权。其中主体意愿确认环节是否存在需根据如下条件判断:
完成主体意愿确认环节之后,申请单会流转为“资料审核中”(applyment_state: APPLYMENT_STATE_WAITING_AUDIT)状态。
2.2、支付侧审核:支付侧同时会对申请资料进行人工审核:
3、品牌开号阶段:“待授权确认”状态的申请单需要管理员完成所有授权流程后才能扭转为“开号中”(applyment_state: APPLYMENT_STATE_OPEN_ACCOUNT)状态,之后支付侧系统将完成最后的开号流程,完成后申请单自动流转为“开号完成”(applyment_state: APPLYMENT_STATE_FINISH)状态。
特殊状态说明:
“审核驳回”态的申请单可修改资料后调用「提交入驻申请」接口重新提交入驻申请,申请单会再次流转为“未提交”(applyment_state: APPLYMENT_STATE_UNSUBMITTED)状态,重新开始新的入驻流程,注意如果资料初步校验通过,仍然需要进行管理员授权确认和主体意愿确认流程。
“开号中”状态之前的申请单,服务商可调用「撤销入驻申请」接口撤销申请,管理员可在授权页点击“拒绝品牌注册”按钮撤销申请,申请单将流转为“已撤销”(applyment_state:APPLYMENT_STATE_CANCELED)状态。
以下两个状态为终态:
4. 接口接入说明
4.1. API接口概览
|
必须接入 | 提交入驻申请 | 服务商通过该接口提交商家资料,帮助商家入驻成为微信支付的品牌商家。 注意:本接口不支持进件境外个人小微商户 频率限制:接口级限制1/s |
撤销入驻申请 | 服务商提交申请后需要进行撤销操作时,可调用该撤销申请接口。 注意:仅当申请状态为初始化、未提交、待主体意愿确认、审核中、已驳回时才允许撤销。 频率限制:接口级限制1/s 前置条件:已提交入驻申请 |
根据业务申请编号查询申请状态 | 服务商可使用业务申请编号调用该接口查询入驻申请状态,获取管理员授权链接。 频率限制:接口级限制50/s 前置条件:已提交入驻申请 |
根据申请单ID查询申请状态 | 服务商可使用业务申请编号调用该接口查询入驻申请的状态,获取管理员授权链接。 频率限制:接口级限制50/s 前置条件:已提交入驻申请 |
4.2. API接入(含示例代码)
文档展示了如何使用微信支付服务端 SDK 快速接入品牌入驻申请,完成与微信支付对接的部分。
4.2.1. 【服务端】提交入驻申请
步骤说明: 服务商收集商户申请资料后,调用提交入驻申请接口,提交创建入驻申请单。
JAVA

1public void Applyment() throws Exception {
2
3 PrivateKey merchantPrivateKey = PemUtil
4 .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
5
6
7 AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
8 new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
9
10 CloseableHttpClient httpClient = HttpClients.createDefault();
11
12 httpClient = WechatPayHttpClientBuilder.create()
13 .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
14 .withValidator(new WechatPay2Validator(verifier)).build();
15
16
17 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/brand/applyments");
18
19 String reqdata = "{"
20 + "\"business_code\":\"1111111111\","
21 + "\"admin_info\": {"
22 + "\"admin_name\":\"wRNIsXOvVuTYIhVxZJCD8uJIGmNPGozCe44Ph8rD+QAJEPxw==\","
23 + "\"id_doc_type\":\"IDENTIFICATION_TYPE_MAINLAND_ID_CARD\","
24 + "\"id_card_number\":\"rjbq82xBwMixDGA5A4x6/hqZRAYmaeM+yyjn9BU8qUBZga+mKqQ==\""
25 + "},"
26 + "\"subject_info\": {"
27 + "\"subject_type\":\"SUBJECT_TYPE_ENTERPRISE\","
28 + "\"subject_name\":\"xx有限公司\","
29 + "\"unified_social_credit_code\": \"91310101MA1FPX1234\""
30 + "},"
31 + "\"brand_basic_info\": {"
32 + "\"brand_name\": \"爱马哥\","
33 + "\"brand_logo\": \"V1_RmiTYG0bm7Qrdg659tbD2HZDcD8XWK-bliSsXX4ylAMiiWMmDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL\""
34 + "},"
35 + "\"trademark\": {"
36 + "\"trademark_exists\": \"TRADEMARK_EXISTS\","
37 + "\"trademark_registration_certificate\": {"
38 + "\"certificate\": \"V1_RmiTYG0bm7Qrdg65xUdNJB4oT9tbD2HZDcD8XWK-bliSsXXgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL\","
39 + "\"name\": \"爱马哥\","
40 + "\"number\": \"12345678\","
41 + "\"valid_begin_time\": \"2025-10-01\","
42 + "\"valid_end_time\": \"长期\","
43 + "\"international_class\": \"43\","
44 + "\"holder\": \"xx有限公司\","
45 + "\"license\": \"V1_RmiTYG0bm7Qrdg65xUdNJB4oT9tbD2HZDcD8XWK-bliSsXXgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL\","
46 + "\"authorization_begin_time\": \"2025-10-01\","
47 + "\"authorization_end_time\": \"2035-10-01\""
48 + "},"
49 + "\"logo_trademark_registration_certificate\": {"
50 + "\"certificate\": \"V1_RmiTYG0bm7Qrdg65xUdNJB4oT9tbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL\","
51 + "\"name\": \"爱马哥\","
52 + "\"number\": \"12345678\","
53 + "\"valid_begin_time\": \"2025-10-01\","
54 + "\"valid_end_time\": \"长期\","
55 + "\"international_class\": \"43\","
56 + "\"holder\": \"xx有限公司\","
57 + "\"license\": \"V1_RmiTYG0bm7Qrdg65xUdNJB4oT9tbD2HZDcD8XWK-bliSsXXgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL\","
58 + "\"authorization_begin_time\": \"2025-10-01\","
59 + "\"authorization_end_time\": \"2035-10-01\""
60 + "},"
61 + "\"no_trademark_addition_prove\": \"V1_RmiTYG0bm7Qrdg65xUdNJB4oT9tbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKSnBL\""
62 + "}"
63 + "}";
64 StringEntity entity = new StringEntity(reqdata,"utf-8");
65 entity.setContentType("application/json");
66 httpPost.setEntity(entity);
67 httpPost.setHeader("Accept", "application/json");
68
69
70 CloseableHttpResponse response = httpClient.execute(httpPost);
71
72 try {
73 int statusCode = response.getStatusLine().getStatusCode();
74 if (statusCode == 200) {
75 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
76 } else if (statusCode == 204) {
77 System.out.println("success");
78 } else {
79 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
80 throw new IOException("request failed");
81 }
82 } finally {
83 response.close();
84 }
85}PHP

1示例代码
2 try {
3 $resp = $client->request(
4 'POST',
5 'https://api.mch.weixin.qq.com/v3/brand/applyments',
6 [
7
8 'json' => [
9 'business_code' => '1111111111',
10 'admin_info' => [
11 'admin_name' => 'wRNIsXOvVuTYIhVxZJCD8uJIGmNPGozCe44Ph8rD+QAJEPxw==',
12 'id_doc_type' => 'IDENTIFICATION_TYPE_MAINLAND_ID_CARD',
13 'id_card_number' => 'rjbq82xBwMixDGA5A4x6/hqZRAYmaeM+yyjn9BU8qUBZga+mKqQ==',
14 ],
15 'subject_info' => [
16 'subject_type' => 'SUBJECT_TYPE_ENTERPRISE',
17 'subject_name' => 'xx有限公司',
18 'unified_social_credit_code' => '91310101MA1FPX1234',
19 ],
20 'brand_basic_info' => [
21 'brand_name' => '爱马哥',
22 'brand_logo' => 'V1_RmiTYG0bm7Qrdg659tbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXvgDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL',
23 ],
24 'trademark' => [
25 'trademark_exists' => 'TRADEMARK_EXISTS',
26 'trademark_registration_certificate' => [
27 'certificate' => 'V1_RmiTYG0bm7Qrdg65xtbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL',
28 'name' => '爱马哥',
29 'number' => '12345678',
30 'valid_begin_time' => '2025-10-01',
31 'valid_end_time' => '长期',
32 'international_class' => '43',
33 'holder' => 'xx有限公司',
34 'license' => 'V1_RmiTYG0bm7Qrdg65xtbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL',
35 'authorization_begin_time' => '2025-10-01',
36 'authorization_end_time' => '2035-10-01',
37 ],
38 'logo_trademark_registration_certificate' => [
39 'certificate' => 'V1_RmiTYG0bm7Qrdg65xUdNJB4oT9tbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL',
40 'name' => '爱马哥',
41 'number' => '12345678',
42 'valid_begin_time' => '2025-10-01',
43 'valid_end_time' => '长期',
44 'international_class' => '43',
45 'holder' => 'xx有限公司',
46 'license' => 'V1_RmiTYG0bm7Qrdg65xtbD2HZDcD8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKcnyfisSnBL',
47 'authorization_begin_time' => '2025-10-01',
48 'authorization_end_time' => '2035-10-01',
49 ],
50 'no_trademark_addition_prove' => 'V1_RmiTYG0bm7Qrdg65xUdNJB4oT8XWK-bliSsXX4ylAMiiWMm2YXv-gDDIgs0LPp2g5bcH4yj8UCPbHhCQxYfQ9hsKSnBL',
51 ],
52 ],
53 'headers' => [ 'Accept' => 'application/json' ]
54 ]
55 );
56 $statusCode = $resp->getStatusCode();
57 if ($statusCode == 200) {
58 echo "success,return body = " . $resp->getBody()->getContents()."\n";
59 } else if ($statusCode == 204) {
60 echo "success";
61 }
62} catch (RequestException $e) {
63
64 echo $e->getMessage()."\n";
65 if ($e->hasResponse()) {
66 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
67 }
68 return;
69}business_code: 业务申请编号,服务商自定义的唯一编号,每个编号对应一个申请单。
id_doc_type: 管理员证件类型,不支持护照和外国人居住证类型。枚举值:
IDENTIFICATION_TYPE_MAINLAND_ID_CARD:中国大陆居民-身份证
IDENTIFICATION_TYPE_HONGKONG:中国香港居民--来往内地通行证
IDENTIFICATION_TYPE_MACAO:中国澳门居民--来往内地通行证
IDENTIFICATION_TYPE_TAIWAN:中国台湾居民--来往大陆通行证
IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT:港澳居民居住证
IDENTIFICATION_TYPE_TAIWAN_RESIDENT:台湾居民居住证
subject_type: 主体类型。枚举值:
unified_social_credit_code: 社会统一信用代码。校验规则:
请填写营业执照上的注册号。
注册号格式须为15位数字或18位数字|大写字母。
brand_logo: 品牌logo。
holder: 商标注册人。
4.2.2. 【服务端】撤销入驻申请
步骤说明: 服务商提交申请后,开号未完成前需要进行撤销操作时,可调用该撤销申请接口。
JAVA

1public void CancelApplyment() throws Exception{
2
3 PrivateKey merchantPrivateKey = PemUtil
4 .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
5
6
7 AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
8 new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
9
10 CloseableHttpClient httpClient = HttpClients.createDefault();
11
12 httpClient = WechatPayHttpClientBuilder.create()
13 .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
14 .withValidator(new WechatPay2Validator(verifier)).build();
15
16
17 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/brand/applyments/cancel-applyment");
18
19 String reqdata = "{"
20 + "\"business_code\":\"1111111111\","
21 + "\"applyment_id\": \"1234567\""
22 + "}";
23 StringEntity entity = new StringEntity(reqdata,"utf-8");
24 entity.setContentType("application/json");
25 httpPost.setEntity(entity);
26 httpPost.setHeader("Accept", "application/json");
27
28
29 CloseableHttpResponse response = httpClient.execute(httpPost);
30
31 try {
32 int statusCode = response.getStatusLine().getStatusCode();
33 if (statusCode == 200) {
34 System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
35 } else if (statusCode == 204) {
36 System.out.println("success");
37 } else {
38 System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
39 throw new IOException("request failed");
40 }
41 } finally {
42 response.close();
43 }
44}PHP

1try {
2 $resp = $client->request(
3 'POST',
4 'https://api.mch.weixin.qq.com/v3/brand/applyments/cancel-applyment',
5 [
6
7 'json' => [
8 'business_code' => '1111111111',
9 'applyment_id' => '1234567',
10 ],
11 'headers' => [ 'Accept' => 'application/json' ]
12 ]
13 );
14 $statusCode = $resp->getStatusCode();
15 if ($statusCode == 200) {
16 echo "success,return body = " . $resp->getBody()->getContents()."\n";
17 } else if ($statusCode == 204) {
18 echo "success";
19 }
20} catch (RequestException $e) {
21
22 echo $e->getMessage()."\n";
23 if ($e->hasResponse()) {
24 echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
25 }
26 return;
27}4.2.3. 【服务端】根据业务申请编号查询申请状态
步骤说明: 根据业务申请编号查询申请单申请状态。
JAVA

1public void QueryApplyment() throws Exception{
2
3 PrivateKey merchantPrivateKey = PemUtil
4 .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
5
6
7 AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
8 new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
9
10 CloseableHttpClient httpClient = HttpClients.createDefault();
11
12 httpClient = WechatPayHttpClientBuilder.create()
13 .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
14 .withValidator(new WechatPay2Validator(verifier)).build();
15
16
17 HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/brand/applyments/business-code/1111111111");
18 httpGet.setHeader("Accept", "application/json");
19
20
21 CloseableHttpResponse response = httpClient.execute(httpGet);
22
23 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) {
28 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}PHP

1try {
2 $resp = $client->request(
3 'GET',
4 'https://api.mch.weixin.qq.com/v3/brand/applyments/business-code/1111111111',
5 [
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) {
13 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}4.2.4. 【服务端】根据申请单ID查询申请状态
步骤说明: 根据申请单ID查询申请单申请状态。
JAVA

1public void QueryApplyment() throws Exception{
2
3 PrivateKey merchantPrivateKey = PemUtil
4 .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
5
6
7 AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
8 new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
9
10 CloseableHttpClient httpClient = HttpClients.createDefault();
11
12 httpClient = WechatPayHttpClientBuilder.create()
13 .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
14 .withValidator(new WechatPay2Validator(verifier)).build();
15
16
17 HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/brand/applyments/applyment-id/1234567");
18 httpGet.setHeader("Accept", "application/json");
19
20
21 CloseableHttpResponse response = httpClient.execute(httpGet);
22
23 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) {
28 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}PHP

1try {
2 $resp = $client->request(
3 'GET',
4 'https://api.mch.weixin.qq.com/v3/brand/applyments/applyment-id/1234567',
5 [
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) {
13 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}