为了在保证支付安全的前提下,带给商户简单、一致且易用的开发体验,我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则”
为了帮助开发者调用开放接口,我们提供了JAVA、PHP、GO三种语言版本的开发库,封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能(更多语言版本的开发库将在近期陆续提供)
测试步骤:
1、根据自身开发语言,选择对应的开发库并构建项目,具体配置请参考下面链接的详细说明:
• wechatpay-java(推荐)wechatpay-apache-httpclient,适用于Java开发者。
• wechatpay-php(推荐)、wechatpay-guzzle-middleware,适用于PHP开发者
注:当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本
• wechatpay-go,适用于Go开发者
更多资源可前往微信支付开发者社区搜索查看
2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法
@Before
public void setup() throws IOException {
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
}
@After
public void after() throws IOException {
httpClient.close();
}
3、基于接口的示例代码,替换请求参数后可发起测试
说明:
• 上面的开发库为微信支付官方开发库,其它没有审核或者控制下的第三方工具和库,微信支付不保证它们的安全性和可靠性
通过包管理工具引入SDK后,可根据下面每个接口的示例代码替换相关参数后进行快速测试
• 开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现,可阅读下面的详细说明:
1.签名生成
2.签名验证
3.敏感信息加解密
• 如想更详细的了解我们的接口规则,可查看我们的接口规则指引文档
申请单状态变化如下:
重点步骤说明:
步骤1 获取微信支付商户号:渠道商使用银行或者支付机构提供的API或者后台系统录入商家门店信息,获取商家每个门店在微信支付侧的商户号(上送给微信支付的“商户名称”字段必须与营业执照上商户名称一致,具体规则 点击查看 )。
步骤2 查询微信支付商户号授权状态:渠道商使用《获取商户号开户意愿确认状态接口》查询微信支付商户号是否完成开户意愿确认。
步骤5 提交商家资料给微信支付:渠道商根据商家类型(企业、个体户、小微、事业单位、其他组织等)准备好相关的商家资料,使用微信支付接口《提交开户意愿确认申请单》获取微信支付申请单编号。
步骤8 查询申请单审核结果:渠道商提交商家资料后,建议每隔五分钟调用《查询申请单审核结果接口》查询申请单审核结果。
1、提交后申请单状态为“审核中”,微信支付后台会进行审核,审核通过后申请单状态变成“待联系人确认”,同时接口会提供“申请单小程序码” (小程序码的图片)。
2、联系人扫“申请单小程序码”后确认资料无误后,申请单状态变成“待账户验证”。
3、联系人将“法人确认二维码”在微信上发给法人确认后(或打款验证),申请单状态变成“审核通过”。
文档展示了如何使用微信支付服务端 SDK 快速接入商户开户意愿确认产品,完成与微信支付对接的部分。
注意:
步骤说明:服务商收集商户资料后,调用提交申请单接口,提交创建入驻申请单。
示例代码:
public void Applyment() throws Exception {
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3秘钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/apply4subject/applyment");
// 请求body参数
String reqdata = "{"
+ "\"business_code\":\"1111111111\","
+ "\"contact_info\": {"
+ "\"name\":\"wRNIsXOvVuTYIhVxZJCD8uJIGmNPGozCe44Ph8rD+QAJEPxw==\","
+ "\"mobile\":\"w+zPKEVNm7IDxPvK55P0OfNd5E5VXoWbRwyyGk37HiB6C/F2lUog==\","
+ "\"id_card_number\":\"rjbq82xBwMixDGA5A4x6/hqZRAYmaeM+yyjn9BU8qUBZga+mKqQ==\""
+ "},"
+ "\"subject_info\": {"
+ "\"subject_type\":\"SUBJECT_TYPE_ENTERPRISE\","
+ "\"business_licence_info\": {"
+ "\"licence_number\":\"914201123033363296\","
+ "\"licence_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\","
+ "\"merchant_name\":\"李四网络有限公司\","
+ "\"legal_person\":\"李四\","
+ "\"company_address\":\"广东省深圳市南山区xx路xx号\","
+ "\"licence_valid_date\":\"["1970-01-01","forever"]\""
+ "},"
+ "\"certificate_info\": {"
+ "\"cert_type\":\"CERTIFICATE_TYPE_2388\","
+ "\"cert_number\":\"111111111111\","
+ "\"cert_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\","
+ "\"merchant_name\":\"xx公益团体\","
+ "\"legal_person\":\"李四\","
+ "\"company_address\":\"广东省深圳市南山区xx路xx号\","
+ "\"cert_valid_date\":\"["1970-01-01","forever"]\""
+ "},"
+ "\"company_prove_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\","
+ "\"assist_prove_info\": {"
+ "\"micro_biz_type\":\"MICRO_TYPE_STORE\","
+ "\"store_name\":\"大郎烧饼\","
+ "\"store_address_code\":\"440305\","
+ "\"store_address\":\"广东省深圳市南山区xx大厦x层xxxx室\","
+ "\"store_header_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV-4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\","
+ "\"store_indoor_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\""
+ "}"
+ "},"
+ "\"identification_info\": {"
+ "\"identification_type\":\"IDENTIFICATION_TYPE_IDCARD\","
+ "\"identification_name\":\"MZnwEx6zotwIz6ctW2/iQL5z94odwP9sKiFRL8Aii3L4U74RPCPztcJOScaXsaGs82HJNU3K+46ndk7prENiPDw==\","
+ "\"identification_number\":\"ZTnn5dKGCvP4csw4XTLug/+VLB+4R6nxSPQwqSpmPVZtXmye+/3s9O+y32w==\","
+ "\"identification_valid_date\":\"["1970-01-01","forever"]\","
+ "\"identification_front_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV-4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\","
+ "\"identification_back_copy\":\"0P3ng6KTIW4-Q_l2FjKLZuhHjBWoMAjmVtCz7ScmhEIThCaV4BBgVwtNkCHO_XXqK5dE5YdOmFJBZR9FwczhJehHhAZN6BKXQPcs-VvdSo\""
+ "},"
+ "\"addition_info\": {"
+ "\"confirm_mchid_list\": ["
+ "\"20001113\","
+ "\"20001112\""
+ "]"
+ "}"
+ "}";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) { //处理成功
System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
} else if (statusCode == 204) { //处理成功,无返回Body
System.out.println("success");
} else {
System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} finally {
response.close();
}
}
重要入参说明:
• business_code:业务申请编号,服务商自定义的唯一编号,每个编号对应一个申请单。
• subject_type:主体类型。枚举值:
SUBJECT_TYPE_ENTERPRISE:企业
SUBJECT_TYPE_INSTITUTIONS_CLONED:事业单位
SUBJECT_TYPE_INDIVIDUAL:个体工商户
SUBJECT_TYPE_OTHERS:其他组织
SUBJECT_TYPE_MICRO:小微商户
• licence_number:营业执照注册号。
1、请填写营业执照上的注册号。
2、若主体类型为个体工商户或企业,注册号格式须为15位数字或18位数字|大写字母。
• merchant_name:商户名称。
1、个体工商户,不能以“公司”结尾。
2、个体工商户,若营业执照上商户名称为空或为“无”,请填写"个体户+经营者姓名",如“个体户张三”。
• legal_person:法人姓名。
1、只能由中文字符、英文字符、可见符号组成。
2、请填写营业执照的经营者/法定代表人姓名。
注意:
更多参数、响应详情及错误码请参见提交申请单接口文档
步骤说明:服务商提交申请单后需要修改信息时,或者申请单审核结果为“已驳回”时服务商要修改申请材料时,均需要先调用撤销申请单接口。
示例代码:
public void CancelApplyment() throws Exception{
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3秘钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/apply4subject/applyment/20000011111/cancel");
StringEntity entity = new StringEntity("");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) { //处理成功
System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
} else if (statusCode == 204) { //处理成功,无返回Body
System.out.println("success");
} else {
System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} finally {
response.close();
}
}
重要入参说明:
• applyment_id:申请单编号,微信支付分配的申请单号,申请单编号和业务申请编号至少传一个。
• business_code:业务申请编号
1、服务商自定义的唯一编号。
2、每个编号对应一个申请单。
注意:
更多参数、响应详情及错误码请参见撤销申请单接口文档
步骤说明:当服务商提交申请单后,需要定期调用此接口查询申请单的审核状态。
示例代码:
public void QueryApplyment() throws Exception{
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3秘钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/apply4subject/applyment?applyment_id=20000011111");
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpGet);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) { //处理成功
System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
} else if (statusCode == 204) { //处理成功,无返回Body
System.out.println("success");
} else {
System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} finally {
response.close();
}
}
重要入参说明:
• applyment_id:申请单编号,微信支付分配的申请单号,申请单编号和业务申请编号至少传一个。
• business_code:业务申请编号
1、服务商自定义的唯一编号。
2、每个编号对应一个申请单。
注意:
更多参数、响应详情及错误码请参见撤销申请单接口文档
步骤说明:当服务商需要确认微信支付子商户号是否完成确认时,如果调用此接口提到“已授权”状态,则说明该商户号已完成开户意愿确认。
示例代码:
public void QueryMerchantsState() throws Exception{
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3秘钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/apply4subject/applyment/merchants/20000011111/state");
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpGet);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) { //处理成功
System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
} else if (statusCode == 204) { //处理成功,无返回Body
System.out.println("success");
} else {
System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} finally {
response.close();
}
}
重要入参说明:
A1:请求参数“营业执照注册号(licence_number)”填写错误,请填写营业执照上的注册号,若主体类型为个体工商户或企业,注册号格式须为15位数字或18位数字|大写字母
A2:请按照以下几点检查:
1. 系统异常,请使用相同参数稍后重新调用
2. 请求参数错误,请确认参数的大小写、参数名、格式是否与接口文档一致
3. 请求头里面的参数mchid错误,也会报这个错误,请检查确认
A3:请求参数申请单编号(applyment_id)填写错误或没有填写,请填写微信支付分配的申请单号,申请单编号和业务申请编号至少传一个
A4:请按照以下几点检查:
1. Authorization头认证类型或签名信息错误,请严格按照文档要求填写参数
a. Authorization头认证类型目前为WECHATPAY2-SHA256-RSA2048
b. Authorization头签名信息包括发起请求的商户(渠道商)的商户号mchid
商户API证书序列号serial_no,用于声明所使用的证书
请求随机串nonce_str
时间戳timestamp
签名值signature
2. Authorization头参数存在换行,实际数据应在一行
A5:请按照错误提示,到商户平台上申请下载API证书并正确使用,请参考以下几点:
1. 证书获取指引
2. 如何在程序中加载证书
A6:请求参数类型填写错误,正确的参数类型是uint64