SpringBoot + 微信公众号JSAPI支付功能的实现

时间:2022-09-06 11:35:23

1、pom.xml依赖配置

?
1
2
3
4
5
6
<!-- 微信支付 -->
<dependency>
  <groupId>com.egzosn</groupId>
  <artifactId>pay-java-wx</artifactId>
  <version>2.12.4</version>
</dependency>

2、application.yml文件配置微信公众号的基础信息

?
1
2
3
4
5
6
7
8
#微信公众号支付配置
wechatpay:
 mchId: # 商户Id
 appId: #应用id
 storePassword: #秘钥支付密码
 secretKey: # 密钥
 notifyUrl: #微信支付回调
 keyStore:  # 证书所在位置

3、设置配置文件 WechatPayConfig.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.example.emoticon.wechat;
 
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
/**
 * @ClassName WechatPayConfig
 * @Description 微信支付配置
 * @Author WangJing
 * @Date 2021/3/23 4:38 下午
 * @Version V1.1.0
 */
 
@Data
@Component
@ConfigurationProperties(prefix = "wechatpay")
public class WechatPayConfig {
 
  private String mchId;//合作者id(商户号
 
  private String appId;//应用id
 
  private String secretKey;//密钥
 
  private String notifyUrl;
  private String keyStore;// 支付密钥存放位置 文件是以.p12为后缀名字
  private String storePassword;
 
}

4、controller 逻辑代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package com.example.emoticon.controller;
 
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.RefundOrder;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.wx.api.WxPayConfigStorage;
import com.egzosn.pay.wx.api.WxPayService;
import com.egzosn.pay.wx.bean.WxTransactionType;
import com.example.emoticon.wechat.WechatPayConfig;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
 
/**
 * @ClassName WechatPayController
 * @Description 微信支付Controller
 * @Author WangJing
 * @Date 2021/3/23 4:35 下午
 * @Version V1.1.0
 */
@RestController
@RequestMapping("/wechatPay")
@Slf4j
public class WechatPayController {
 
 
  @Autowired
  WechatPayConfig wechatPayConfig;
 
  private PayService service = null;
 
  @PostConstruct
  public void init() {
    WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
    wxPayConfigStorage.setMchId(wechatPayConfig.getMchId()); // 合作者id(商户号
    wxPayConfigStorage.setAppid(wechatPayConfig.getAppId()); // 应用id
    wxPayConfigStorage.setSecretKey(wechatPayConfig.getSecretKey()); // 密钥
    wxPayConfigStorage.setNotifyUrl(wechatPayConfig.getNotifyUrl()); // 异步回调地址 http://域名:端口号/项目名/回调接口名称
    wxPayConfigStorage.setSignType(SignUtils.MD5.name());
    wxPayConfigStorage.setInputCharset("utf-8");
    // 支付api证书设置,退款必须 方式一
    HttpConfigStorage httpConfigStorage = new HttpConfigStorage();
    httpConfigStorage.setKeystore(wechatPayConfig.getKeyStore());// 支付密钥存放位置 文件是以.p12为后缀名字
    httpConfigStorage.setStorePassword(wechatPayConfig.getStorePassword());
    // 是否为证书地址
    httpConfigStorage.setPath(true);
    service = new WxPayService(wxPayConfigStorage, httpConfigStorage);
    // 请求连接池配置
    // 最大连接数
    httpConfigStorage.setMaxTotal(20);
    // 默认的每个路由的最大连接数
    httpConfigStorage.setDefaultMaxPerRoute(10);
    service.setRequestTemplateConfigStorage(httpConfigStorage);
  }
 
  @ApiOperation("返回订单信息")
  @RequestMapping(value = "weixinpay", method = RequestMethod.POST)
  public Map<String, Object> weixinpay(HttpServletRequest request) {
    //备注:这个可以获取预支付的订单,根据需要调用这个接口,可有前台向后台传递参数。然后后台根据需要进行处理。
    init();
    // 在这一步,可以传入一个订单Id,自行去搜索订单信息,并填写以下内容
    PayOrder payOrder = new PayOrder();// 这个就是支付成功后,在微信支付里面返回的信息(支付订单信息)
    // 一下内容需要分情况而定,自行填写。
    payOrder.setSubject("商品名称");
    payOrder.setBody("商品描述");
    payOrder.setAddition("附加信息");
    payOrder.setPrice(new BigDecimal(0.2));// 价格
    payOrder.setOutTradeNo("商户订单号");
    payOrder.setBankType("银行卡类型");
    payOrder.setDeviceInfo("设备信息");
    payOrder.setSpbillCreateIp("支付创建ip");// 可用IPUtils.getIpAddr(request)
    payOrder.setOpenid("用户微信openid");
    payOrder.setTransactionType(WxTransactionType.JSAPI);// 支付方式
    Map orderInfo = service.orderInfo(payOrder);// 返回创建的订单信息
    log.debug("获取预支付订单信息回参" + orderInfo.toString());
    // 可自行选择 ,是否将支付的流水插入到数据库中。返回的信息由:signType appId timeStamp nonceStr package sign
    return orderInfo;
  }
 
  /**
   * 这就是支付回调地址
   *
   * @param request
   * @return
   * @throws IOException
   */
  @ApiOperation("回调地址")
  @RequestMapping(value = "weixinpayBack")
  public String payBack(HttpServletRequest request) throws IOException {
    init();
    // 获取支付方返回的对应参数
    Map<String, Object> params = service.getParameter2Map(request.getParameterMap(), request.getInputStream());
    if (null == params) {
      log.debug("通知失败");
      return service.getPayOutMessage("failed", "通知失败").toMessage();
    }
    log.debug("微信公众号支付结果通知:" + params.toString());
    // 校验
    if (service.verify(params)) {
      // 这里处理业务逻辑 支付成功后的代码逻辑块
      // ......业务逻辑处理块........
      log.debug("通知支付成功");
      return service.getPayOutMessage("success", "支付成功").toMessage();
    }
    log.debug("通知支付失败");
    return service.getPayOutMessage("fail", "支付失败").toMessage();
  }
 
 
  @ApiOperation("微信公众号退款")
  @RequestMapping(value = "weixinAccRefund")
  public String weixinRefund() {
    init();
    RefundOrder refundOrder = new RefundOrder();//退款订单信息
    refundOrder.setRefundNo("退款单号,每次进行退款的单号,此处唯一");
    refundOrder.setTradeNo("支付平台订单号,交易号");
    refundOrder.setOutTradeNo("商户单号");
    refundOrder.setRefundAmount(new BigDecimal(0.2));//退款金额
    refundOrder.setTotalAmount(new BigDecimal(0.5));//订单总金额
    refundOrder.setOrderDate(new Date());//退款交易日期
    refundOrder.setDescription("退款说明");
    Map<String, Object> refund = service.refund(refundOrder);//微信退款
    //退款成功后,写其他的逻辑
    log.debug("微信公众号退款结果:=" + refund.toString());
 
    return "Success";
 
  }
}

到此这篇关于SpringBoot + 微信公众号JSAPI支付功能的实现的文章就介绍到这了,更多相关SpringBoot 微信公众号JSAPI支付内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/wang_jing_jing/article/details/115129329