> 技术文档 > 微信支付V3平台证书切换成公钥遇到的问题。【无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥】【 Illegal base64 character 2d】_无可用的平台证书,请在商户平台-api安全申请使用微信支付公钥

微信支付V3平台证书切换成公钥遇到的问题。【无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥】【 Illegal base64 character 2d】_无可用的平台证书,请在商户平台-api安全申请使用微信支付公钥


第一个问题,使用正常的V3支付,返回无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥

报错如下

httpResponseBody[{\"code\":\"RESOURCE_NOT_EXISTS\",\"message\":\"无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥。可查看指引https://pay.weixin.qq.com/docs/merchant/products/platform-certificate/wxp-pub-key-guide.html\"}]

解决办法:
首先因为因为我们使用了微信公钥调起支付,商户可使用微信支付的公钥验证应答和回调的签名,可使用微信支付公钥和公钥ID初始化。所以不能使用原来的RSAAutoCertificateConfig来创建支付配置,而要使用RSAPublicKeyConfig。支付的maven从0.2.12升级到0.2.14才有RSAPublicKeyConfig。
在微信支付Github也更新了最新的微信V3公钥支付的调用:wechatpay-java

  • 旧依赖和代码
    maven
  com.github.wechatpay-apiv3 wechatpay-java 0.2.12 

代码

Config config = new RSAAutoCertificateConfig.Builder() .merchantId(merchantId) .merchantSerialNumber(merchantSerialNumber) .privateKeyFromPath(privateKeyPath) .apiV3Key(apiV3Key) .build();
  • 新的依赖和代码

依赖

 com.github.wechatpay-apiv3 wechatpay-java 0.2.14

代码

Config config = new RSAPublicKeyConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .publicKeyFromPath(publicKeyPath) .publicKeyId(publicKeyId) .merchantSerialNumber(merchantSerialNumber) .apiV3Key(apiV3Key) .build();

第二个问题,以上改好发送获取支付的链接,报错:java.lang.IllegalArgumentException: Illegal base64 character 2d

异常部分有用完整报文:

java.lang.IllegalArgumentException: Illegal base64 character 2dat java.util.Base64$Decoder.decode0(Base64.java:714)at java.util.Base64$Decoder.decode(Base64.java:526)at java.util.Base64$Decoder.decode(Base64.java:549)at com.wechat.pay.java.core.util.PemUtil.loadPublicKeyFromString(PemUtil.java:90)at com.wechat.pay.java.core.util.PemUtil.loadPublicKeyFromPath(PemUtil.java:128)at com.wechat.pay.java.core.RSAPublicKeyConfig$Builder.publicKeyFromPath(RSAPublicKeyConfig.java:96)at com.zhjs.service.impl.TestPay.nativePay(TestPay.java:75)at com.zhjs.controller.TestController.test(TestController.java:32)at com.zhjs.controller.TestController$$FastClassBySpringCGLIB$$f90b7656.invoke()at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)

报错原因和解决办法
原因是:.publicKeyFromPath(publicKeyPath)输入公钥路径的时候我输入是apiclient_cert.pem,所以导致报错,用错证书了。
解决办法:去下载V3的公钥pub_key.pem。

下载的步骤如下图:
请添加图片描述
请添加图片描述
原代码:

/** * 公钥路径 */private String publicKeyPath = \"data/testPay/apiclient_cert.pem\";

新代码

/** * 公钥路径 */private String publicKeyPath = \"data/testPay/pub_key.pem\";

换成新的公钥pub_key.pem的路径就可以正常吊起支付了

完整代码

次测试使用的是Native下单
代码做个参考

public class TestPay { /** * 商户号 */ private String merchantId = \"xxxxxxx\"; /** * 私钥路径 */ private String privateKeyPath = \"data/testPay/apiclient_key.pem\"; /** * 公钥路径 */ private String publicKeyPath = \"data/testPay/pub_key.pem\"; /** * 商户APIv3密钥公钥 */ private String publicKeyId = \"xxxxxx\"; /** * 商户API证书序列号 */ private String merchantSerialNumber = \"xxxxxxxx\"; /** * APIv3密钥 */ private String apiV3Key = \"xxxxxxxxxx\"; /** * appid */ private String appId = \"xxxxxxxx\"; /** * Native下单 */ public Map nativePay() { //创建支付配置 Config config = new RSAPublicKeyConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .publicKeyFromPath(publicKeyPath) .publicKeyId(publicKeyId) .merchantSerialNumber(merchantSerialNumber) .apiV3Key(apiV3Key) .build(); //1.0创建支付服务 NativePayService service = new NativePayService.Builder().config(config).build(); //2.0创建预支付请求体 PrepayRequest prepayRequest = new PrepayRequest(); prepayRequest.setAppid(appId); //appid prepayRequest.setMchid(merchantId); //商户号 //2.1 商品描述 prepayRequest.setDescription(\"test\"); //2.2 todo 商户订单号 随机生成Utility.generateRandomString(16)是随机生成的 换成你自己的 prepayRequest.setOutTradeNo(Utility.generateRandomString(16)); //2.3 支付超时时间 prepayRequest.setTimeExpire(Utility.getTimeFactory()); //2.4 todo 回调地址 prepayRequest.setNotifyUrl(\"https://www.baidu.com/xxxxxx\"); //2.5 todo 附加信息 创建一个 JSON 对象 不需要可以删除 JSONObject jsonObjectAttach = new JSONObject(); jsonObjectAttach.put(\"orId\", \"xxx\"); jsonObjectAttach.put(\"orStatus\", \"xxxx\"); prepayRequest.setAttach(jsonObjectAttach.toJSONString()); //2.6订单金额 Amount amount = new Amount(); //金额 1=0.01 amount.setTotal(100); amount.setCurrency(\"CNY\"); prepayRequest.setAmount(amount); //3.0 调用接口 PrepayResponse prepay = service.prepay(prepayRequest); //打印支付结果 System.out.println(prepay); Map map = new HashMap(); map.put(\"data\",prepay.getCodeUrl()); return map; }}