Java 小程序 微信支付 APIv3

可能会遇到的问题:

        1.apiclient_key.pem (No such file or directory)

        2.apiclient_key.pem] cannot be resolved to URL because it does not exist

        3.Illegal key size (javaSDK的版本问题,文章末尾)

1. 支付前各种账号准备参考官方文档

2.使用官方推荐的wechatpay-java

3.wechatpat-java地址是github项目,内包含Maven依赖

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

4.官方示例是以 Native 支付为例,我已小程序为例吧。

5.自动更新微信支付平台证书

官方提供使用自动更新和使用本地证书,但本地证书使用不当会出现证书对不上,抛异常,无法支付,所以这里推荐使用自动更新,为了提高性能,建议将配置类作为全局变量,但要慎重,这个操作有难度,初期对接先不要考虑。(最下面注意事项有本地证书使用的官方文档链接)

Config config =
    new RSAAutoCertificateConfig.Builder()
        .merchantId(merchantId)
        .privateKeyFromPath(privateKeyPath)
        .merchantSerialNumber(merchantSerialNumber)
        .apiV3Key(apiV3Key)
        .build();

6.现在java环境下大家都是打jar包,大多数人会把密钥放到项目下,最常见的就是在服务器无法获得密钥文件,解决方法:

        获取文件(方式多种,此次提供一种),通过文件流创建临时文件。

注意:如果你是本地文件,那么其实主要是参数.apiV3Key                    与.wechatPayCertificatesFromPath的差异,我这里的拷贝文件其实是多余的。

public JsapiService init(){
        JsapiService service = null;
        try {
            ClassPathResource keyPath = new ClassPathResource("cert/apiclient_key.pem");
            File keyFile = new File("apiclient_key.pem");
            FileUtils.copyInputStreamToFile(keyPath.getInputStream(),keyFile);

            Config config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKeyFromPath("apiclient_key.pem")
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();

            service = new JsapiService.Builder().config(config).build();
        } catch (HttpException e) { // 发送HTTP请求失败
            // 调用e.getHttpRequest()获取请求打印日志或上报监控,更多方法见HttpException定义
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控,更多方法见ServiceException定义
        } catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
            // 调用e.getMessage()获取信息打印日志或上报监控,更多方法见MalformedMessageException定义
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return service;
    }

7.定义了JsapiService其实就可以通过调用SDK里面的prepay进行统一下单了。

public String prepay(BigDecimal price, String orderId,String openId) {
        PrepayRequest request = new PrepayRequest();
        request.setAppid(appID);
        request.setMchid(merchantId);
        request.setDescription("商城");
        request.setOutTradeNo(orderId);
        request.setNotifyUrl("https://");
        // 订单金额
        Amount amount = new Amount();
        BigDecimal total = price.multiply(new BigDecimal(100));
        amount.setTotal(total.intValue());
        amount.setCurrency("CNY");
        request.setAmount(amount);
        //支付者
        Payer payer = new Payer();
        payer.setOpenid(openId);
        request.setPayer(payer);
        return init().prepay(request).getPrepayId();
    }

关闭订单,查询订单都类似。

8.接下来是前端调起支付的签名问题。

        我这里写了个小程序的,其他的也都很类似,jsapi支付可直接使用。

        按官方签名规则进行RSA和Base64。

public RequestPaymentVo getSigner(RequestPaymentVo requestPaymentVo) {
        try{
            ClassPathResource keyPath = new ClassPathResource("cert/apiclient_key.pem");
            File keyFile = new File("apiclient_key.pem");
            FileUtils.copyInputStreamToFile(keyPath.getInputStream(),keyFile);

            PrivateKey privateKeyPath = PemUtil.loadPrivateKeyFromPath("apiclient_key.pem");
            String message = requestPaymentVo.getAppId() + "\n"
                    + requestPaymentVo.getTimeStamp() + "\n"
                    + requestPaymentVo.getNonceStr() + "\n"
                    + requestPaymentVo.getPrepayId() + "\n";
            Signature sign = Signature.getInstance("SHA256withRSA");
            sign.initSign(privateKeyPath);
            sign.update(message.getBytes());
            requestPaymentVo.setPaySign(Base64.getEncoder().encodeToString(sign.sign()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return requestPaymentVo;
    }

9.接下来就是注意事项,由于加密方式不同,所以对官方在文档最后是有提示的。

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay7_2.shtml

 接下来是遇到的问题:

1.社区有朋友针对提出下载与本地证书,评论区有沟通方式及官方地址,大家可以做参考

https://developers.weixin.qq.com/community/develop/doc/000666eb5c0b1051edaf1a26759c00?jumpto=reply&parent_commentid=000e6acb4bccb0cae3afcacde544&commentid=00062ab7ea0af00472207ce946bc

2.本地证书会涉及解密保存,官方文档解密内容

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_2.shtml

3.找不到证书文件的社区提问

https://developers.weixin.qq.com/community/pay/doc/00022cac9fc940656b20bab8a61000

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值