combinations-wx-pay-starter
1.功能介绍
支持通过一行代码调用以下功能:
- 预支付:发起微信支付请求,获取支付相关信息。
- 支付结果回调:处理微信支付结果的回调请求。
- 查询订单状态:查询微信支付订单的支付状态。
- 关闭订单:关闭指定的支付订单。
2.配置示例
yaml
sun-rays:
wx:
pay:
merchant-id: ${MERCHANT_ID} # 商户号
appid: ${APPID} # 应用的appid
merchant-serial-number: ${MERCHANT_SERIAL_NUMBER} # 商户API证书序列号
private-key-path: ${PRIVATE_KEY_PATH} # 商户API证书私钥路径
api-v3-key: ${API_V3_KEY} # 商户APIV3密钥
cert-file-path: ${CERT_FILE_PATH} # 微信支付平台的证书路径
notify-url: ${NOTIFY_URL} # 支付结果回调url(https)
3.案例演示
1.创建模块
2.目录结构
3.pom.xml
xml
<dependencies>
<!-- combinations-wx-pay-starter -->
<dependency>
<groupId>cn.sunxiansheng</groupId>
<artifactId>combinations-wx-pay-starter</artifactId>
</dependency>
<!-- 必须引入 -->
<dependency>
<groupId>cn.sunxiansheng</groupId>
<artifactId>common-log4j2-starter</artifactId>
</dependency>
<!-- env模块确保数据安全 -->
<dependency>
<groupId>cn.sunxiansheng</groupId>
<artifactId>common-env-starter</artifactId>
</dependency>
</dependencies>
4.application.yml 配置日志存储根目录、.env文件的绝对路径以及微信支付
yaml
sun-rays:
log4j2:
home: /Users/sunxiansheng/IdeaProjects/sunrays-framework-demo/combinations-wx-pay-starter-demo/logs # 日志存储根目录
env:
path: /Users/sunxiansheng/IdeaProjects/sunrays-framework-demo/combinations-wx-pay-starter-demo # .env文件的绝对路径
wx:
pay:
merchant-id: ${MERCHANT_ID} # 商户号
appid: ${APPID} # 应用的appid
merchant-serial-number: ${MERCHANT_SERIAL_NUMBER} # 商户API证书序列号
private-key-path: ${PRIVATE_KEY_PATH} # 商户API证书私钥路径
api-v3-key: ${API_V3_KEY} # 商户APIV3密钥
cert-file-path: ${CERT_FILE_PATH} # 微信支付平台的证书路径
notify-url: ${NOTIFY_URL} # 支付结果回调url(https)
5..env
properties
MERCHANT_ID=商户号
APPID=应用的appid
MERCHANT_SERIAL_NUMBER=商户API证书序列号
PRIVATE_KEY_PATH=商户API证书私钥路径
API_V3_KEY=商户APIV3密钥
CERT_FILE_PATH=微信支付平台的证书路径
NOTIFY_URL=支付结果回调url(https)
6.WxPayController.java 微信支付的Controller
java
package cn.sunxiansheng.wx.pay.controller;
import cn.sunxiansheng.log4j2.annotation.SkipLogAspect;
import cn.sunxiansheng.tool.utils.JsonUtil;
import cn.sunxiansheng.wx.pay.config.entity.WxPayPrePayEntity;
import cn.sunxiansheng.wx.pay.config.service.WxPayService;
import cn.sunxiansheng.wx.pay.config.utils.WxPayUtil;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* Description: WxPayController
*
* @Author sun
* @Create 2025/1/24 14:25
* @Version 1.0
*/
@RestController
@RequestMapping("/wx/pay")
@Slf4j
public class WxPayController {
/**
* 注入框架封装好的WxPayService
*/
@Resource
private WxPayService wxPayService;
/**
* A test endpoint.
*
* @return A sample response.
*/
@RequestMapping("/test")
public String test() {
return "This is a test response from WxPayController";
}
/**
* 生成订单号
*
* @return
*/
private String generateOutTradeNo() {
// 当前时间,格式为yyyyMMddHHmmssSSS
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
// 生成3位随机数
int random = new Random().nextInt(900) + 100;
// 拼接订单号
return "ORD" + timestamp + random;
}
@Data
public static class PrepayReq {
/**
* 商品金额
*/
private Double mount;
/**
* 商品名称
*/
private String name;
}
@Data
public static class PrepayVo {
/**
* 二维码的url
*/
private String codeUrl;
/**
* 全局唯一订单号
*/
private String outTradeNo;
/**
* 过期时间
*/
private String timeExpire;
}
/**
* 前端携带用户购买商品信息向后端发送下单请求,Native支付预下单
*
* @param prepayReq 商品金额
* @return 返回code_url,也就是二维码链接
*/
@RequestMapping("/prepay")
public PrepayVo prepay(@RequestBody PrepayReq prepayReq) {
// 唯一订单号
String outTradeNo = generateOutTradeNo();
// 选填:用户能够完成该笔订单支付的最后时限(两分钟)
String timeExpire = WxPayUtil.getTimeExpire(2, TimeUnit.MINUTES);
// 一行调用接口
PrepayResponse prepay = wxPayService.prepay(
new WxPayPrePayEntity("自定义的商品描述",
outTradeNo,
(int) (prepayReq.getMount() * 100))
.setTimeExpire(timeExpire));
// 封装Vo
PrepayVo prepayVo = new PrepayVo();
prepayVo.setCodeUrl(prepay.getCodeUrl());
prepayVo.setOutTradeNo(outTradeNo);
prepayVo.setTimeExpire(timeExpire);
return prepayVo;
}
@SkipLogAspect // 跳过日志切面的处理,因为有大对象
@PostMapping("/callback")
public ResponseEntity<String> callback(
HttpServletRequest request
) {
return wxPayService.callback(request, (transaction) -> {
String prettyJson = JsonUtil.toPrettyJson(transaction);
// 对解密后的业务逻辑进行处理(一锁、二判、三更新),成功返回true,失败返回false
log.info("对解密后的业务逻辑进行处理:{}", prettyJson);
return true;
});
}
/**
* 商户订单号查询订单状态
*/
@RequestMapping("/queryOrderByOutTradeNo")
public Transaction queryOrderByOutTradeNo(@RequestParam String outTradeNo) {
return wxPayService.queryOrderByOutTradeNo(outTradeNo);
}
/**
* 根据商户订单号关闭订单
*/
@RequestMapping("/closeOrder")
public void closeOrder(@RequestParam String outTradeNo) {
wxPayService.closeOrder(outTradeNo);
}
}
7.WxPayApplication.java 启动类
java
package cn.sunxiansheng.wx.pay;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Description: WxPayApplication
*
* @Author sun
* @Create 2025/1/24 14:22
* @Version 1.0
*/
@SpringBootApplication
public class WxPayApplication {
public static void main(String[] args) {
SpringApplication.run(WxPayApplication.class, args);
}
}