springboot 集成 微信支付APIV3

1.准备工作
<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-apache-httpclient</artifactId>
    <version>0.2.1</version>
  </dependency>
  <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
  </dependency>
2.统一下单以及退款单
2.1统一下单
private Map<String, String> wxPay(String openId, BigDecimal consume, Orders orders, String notifyUrl) throws IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
        //WxPayConfig.certPath 为证书存放路径,绝对路径。eg:/root/xx/xx/xx.pem
        PrivateKey privateKey = WxUtils.create().getPrivateKey(WxPayConfig.certPath);
        CloseableHttpClient client = WxUtils.create().client();
        String param = ModelOrder.WxCreateOrder.create()
                .setAmount(new ModelOrder.WxCreateOrder.Amount(consume.intValue(), "CNY"))
                .setMchid(WxPayConfig.mchId)
                .setDescription(orders.getContent())
                .setNotify_url(WxPayConfig.notifyUrl + notifyUrl)
                .setPayer(new ModelOrder.WxCreateOrder.Payer(openId))
                .setOut_trade_no(orders.getCode())
                .setAppid(WxPayConfig.appId).build();
        logger.debug(param);
        Map<String, String> headers = new HashMap<>(3);
        headers.put("Accept", "application/json");
        headers.put("Content-Type", "application/json");
       //参考另一篇文章中的HttpUtils
        String ret = HttpUtils.create().headers(headers).client(client).post(WxUtils.CREATE_ORDER, param);
        ModelOrder.WxCreateOrderResult result = new Gson().fromJson(ret, new TypeToken<ModelOrder.WxCreateOrderResult>() {
        }.getType());
        String nonceStr = WxUtils.create().nonceStr(32).toUpperCase();
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        String packAge = "prepay_id=" + result.getPrepay_id();
        String signType = "RSA";
        String message = WxPayConfig.appId + "
" + timeStamp + "
" + nonceStr + "
" + packAge + "
";
        logger.debug(message);
        String sign = WxUtils.create().paySign(message, privateKey);
        Map<String, String> data = new HashMap<>(6);
        data.put("appId", WxPayConfig.appId);
        data.put("timeStamp", timeStamp);
        data.put("nonceStr", nonceStr);
        data.put("package", packAge);
        data.put("signType", signType);
        data.put("paySign", sign);
        return data;
    }
2.2退款单
4.支付回调
/**
 * 余额充值支付回调
 */
public NotifyResult invest(@RequestBody NotifyBody body) throws IOException, GeneralSecurityException {
        logger.info("余额充值支付回调:" + body.toString());
        if (StringUtils.equals("TRANSACTION.SUCCESS", body.getEvent_type())) {
            NotifyBody.Resource resource = body.getResource();
            String ret = new AesUtil(WxPayConfig.v3Secret.getBytes(StandardCharsets.UTF_8)).decryptToString(resource.getAssociated_data().getBytes(StandardCharsets.UTF_8), resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
            NotifyResource result = new Gson().fromJson(ret, NotifyResource.class);
            if (StringUtils.equals(result.getTrade_state(), "SUCCESS")) {
                //支付回调 数据解析成功后,相关处理
            }
            logger.debug(ret);
        }
        return NotifyResult.create().success();
    }
/**
 * 退款回调
 */
@PostMapping("/refund")
public NotifyResult refund(@RequestBody NotifyBody body) throws IOException, GeneralSecurityException {
    logger.info("退款回调:" + body.toString());
    if (StringUtils.equals("REFUND.SUCCESS", body.getEvent_type())) {
        NotifyBody.Resource resource = body.getResource();
        String ret = new AesUtil(WxPayConfig.v3Secret.getBytes(StandardCharsets.UTF_8)).decryptToString(resource.getAssociated_data().getBytes(StandardCharsets.UTF_8), resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
        RefundResource result = new Gson().fromJson(ret, RefundResource.class);
        if (StringUtils.equals(result.getRefund_status(), "SUCCESS")) {
            //退款回调 数据解析成功后,相关处理
        }
        logger.debug(ret);
    }
    return NotifyResult.create().success();
}
5.接收回调参数类以及解析结果类 NotifyBody.java,RefundResource.java
public class NotifyResult {
    private String code;
    private String message;

    public NotifyResult() {
    }
    public static NotifyResult create(){
        return new NotifyResult();
    }
    public NotifyResult success(){
        this.code = "SUCCESS";
        this.message = "成功";
        return this;
    }
    public NotifyResult fail(){
        this.code = "FAIL";
        this.message = "失败";
        return this;
    }
    public NotifyResult fail(String message){
        this.code = "FAIL";
        this.message = message;
        return this;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
8.文中缺少的一些类文件如下:
经验分享 程序员 微信小程序 职场和发展