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

第一个问题,使用正常的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
 <dependency>
      <groupId>com.github.wechatpay-apiv3</groupId>
      <artifactId>wechatpay-java</artifactId>
      <version>0.2.12</version>
 </dependency>

代码

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

依赖

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>0.2.14</version>
</dependency>

代码

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 2d
	at 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(<generated>)
	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<String, Object> 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<String, Object> map = new HashMap<>();
        map.put("data",prepay.getCodeUrl());
        return map;
    }
}

### 解决微信支付API RESOURCE_NOT_EXISTS无可平台证书问题 对于新申请微信商户号,确实存在不再支持旧版平台证书的情况[^1]。这意味着任何依赖于这些证书来完签名验证或其他安全操作的应用程序都需要调整其逻辑。 #### 使用公钥模式替代传统证书机制 为了适应这一变化并继续正常处理支付求,建议采用基于公钥的方式来进行数据加密和解密工作: - **获取公钥**:通过官方渠道获得最新的公钥文件,并将其集到现有系统中用于后续的安全校验流程。 - **修改代码实现**:针对`binarywang`框架中的具体应用场景,可能需要自定义部分功能模块以兼容新的认证方式。例如,在初始化阶段跳过原有的证书加载过程而直接读取预存好的公钥信息;或者重写某些涉及敏感信息传输的服务端接口以便能够正确解析由客户端发送过来的数据包。 ```java // 假设这是Java环境下对原有代码片段所做的改动之一 public class CustomizedPaymentService { private static final String PUBLIC_KEY_PATH = "path/to/public/key"; public void init() throws Exception { // 不再尝试加载本地存储的传统型.p12格式证书 // Instead, load the provided RSA public key directly. Security.addProvider(new BouncyCastleProvider()); FileInputStream fis = new FileInputStream(PUBLIC_KEY_PATH); byte[] encodedPublicKey = IOUtils.toByteArray(fis); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey); KeyFactory kf = KeyFactory.getInstance("RSA"); PublicKey pubKey = kf.generatePublic(publicKeySpec); // 将pubKey设置给其他需要用到的地方... } } ``` #### 更新至最新版本SDK 考虑到开发者社区反馈以及官方文档说明,强烈推荐升级至最新型号的WeChat Pay SDK版本。新版库通常包含了更多优化特性和支持更广泛的功能集,同时也修复了一些已知漏洞或错误行为。这有助于减少因环境差异带来的潜在冲突风险。 ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值