Spring Boot 是一款非常流行的 Java 开发框架,而微信支付则是众多移动支付产品中的佼佼者,整合两者可以让我们更方便地开发各种支付产品。在本篇博客中,我将介绍如何在 Spring Boot 中整合微信支付的各种支付产品。
准备工作
- 注册一个微信支付商户账号
- 创建一个微信支付应用程序并获取应用程序的AppID和AppSecret
- 获取商户号和API密钥
首先,我们需要在 pom.xml 中添加以下依赖:
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>4.1.0</version>
</dependency>
然后,我们需要在 application.yml 中配置微信支付的相关信息:
wx:
pay:
app-id: your_app_id
mch-id: your_mch_id
mch-key: your_mch_key
key-path: your_key_path
notify-url: your_notify_url
接下来,我们就可以开始整合微信支付的各种支付产品了。
微信公众号支付
微信公众号支付是指在微信公众号内进行支付。在 Spring Boot 中整合微信公众号支付,我们需要使用 WxPayService 对象来进行支付。
首先,我们需要在配置类中注入 WxPayService 对象:
@Configuration
public class WxPayConfig {
@Value("${wx.pay.app-id}")
private String appId;
@Value("${wx.pay.mch-id}")
private String mchId;
@Value("${wx.pay.mch-key}")
private String mchKey;
@Value("${wx.pay.key-path}")
private String keyPath;
@Value("${wx.pay.notify-url}")
private String notifyUrl;
@Bean
public WxPayService wxPayService() throws Exception {
WxPayConfig wxPayConfig = new WxPayConfig();
wxPayConfig.setAppId(appId);
wxPayConfig.setMchId(mchId);
wxPayConfig.setMchKey(mchKey);
wxPayConfig.setKeyPath(keyPath);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(wxPayConfig);
wxPayService.setPayConfig(wxPayConfig);
// 注册异步通知处理器
wxPayService.setNotifyUrl(notifyUrl, "/notify");
return wxPayService;
}
}
然后,我们就可以在支付控制器中使用 WxPayService 对象来进行支付了:
@RestController
public class PayController {
@Autowired
private WxPayService wxPayService;
@GetMapping("/pay")
public String pay(HttpServletRequest request) throws Exception {
// 构造订单信息
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setBody("订单描述");
orderRequest.setOutTradeNo("订单号");
orderRequest.setTotalFee(1);
orderRequest.setSpbillCreateIp(request.getRemoteAddr());
orderRequest.setNotifyUrl(notifyUrl);
orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
orderRequest.setOpenid("用户的openid");
// 调用统一下单接口
WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
// 构造支付参数
Map<String, String> payParams = new HashMap<>();
payParams.put("appId", orderResult.getAppId());
payParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
payParams.put("nonceStr", orderResult.getNonceStr());
payParams.put("package", "prepay_id=" + orderResult.getPrepayId());
payParams.put("signType", "MD5");
payParams.put("paySign", WXPayUtil.generateSignature(payParams, mchKey));
return JSON.toJSONString(payParams);
}
@PostMapping("/notify")
public String notify(@RequestBody String xmlData) throws Exception {
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
if (!WxPayConstants.ResultCode.SUCCESS.equals(notifyResult.getResultCode())) {
// 支付失败,处理失败逻辑
return WxPayNotifyResponse.fail("支付失败");
}
// 支付成功,处理成功逻辑
String orderId = notifyResult.getOutTradeNo();
// 更新订单状态等业务逻辑
return WxPayNotifyResponse.success("OK");
}
}
在这里,我们使用了 WxPayService.parseOrderNotifyResult() 方法将微信支付异步通知的 XML 数据解析为 WxPayOrderNotifyResult 对象。如果支付成功,则处理成功逻辑,否则处理失败逻辑。
最后,我们需要编写一个 WxPayNotifyResponse
类来封装异步通知的响应信息:
public class WxPayNotifyResponse {
private static final String SUCCESS = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
private static final String FAIL = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>";
public static String success(String msg) {
return SUCCESS;
}
public static String fail(String msg) {
return String.format(FAIL, msg);
}
}
微信扫码支付
微信扫码支付是指用户使用微信扫描商家的二维码进行支付。在 Spring Boot 中整合微信扫码支付,我们需要使用 WxPayService 对象来进行支付。
首先,我们需要在配置类中注入 WxPayService 对象;配置信息同公众号支付一样:
@Configuration
public class WxPayConfig {
@Value("${wx.pay.app-id}")
private String appId;
@Value("${wx.pay.mch-id}")
private String mchId;
@Value("${wx.pay.mch-key}")
private String mchKey;
@Value("${wx.pay.key-path}")
private String keyPath;
@Value("${wx.pay.notify-url}")
private String notifyUrl;
@Bean
public WxPayService wxPayService() throws Exception {
WxPayConfig wxPayConfig = new WxPayConfig();
wxPayConfig.setAppId(appId);
wxPayConfig.setMchId(mchId);
wxPayConfig.setMchKey(mchKey);
wxPayConfig.setKeyPath(keyPath);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(wxPayConfig);
wxPayService.setPayConfig(wxPayConfig);
// 注册异步通知处理器
wxPayService.setNotifyUrl(notifyUrl, "/notify");
return wxPayService;
}
}
然后,我们就可以在支付控制器中使用 WxPayService 对象来进行支付了:
@RestController
public class PayController {
@Autowired
private WxPayService wxPayService;
@GetMapping("/pay")
public String pay(HttpServletRequest request) throws Exception {
// 构造订单信息
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setBody("订单描述");
orderRequest.setOutTradeNo("订单号");
orderRequest.setTotalFee(1);
orderRequest.setSpbillCreateIp(request.getRemoteAddr());
orderRequest.setNotifyUrl(notifyUrl);
orderRequest.setTradeType(WxPayConstants.TradeType.NATIVE);
orderRequest.setProductId("商品id");
// 调用统一下单接口
WxPayNativeOrderResult orderResult = wxPayService.createOrder(orderRequest);
// 获取二维码链接
String codeUrl = orderResult.getCodeUrl();
return codeUrl;
}
@PostMapping("/notify")
public String notify(@RequestBody String xmlData) throws Exception {
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
if (!WxPayConstants.ResultCode.SUCCESS.equals(notifyResult.getResultCode())) {
// 支付失败,处理失败逻辑
return WxPayNotifyResponse.fail("支付失败");
}
// 支付成功,处理成功逻辑
String orderId = notifyResult.getOutTradeNo();
// 更新订单状态等业务逻辑
return WxPayNotifyResponse.success("OK");
}
}
在这里,我们将 tradeType
参数设置为 WxPayConstants.TradeType.NATIVE
,表示使用扫码支付方式。我们通过调用 createOrder() 方法生成订单,并从返回结果中获取二维码链接,然后使用 QrCodeUtil.createQrCode() 方法生成二维码图片。
注意,生成的二维码链接有效期为2小时,超时后需要重新生成。
我们使用了 WxPayService.parseOrderNotifyResult()
方法将微信支付异步通知的 XML 数据解析为 WxPayOrderNotifyResult
对象。如果支付成功,则处理成功逻辑,否则处理失败逻辑。
最后,我们需要编写一个 WxPayNotifyResponse
类来封装异步通知的响应信息:
public class WxPayNotifyResponse {
private static final String SUCCESS = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
private static final String FAIL = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>";
public static String success(String msg) {
return SUCCESS;
}
public static String fail(String msg) {
return String.format(FAIL, msg);
}
}
微信APP支付
微信APP支付是指在微信内部或者第三方应用中进行支付。在 Spring Boot 中整合微信APP支付,我们需要使用 WxPayService 对象来进行支付。
首先,我们需要在配置类中注入 WxPayService 对象:
@Configuration
public class WxPayConfig {
@Value("${wx.pay.app-id}")
private String appId;
@Value("${wx.pay.mch-id}")
private String mchId;
@Value("${wx.pay.mch-key}")
private String mchKey;
@Value("${wx.pay.key-path}")
private String keyPath;
@Value("${wx.pay.notify-url}")
private String notifyUrl;
@Bean
public WxPayService wxPayService() throws Exception {
WxPayConfig wxPayConfig = new WxPayConfig();
wxPayConfig.setAppId(appId);
wxPayConfig.setMchId(mchId);
wxPayConfig.setMchKey(mchKey);
wxPayConfig.setKeyPath(keyPath);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(wxPayConfig);
wxPayService.setPayConfig(wxPayConfig);
// 注册异步通知处理器
wxPayService.setNotifyUrl(notifyUrl, "/notify");
return wxPayService;
}
}
然后,我们就可以在支付控制器中使用 WxPayService 对象来进行支付了:
@RestController
public class PayController {
@Autowired
private WxPayService wxPayService;
@PostMapping("/pay")
public String pay(@RequestBody PayRequest payRequest) throws Exception {
// 构造订单信息
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setBody(payRequest.getSubject());
orderRequest.setOutTradeNo(payRequest.getOrderId());
orderRequest.setTotalFee(payRequest.getAmount().intValue());
orderRequest.setSpbillCreateIp(payRequest.getClientIp());
orderRequest.setNotifyUrl(notifyUrl);
orderRequest.setTradeType(WxPayConstants.TradeType.APP);
// 调用统一下单接口
WxPayAppOrderResult orderResult = wxPayService.createOrder(orderRequest);
// 构造APP支付参数
Map<String, String> payParams = new HashMap<>();
payParams.put("appid", orderResult.getAppId());
payParams.put("partnerid", orderResult.getPartnerId());
payParams.put("prepayid", orderResult.getPrepayId());
payParams.put("package", "Sign=WXPay");
payParams.put("noncestr", orderResult.getNonceStr());
payParams.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
payParams.put("sign", WXPayUtil.generateSignature(payParams, mchKey));
return JSON.toJSONString(payParams);
}
@PostMapping("/notify")
public String notify(@RequestBody String xmlData) throws Exception {
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
if (!WxPayConstants.ResultCode.SUCCESS.equals(notifyResult.getResultCode())) {
// 支付失败,处理失败逻辑
return WxPayNotifyResponse.fail("支付失败");
}
// 支付成功,处理成功逻辑
String orderId = notifyResult.getOutTradeNo();
// 更新订单状态等业务逻辑
return WxPayNotifyResponse.success("OK");
}
}
在这里,我们使用了 WxPayService.parseOrderNotifyResult() 方法将微信支付异步通知的 XML 数据解析为 WxPayOrderNotifyResult 对象。如果支付成功,则处理成功逻辑,否则处理失败逻辑。
最后,我们需要编写一个 WxPayNotifyResponse
类来封装异步通知的响应信息:
public class WxPayNotifyResponse {
private static final String SUCCESS = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
private static final String FAIL = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>";
public static String success(String msg) {
return SUCCESS;
}
public static String fail(String msg) {
return String.format(FAIL, msg);
}
}
微信H5支付
微信H5支付是指在移动端网页上进行支付。在 Spring Boot 中整合微信H5支付,我们需要使用 WxPayService 对象来进行支付。
首先,我们需要在配置类中注入 WxPayService 对象:
@Configuration
public class WxPayConfig {
@Value("${wx.pay.app-id}")
private String appId;
@Value("${wx.pay.mch-id}")
private String mchId;
@Value("${wx.pay.mch-key}")
private String mchKey;
@Value("${wx.pay.key-path}")
private String keyPath;
@Value("${wx.pay.notify-url}")
private String notifyUrl;
@Bean
public WxPayService wxPayService() throws Exception {
WxPayConfig wxPayConfig = new WxPayConfig();
wxPayConfig.setAppId(appId);
wxPayConfig.setMchId(mchId);
wxPayConfig.setMchKey(mchKey);
wxPayConfig.setKeyPath(keyPath);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(wxPayConfig);
wxPayService.setPayConfig(wxPayConfig);
// 注册异步通知处理器
wxPayService.setNotifyUrl(notifyUrl, "/notify");
return wxPayService;
}
}
然后,我们就可以在控制器中使用 WxPayService 对象来进行支付了:
@RestController
public class PayController {
@Autowired
private WxPayService wxPayService;
@PostMapping("/pay")
public String pay(@RequestBody PayRequest payRequest) throws Exception {
// 构造订单信息
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setBody(payRequest.getSubject());
orderRequest.setOutTradeNo(payRequest.getOrderId());
orderRequest.setTotalFee(payRequest.getAmount().intValue());
orderRequest.setSpbillCreateIp(payRequest.getClientIp());
orderRequest.setNotifyUrl(notifyUrl);
orderRequest.setTradeType(WxPayConstants.TradeType.MWEB);
orderRequest.setSceneInfo("{\"h5_info\":{\"type\":\"Wap\",\"wap_url\":\"http://www.example.com\",\"wap_name\":\"Example网站\"}}");
// 调用统一下单接口
WxPayMwebOrderResult orderResult = wxPayService.createOrder(orderRequest);
// 获取支付跳转链接
String mwebUrl = orderResult.getMwebUrl();
return mwebUrl;
}
@PostMapping("/notify")
public String notify(@RequestBody String xmlData) throws Exception {
WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
if (!WxPayConstants.ResultCode.SUCCESS.equals(notifyResult.getResultCode())) {
// 支付失败,处理失败逻辑
return WxPayNotifyResponse.fail("支付失败");
}
// 支付成功,处理成功逻辑
String orderId = notifyResult.getOutTradeNo();
// 更新订单状态等业务逻辑
return WxPayNotifyResponse.success("OK");
}
}
在这里,我们将 tradeType 参数设置为 WxPayConstants.TradeType.MWEB,表示使用H5支付方式。我们还设置了 sceneInfo 参数,它包含了 H5 支付的相关信息,比如 H5 网页的 URL 和名称。
注意,微信H5支付跳转链接的有效期为5分钟,所以在获取到跳转链接后应该尽快让用户跳转到支付页面。
总结
本文介绍了如何在 Spring Boot 中整合微信支付,包括微信公众号支付、微信APP支付、微信H5支付和微信扫码支付。我们使用了 WxPayService 对象来与微信支付接口进行交互,并在支付控制器中使用 WxPayService 对象来生成各种支付产品的支付参数或支付链接。在实际应用中,我们可以根据业务需求选择相应的支付产品和支付方式。
当然,本文只是简单介绍了微信支付的整合过程,实际的业务场景中可能还需要考虑一些其他因素,例如订单状态的处理、支付回调通知的处理等等。在实际开发中,我们还需要根据具体业务场景进行相应的定制化开发。
总的来说,通过本文的介绍,我们可以对 Spring Boot 中整合微信支付有一个基本的了解,并且可以快速上手进行开发。