微信支付升级V3接口总结:
主要步骤如下:
- 首先需要获取所需要的证书、私钥、秘钥等信息
- 简化加签验签,使用微信提供的支付sdk工具
- 根据sdk demo中的实例,提供所需要的信息,使用微信提供的http方法进行接口请求
一、获取证书、私钥、秘钥等信息
开发需要让运营联系财务在微信后台对V3秘钥的获取和证书的下载,具体教程请参考:
证书:https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
秘钥:https://kf.qq.com/faq/180830E36vyQ180830AZFZvu.html
通过如上步骤之后会获取到如下信息: 商户号、apiKey3 APIv3 密钥、apiclient_cert.pem、apiclient_key.pem、apiclient_cert.p12、证书使用说明.txt
二、获取微信支付sdk
sdk对应的github地址:https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient
maven依赖:
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.3</version>
</dependency>
创建加密后的HttpClient:
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
.withWechatPay(wechatpayCertificates);
// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
HttpClient httpClient = builder.build();
// 后面跟使用Apache HttpClient一样
HttpResponse response = httpClient.execute(...);
参数说明:
`` merchantId ``商户号。
`` merchantSerialNumber ``商户API证书的证书序列号。
`` merchantPrivateKey ``商户API私钥,如何加载商户API私钥请看<a href="https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient#%E5%A6%82%E4%BD%95%E5%8A%A0%E8%BD%BD%E5%95%86%E6%88%B7%E7%A7%81%E9%92%A5" rel="noopener" target="_blank">常见问题</a>。
`` wechatpayCertificates ``微信支付平台证书。你也可以使用后面章节提到的“<a href="https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient#%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0%E8%AF%81%E4%B9%A6%E5%8A%9F%E8%83%BD" rel="noopener" target="_blank">自动更新证书功能</a>”,而不需要关心平台证书的来龙去脉。
merchantSerialNumber为证书序列号需要通过命令获取: openssl x509 -in apiclient_cert.pem -noout -serial 命令进行获取
merchantPrivateKey通过apiclient_key.pem文件获取,注意需要对证书内容进行清洗,具体代码如下:
/**
* 获取私钥。
*
* [@param](/user/param) filename 私钥文件路径 (required)
* [@return](/user/return) 私钥对象
*/
public static PrivateKey getPrivateKey(String filename) throws IOException {
String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
try {
String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(
new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持RSA", e);
} catch (InvalidKeySpecException e) {
throw new RuntimeException("无效的密钥格式");
}
}
wechatpayCertificates是最难理解,我也没理解明白,大概意思是为了让商户自己来完成证书的自动更新和自动下载,但是首次使用的不是财务同学从微信商户后台下载下来的apiclient_key.pem或者apiclient_cert.p12,需要我们手动的下载一次,微信提供了下载证书的jar包CertificateDownloader.jar,
下载地址为:https://github.com/EliasZzz/CertificateDownloader/releases
使用说明参考:https://github.com/wechatpay-apiv3/CertificateDownloader
具体命令: java -jar CertificateDownloader.jar -k 76a5e*********_____9eccd3arh66 -m --mchid=122_____801 -f --privatekey=apiclient_key.pem -s --serialno=4B2882**********************CD03 -o --output=newCerDir -c apiclient_cert.pem
此时会在newCerDir下载到新的证书,至此,我们HttpClient所需要的所有参数都已经获取成功。
三、参考微信sdk中提供的demo请求示例为:
PrivateKey privateKey = getPrivateKey("$filePath");
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant("12*****801", "4B********CD03", privateKey)
.withWechatpay(Arrays.asList(getCertificate(new FileInputStream(new File("${filePath}/newCerDir/wechatpay_22A***********0733515.pem")))));
URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/merchant/fund/balance/BASIC");
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type","application/json; charset=utf-8");
HttpClient httpClient = builder.build();
HttpResponse response = httpClient.execute(httpGet);
response.getEntity()
参考的文档比较多的,比较详细的文档为:https://developers.weixin.qq.com/community/develop/article/doc/000cca8440c6a0dca61a3efb053c13
再次鸣谢作者,和此文档差异的地方是,本文使用的是微信提供的java SDK这种比较简单的方式,