在目前的互联网上,我们已经经常使用微信支付进行各种支付操作。微信支付作为一种移动支付的新时代产品,新颖的功能和稳定的操作流程使得它在用户中深得信任。对于一些企业或者个人,如何实现和使用微信支付成了一个不可避免的问题。为此,本文将介绍如何使用SpringBoot来快速实现微信支付的功能。
准备工作
在实现微信支付之前,需要先确保满足以下条件:
- 使用微信公众号或者小程序账号,并开通支付功能;
- 有自己的服务器,能够接收微信支付的通知;
- 使用Java SpringBoot框架。
如果已经满足以上条件,则可以开始进行以下步骤。
申请微信支付
首先需要前往微信公众平台或者微信开放平台进行注册和登录。在登录之后,在菜单中找到“开发者中心”,并选择“开发设置”,然后找到“微信支付”功能,进入申请流程。
在申请过程中,需要填写一些相关的信息,并上传一些必须的文件(如商户证书等)。在完成审核之后,会获得一些必要的信息,如appid
、mch_id
、key
等。
引入依赖
在SpringBoot项目中,使用微信支付需要引入对应的依赖。在pom.xml
文件中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>3.0.10</version>
</dependency>
注意:以上依赖中的版本号可能跟您当前使用的版本号不一致,可以根据实际情况进行更改。
配置参数
在项目的配置文件中,需要添加以下配置信息:
#微信支付的相关配置
wxpay.appid=你的appid
wxpay.mchid=你的商户id
wxpay.key=你的商户key
wxpay.notifyurl=你的后台接收微信支付结果通知的url
wxpay.trade_type=JSAPI
# 等等
代码实现
预支付
在使用微信支付之前,需要先生成一个预支付订单,在此之后才能发起支付。以下代码实现了通过预支付生成支付订单并获取支付信息:
/**
* 创建统一下单接口
* @param order
* @return
* @throws Exception
*/
public Map<String, String> createUnifiedOrder(Order order) throws Exception {
// 1.生成随机字符串
String nonceStr = WXPayUtil.generateNonceStr();
// 2.生成订单号
String outTradeNo = order.getOutTradeNo();
// 3.获取订单金额,单位是分
String totalFee = order.getTotalFee().toString();
// 4.获取用户openId(JSAPI支付必需)
String openid = order.getOpenid();
// 5.配置统一下单参数
Map<String, String> data = new HashMap<>();
data.put("appid", wxpayAppid);
data.put("mch_id", wxpayMchid);
data.put("nonce_str", nonceStr);
if (order.getBody() != null) {
data.put("body", order.getBody());
}
data.put("out_trade_no", outTradeNo);
data.put("total_fee", totalFee);
data.put("spbill_create_ip", order.getSpbillCreateIp());
data.put("notify_url", wxpayNotifyurl);
data.put("trade_type", wxpayTrade_type);
data.put("openid", openid);
// 6.生成签名
String sign = WXPayUtil.generateSignature(data, wxpayKey, WXPayConstants.SignType.MD5);
data.put("sign", sign);
// 7.将参数转换为XML格式,通过HTTP请求调用微信支付接口
String requestXml = WXPayUtil.mapToXml(data);
WXPay wxPay = new WXPay(wxpayConfig);
Map<String, String> resultMap = wxPay.unifiedOrder(data);
// 8.对微信支付接口返回的数据进行处理并返回,包括二次签名和返回给前端的数据格式处理。
Map<String, String> resultMap = wxPay.unifiedOrder(data);
String returnCode = resultMap.get("return_code");
String resultCode = resultMap.get("result_code");
if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
String prepayId = resultMap.get("prepay_id");
// 生成响应给前端的参数列表
Map<String, String> responseMap = new HashMap<>();
responseMap.put("timeStamp", timeStamp);
responseMap.put("nonceStr", nonceStr);
responseMap.put("signType", WXPayConstants.MD5);
responseMap.put("package", "prepay_id=" + prepayId);
// 二次签名
String responseSign = WXPayUtil.generateSignature(responseMap, wxpayKey, WXPayConstants.SignType.MD5);
responseMap.put("paySign", responseSign);
return responseMap;
} else {
return null;
}
}
支付结果回调
支付结果回调通知是微信支付中非常重要的一步,因为它能够实时地将支付的结果反馈给我们的服务端。当用户支付成功后,微信会通过POST方式把相关支付通知发送到我们所设定的回调URL上,我们需要在回调URL所在的服务中对支付结果进行处理。
/**
* 微信支付结果通知接口(POST方式)
* @param request
* @param response
* @return
*/
@ResponseBody
@PostMapping(value="/wxpay/notify")
public String handleWxPayNotify(HttpServletRequest request, HttpServletResponse response) {
try {
ServletInputStream inputStream = request.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
String result = "";
while((line = bufferedReader.readLine()) != null){
result += line;
}
// 此处 result 就是接受到的微信支付异步通知报文,直接使用WXPayUtil工具解析xml报文内容即可
Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
// 通过微信支付通知的返回结果,校验是否支付成功
String returnCode = resultMap.get("return_code");
String resultCode = resultMap.get("result_code");
if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
String outTradeNo = resultMap.get("out_trade_no");
//... 业务逻辑处理
// 返回给微信支付结果通知接收服务器的信息
String returnMsg = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml>";
return returnMsg;
} else {
String returnMsg = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[支付失败]]></return_msg>" + "</xml>";
return returnMsg;
}
} catch (Exception e) {
logger.error("微信支付结果回调出现异常:{}", e.getMessage());
return null;
}
}
完整的控制器代码如下:
package com.example.demo.controller;
import com.example.demo.config.WxpayConfig;
import com.example.demo.dto.Order;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
@RestController
public class WxPayController {
private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);
@Autowired
private WxpayConfig wxpayConfig;
@Value("${wxpay.appid}")
private String wxpayAppid;
@Value("${wxpay.mchid}")
private String wxpayMchid;
@Value("${wxpay.key}")
private String wxpayKey;
@Value("${wxpay.notifyurl}")
private String wxpayNotifyurl;
@Value("${wxpay.trade_type}")
private String wxpayTrade_type;
/**
* 创建统一下单接口
* @param order
* @return
* @throws Exception
*/
public Map<String, String> createUnifiedOrder(Order order) throws Exception {
// 1.生成随机字符串
String nonceStr = WXPayUtil.generateNonceStr();
// 2.生成订单号
String outTradeNo = order.getOutTradeNo();
// 3.获取订单金额,单位是分
String totalFee = order.getTotalFee().toString();
// 4.获取用户openId(JSAPI支付必需)
String openid = order.getOpenid();
// 5.配置统一下单参数
Map<String, String> data = new HashMap<>();
data.put("appid", wxpayAppid);
data.put("mch_id", wxpayMchid);
data.put("nonce_str", nonceStr);
if (order.getBody() != null) {
data.put("body", order.getBody());
}
data.put("out_trade_no", outTradeNo);
data.put("total_fee", totalFee);
data.put("spbill_create_ip", order.getSpbillCreateIp());
data.put("notify_url", wxpayNotifyurl);
data.put("trade_type", wxpayTrade_type);
data.put("openid", openid);
// 6.生成签名
String sign = WXPayUtil.generateSignature(data, wxpayKey, WXPayConstants.SignType.MD5);
data.put("sign", sign);
// 7.将参数转换为XML格式,通过HTTP请求调用微信支付接口
String requestXml = WXPayUtil.mapToXml(data);
WXPay wxPay = new WXPay(wxpayConfig);
Map<String, String> resultMap = wxPay.unifiedOrder(data);
// 8.对微信支付接口返回的数据进行处理并返回,包括二次签名和返回给前端的数据格式处理。
Map<String, String> resultMap = wxPay.unifiedOrder(data);
String returnCode = resultMap.get("return_code");
String resultCode = resultMap.get("result_code");
if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
String prepayId = resultMap.get("prepay_id");
// 生成响应给前端的参数列表
Map<String, String> responseMap = new HashMap<>();
responseMap.put("timeStamp", timeStamp);
responseMap.put("nonceStr", nonceStr);
responseMap.put("signType", WXPayConstants.MD5);
responseMap.put("package", "prepay_id=" + prepayId);
// 二次签名
String responseSign = WXPayUtil.generateSignature(responseMap, wxpayKey, WXPayConstants.SignType.MD5);
responseMap.put("paySign", responseSign);
return responseMap;
} else {
return null;
}
}
/**
* 微信支付结果通知接口(POST方式)
* @param request
* @param response
* @return
*/
@ResponseBody
@PostMapping(value="/wxpay/notify")
public String handleWxPayNotify(HttpServletRequest request, HttpServletResponse response) {
try {
ServletInputStream inputStream = request.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
String result = "";
while((line = bufferedReader.readLine()) != null){
result += line;
}
// 此处 result 就是接受到的微信支付异步通知报文,直接使用WXPayUtil工具解析xml报文内容即可
Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
// 通过微信支付通知的返回结果,校验是否支付成功
String returnCode = resultMap.get("return_code");
String resultCode = resultMap.get("result_code");
if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
String outTradeNo = resultMap.get("out_trade_no");
//... 业务逻辑处理
// 返回给微信支付结果通知接收服务器的信息
String returnMsg = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml>";
return returnMsg;
} else {
String returnMsg = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[支付失败]]></return_msg>" + "</xml>";
return returnMsg;
}
} catch (Exception e) {
logger.error("微信支付结果回调出现异常:{}", e.getMessage());
return null;
}
}
/**
* 发起微信支付
* @param order
* @return
* @throws Exception
*/
@PostMapping("/wxpay")
public Map<String, String> wxPay(@RequestBody Order order) throws Exception {
// 生成微信支付订单并获取支付信息
Map<String, String> result = createUnifiedOrder(order);
if(result != null) {
return result;
} else {
return null;
}
}
}
总结
通过以上步骤,我们已经成功地实现了SpringBoot实现微信支付的功能。在实际使用中,您可以根据具体需求对代码进行调整,增强支付的可用性。同时我们也需要注意,支付过程中需要注意数据安全性和消息传递的可靠性。文章来源:https://www.toymoban.com/news/detail-647525.html
希望本文对您有所帮助,谢谢阅读。文章来源地址https://www.toymoban.com/news/detail-647525.html
到了这里,关于SpringBoot实现微信支付的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!