当前位置: 首页 > news >正文

微信支付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;
    }
}

相关文章:

  • 【CCF CSP-J 2023】一元二次方程
  • U-Net 与深度学习的完美结合:图像分割的高效解决方案
  • Windows 环境下配置多个不同版本的 Maven
  • Vue3+Vite创造路由
  • Kubernetes的Ingress 资源是什么?
  • 【综合实验】
  • docker修改镜像默认存储路径(基于页面迁移)
  • 跟着 Lua 5.1 官方参考文档学习 Lua (2)
  • 【HarmonyOS NEXT】获取正式应用签名证书的签名信息
  • 基于 Spring Boot + 微信小程序的短文写作竞赛管理系统设计与实现(源码+文档)
  • 《Python在数据可视化中的应用与实践》
  • 在nodejs中使用ElasticSearch(一)安装,使用
  • css主题色修改后会多出一个css吗?css怎么定义变量?
  • C++ day2
  • JVM深入理解
  • 网络安全技术pat实验 网络安全 实验
  • floodfill算法系列一>衣橱整理
  • GPT-SoVITS更新V3 win整合包
  • iOS进程增加内存上限的接口
  • C#发送邮件
  • 10家A股农商行一季报:净利均实现增长,常熟银行营收、净利增速领跑
  • 朝中社:美在朝鲜半岛增兵将进一步增加其本土安全不确定性
  • 特朗普称加总理将很快访美,白宫:不影响将加拿大打造成“第51个州”计划
  • 首部关于民营经济发展的基础性法律,有何亮点?专家解读
  • 新能源车盈利拐点:8家上市车企去年合计净利854亿元,多家扭亏
  • 湖北鄂城:相继4所小学有学生腹泻呕吐,供餐企业负责人已被采取强制措施