Java Springboot对接微信支付(JSAPI等)API-V3

作者: ʘᴗʘ发布时间:2021-10-29 20:57 浏览量:1742 点赞:1407 售价:0
Java Springboot对接微信支付(JSAPI等)API-V3
微信支付的接口从V2升级到V3了,作者为了全平台升级到api-V3折腾了一周,发现了很多很多坑,有些是文档太分散不好找,有些是压根没说,得自己猜。现在把工作成果写成教程分享给大家,加快大家对接微信支付V3的速度。
文章:2篇

本文代码绝对可用,本站微信支付就是使用这套代码的!

准备工作

因为微信升级了微信支付的API,从API-V2升级到了API-V3,安全机制方面变动很大,所以在上一篇文章中,我们将整个微信支付API-V3所需要的证书、秘钥之类的封装成了一个HTTP请求类,只要使用这个类调用微信支付的API,即可自动完成所需的安全认证操作。没看的朋友可以点击链接阅读Java Springboot使用OkHttp实现微信支付API-V3签名、证书的管理和使用 。上篇文章中,我们一共封装了四个类,这里简单介绍一下:

  • WxOkHttpUtil 这个类就是我们之后调用微信支付API的HTTP请求类。
  • OkHttpUtil 这个类是上面类的基础,只是简单的HTTP请求封装,没有微信相关的业务逻辑。
  • AesUtilWxCertUtil微信安全机制相关的秘钥、证书加解密类,有兴趣的可以看看,没兴趣的直接粘贴到项目里用就行了。里面的参数介绍,在上一篇文章中。

还有两个POJO类,这里就不解释了,直接粘贴到你的项目中即可。

JSAPI微信下单接口

下单接口都差不多,无非是个别参数有所不同。这里以微信支付JSAPI API-V3接口为例。

新建一个springboot的service(如果你没有使用springboot,那就新建一个静态类),然后编写下单接口的代码,完整代码如下:

package com.coderbbb.book1.service;

import com.coderbbb.book1.utils.WxOkHttpUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

@Service
public class WxPayService {

    public String prePay() throws Exception {

        /**
         * 支付金额
         */
        BigDecimal money = new BigDecimal("10086");

        BigDecimal fen = money.multiply(new BigDecimal("100"));

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

        String timeExpire = format.format(new Date(System.currentTimeMillis() + 300 * 1000));

        /**
         * 改成你的APP_ID
         */
        String appId = "WX_APP_ID";
        /**
         * 商户号
         */
        String mchId = "WX_MCH_ID";

        String notifyUrl = "通知URL,请填写https://开头的完整网址";

        /**
         * 发起支付的用户的OpenID
         */
        String openId = "openid";

        HashMap<String, Object> amountMap = new HashMap<>(1);
        amountMap.put("total", fen.intValue());

        HashMap<String, Object> payerMap = new HashMap<>(1);
        payerMap.put("openid", openId);

        HashMap<String, Object> map = new HashMap<>();
        map.put("appid", appId);
        map.put("mchid", mchId);

        map.put("description", "支付商品描述");
        map.put("out_trade_no", "商户订单号");

        map.put("time_expire", timeExpire);
        map.put("notify_url", notifyUrl);
        map.put("amount", amountMap);
        map.put("payer", payerMap);

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(map);

        String content = WxOkHttpUtil.wxPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", json, null);
        if (content == null) {
            throw new Exception("下单失败");
        }

        JsonNode jsonNode = mapper.readTree(content);
        if (!jsonNode.has("prepay_id")) {
            throw new Exception("下单失败");
        }

        return jsonNode.get("prepay_id").asText();
    }

}

上面的代码中,有些参数需要改成你自己的,这里简单列举一下:

  1. money变量,这个是支付金额,不用解释了吧。
  2. appId变量,这个是从你的微信支付所绑定的公众号复制的。
  3. mchId变量,商户号,从微信支付后台复制。
  4. notifyUrl变量,就是支付成功后,微信通知你的URL。每次支付完成,微信都会访问这个变量里填的URL,来通知你支付结果,是异步通知。同步通知是每次支付完,你调用微信的查单接口,去查结果。
  5. map里的description,商品描述信息,显示在用户支付成功后的账单里。
  6. map里的out_trade_no,商户订单号,就是你自己生成的订单号。长度不超过32位。

调用这个方法之后,会返回一些支付信息,这些支付信息要传给前端,让前端H5网页唤醒微信支付。当用户支付成功之后,微信调用你的notifyUrl来通知你支付成功。

微信JSAPI支付前端代码

JSAPI调起支付API,需要一些参数,微信支付官方文档介绍如下:

Java Springboot对接微信支付(JSAPI等)API-V3

上图所示的所有参数,这里逐一介绍一下:

  • appId:商户申请的公众号对应的appid,由微信支付生成,可在公众号后台查看。若下单时传了sub_appid,可为sub_appid的值。示例值:wx8888888888888888
  • timeStamp:时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。 示例值:1414561699
  • nonceStr:随机字符串,不长于32位。示例值:5K8264ILTKCH16CQ2502SI8ZNMTM67VS
  • package:填写下单接口的返回值即可。上面微信下单接口的代码,返回了一个字符串,填入这里即可。
  • signType:填入RSA
  • paySign:签名。签名方法已经在前面的文章中提供代码了。使用WxCertUtil.rsaSign()方法即可得到签名结果。

演示代码如下:

/**
 * 构造微信前端JSAPI调起支付API的参数
 * @param prePay
 * @return
 */
public WxPayJsDTO getWxPayJsDTO(String prePay) {

    prePay = "prepay_id=" + prePay;

    WxPayJsDTO wxPayJsDTO = new WxPayJsDTO();
    wxPayJsDTO.setPrePay(prePay);
    wxPayJsDTO.setNonceStr(RandomStringUtils.random(21, true, true));
    wxPayJsDTO.setTimeStamp(String.valueOf(System.currentTimeMillis() / 1000));
    wxPayJsDTO.setSignType("RSA");

    String appId = websiteConfigService.getConfig(BaseWebsiteConfig.WX_FWH_APP_ID);

    String signStr = Stream.of(appId, wxPayJsDTO.getTimeStamp(), wxPayJsDTO.getNonceStr(), prePay).collect(Collectors.joining("\n", "", "\n"));

    wxPayJsDTO.setPaySign(WxCertUtil.rsaSign(signStr));

    return wxPayJsDTO;
}

上面的代码简单演示了如何构造前端JSAPI调起支付API的参数,仅供参考。

微信支付异步通知验签

当支付成功后,微信会调用我们的notifyUrl来通知我们。此时,我们需要验证微信携带的签名等信息是否合法。这部分,我们在上篇文章中,已经提供了封装好的验签类WxOkHttpUtil.checkServletRequestSign。使用方法截图如下:

Java Springboot对接微信支付(JSAPI等)API-V3

版权声明:《Java Springboot对接微信支付(JSAPI等)API-V3》为CoderBBB作者「ʘᴗʘ」的原创文章,转载请附上原文出处链接及本声明。

原文链接:https://www.coderbbb.com/articles/27

其它推荐: