private synchronized void downloadAndUpdateCert(Verifier verifier) {
try (CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
.withCredentials(credentials)
.withValidator(verifier == null ? (response) -> true
: new WechatPay2Validator(verifier))
.build()) {
HttpGet httpGet = new HttpGet(CERT_DOWNLOAD_PATH);
httpGet.addHeader(ACCEPT, APPLICATION_JSON.toString());
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
int statusCode = response.getStatusLine().getStatusCode();
String body = EntityUtils.toString(response.getEntity());
if (statusCode == SC_OK) {
Map<BigInteger, X509Certificate> newCertList = CertSerializeUtil.deserializeToCerts(apiV3Key, body);
if (newCertList.isEmpty()) {
log.warn("Cert list is empty");
return;
}
certificates.clear();
certificates.putAll(newCertList);
} else {
log.error("Auto update cert failed, statusCode = {}, body = {}", statusCode, body);
}
}
} catch (IOException | GeneralSecurityException e) {
log.error("Download Certificate failed", e);
}
}
只是BUG修改加大概流程,有少部分人自己开发可能参考不上,但是如果使用官方git实例,大概能用上。
微信支付核心三件套,
//核心 验签 verifier的构建
ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
new WechatPay2Credentials(wxMchid
, new PrivateKeySigner(wxMchkey, merchantPrivateKey))
, v3Key.getBytes("utf-8"));
// 请求client的构建
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(wxMchid, wxMchkey, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier));
需要三个关键参数和一个文件
wxmchid 微信商户号ID
wxMchkey 证书序列号
merchantPrivateKey 微信商户支付密匙 (通过apiclient_key.pem文件解密得到 )
v3Key 商户自己设置的ApiV3Key (32位自定义密匙)
首先注意的一点就是 微信下载的整数rar中会存在三个文件,注意区分下需要的apiclient_key.pem 内容是有**-----BEGIN PRIVATE KEY-----** 开头的。
现在V3支付 另外需要的证书信息现在可以通过最上面的代码获取,并且官方写了定时更新。
问题来了,一切都是官方文件但是为什么还能出现 验签失败的问题呢?
问题一。apiclient_key.pem 文件信息不对,首先会出现解密失败异常。
··· 这个不用看官方的论坛,没有一个解决办法,有的也是老的V2版,这个文件直接从rar中获取的不需要在做额外的操作。···
问题二。获取证书后解密会失败,但并没有任何异常,会正常去验签。
··· 我们项目中的证书没通过测试,有时候能获取到对的证书,会正常通过验签,但是官方的verifier类中 证书是一个list存在,这就导致了第一次获取不到但是verifier类的证书对象已经写入了内存,对象不为空并不会去重新过去证书。
我的解决办法是直接验证证书的list size ,而不是证书的对象是否为Null
···
问题三。java.security.InvalidKeyException: Illegal key size。
··· 解密私钥或者证书的时候都可能会出现该异常,如果出现了反而好办 ··· 这个问题是解密的信息长度过长 ,根据美国那头法规还是什么的限制,需要自己去 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html 下载解除限制jar, 下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt 如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件 如果安装了JDK,还要将两个jar文件也放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。
一般这个问题出现,证明解密过程有问题,并不一定是支付中间会出现的问题
上面四个要素如果全部对应一般网上扒的流程都不会出现问题,而且微信回调不成功不会影响支付流程的~!!!