使用了证书管理器CertificatesManager,请求时使用其下载后的证书进行了敏感信息加密,但其SDK在验证响应时报错,这SDK还需要在哪设置啥呢?
Caused by: org.apache.http.HttpException: 应答的微信支付签名验证失败
at com.wechat.pay.contrib.apache.httpclient.SignatureExec.executeWithSignature(SignatureExec.java:91)
at com.wechat.pay.contrib.apache.httpclient.SignatureExec.execute(SignatureExec.java:61)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
... 5 common frames omitted
再吐槽一下,这叫SDK?连demo都算不上啊
问题解决,单步调试发现响应的validator和请求使用的不一样,SDK中的withWechatPay这需传递平台密钥而非商户!
以下贴出JAVA SDK需注意事项,没见过这么写SDK的,这些该声明的,不应该是SDK内部要做的事情吗?创意他们抄的很好,但代码,他们连抄都不会!!!!
/* 敏感信息都需要用平台公钥进行加密, RsaCryptoUtil.encryptOAEP("待加密内容", getWechatCertificate(payConfig)) HTTP请求时,header需要带上平台证书信息 CloseableHttpClient client = getClient(payConfig); HttpPost httpost = new HttpPost(URL); // httpost.addHeader("Content-Type", "application/json"); //这个SDK没有声明 httpost.addHeader("Wechatpay-Serial",getWechatCertificate(payConfig).getSerialNumber().toString(16)); client.execute(httpost); */ private WechatPayHttpClientBuilder builder = null; private CloseableHttpClient getClient(PayConfig payConfig) { if (builder == null) { List<X509Certificate> certificates = new ArrayList<>(); certificates.add(getWechatCertificate(payConfig)); // 这里获取平台证书 builder = WechatPayHttpClientBuilder.create() .withMerchant(payConfig.getMerchantId(),payConfig.getMerchantCertificateSerial(), getPrivateKey(payConfig.getMerchantCertificatePath())) //这里需设置商户私钥,私钥可从商户证书中可提取 .withWechatPay(certificates); //使用平台证书,这个会验证响应信息的签名 } return builder.build(); } // 证书管理器 private CertificatesManager certificatesManager = null; // 此方法用于获取平台证书 private X509Certificate getWechatCertificate(PayConfig payConfig) { //PayConfig 中存放了商户ID,商户证书文件地址,商户证书编号,商户APIV3密钥, if (certificatesManager == null) { certificatesManager = CertificatesManager.getInstance(); try { certificatesManager.putMerchant(payConfig.getMerchantId(), new WechatPay2Credentials(payConfig.getMerchantId(), new PrivateKeySigner(payConfig.getMerchantCertificateSerial(), getPrivateKey(payConfig.getMerchantCertificatePath()))), payConfig.getMerchantApiV3Key().getBytes(StandardCharsets.UTF_8)); // 注意这里的key,账户中心》API安全》设置APIv3密钥,这个字符串密钥 } catch (Exception e) { logger.error("init wechat certificate manager error.", e); throw PlatformError.code(BussErrorCode.PAY_KEY_ERROR); } } try { return CertificatesManager.getInstance().getVerifier(payConfig.getMerchantId()).getValidCertificate(); } catch (NotFoundException e) { logger.error("get wechat certificate error.", e); throw PlatformError.code(BussErrorCode.PAY_KEY_ERROR); } } private PrivateKey privateKey = null; private PrivateKey getPrivateKey(String merchantId, String keyFilePath) { if (privateKey != null) { return privateKey; } InputStream inputStream = null; char[] keyPassword = merchantId.toCharArray(); try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); inputStream = new FileInputStream(new File(keyFilePath)); keyStore.load(inputStream, keyPassword); String alias = keyStore.aliases().nextElement(); // 注意要这么获取alias X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); return (PrivateKey) keyStore.getKey(alias, keyPassword); } catch (Exception e) { logger.error("Analyse wechat certificate error.", e); throw PlatformError.code(BussErrorCode.PAY_KEY_ERROR); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { } } } }