Spring Boot与Vue集成微信Native支付及退款全流程解析
详解Spring Boot后端与Vue前端集成微信Native支付及退款的完整代码实现,包括参数配置、二维码生成、状态轮询及证书退款处理。
1. 准备条件与依赖配置
在Spring Boot项目中实现微信支付,首先需要引入官方提供的SDK或第三方封装库,并配置商户核心信息。
第1步:添加Maven依赖
在项目的 order 模块(或相关业务模块)的 pom.xml 中添加微信SDK依赖。这里使用的是较为常见的第三方封装版本:
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
第2步:配置商户敏感信息
在配置文件(如 application.yml 或 properties)中保存微信公众号AppID、商户号(Partner ID)及商户密钥(Partner Key)。这些数据用于后续请求签名和身份验证:
# 关联的公众号appid
weixin.pay.appid=wxXXXXXXX
# 商户号
weixin.pay.partner=XXXXXXXXX
# 商户key
weixin.pay.partnerkey=XXXXXXXXXX
2. 实现Native扫码支付流程
Native支付的核心是后端生成包含商品信息的二维码URL,返回给前端展示,前端通过定时器轮询支付结果。
第3步:后端Service层封装下单逻辑
创建 WeiXinServiceImpl,重点实现 createNative 方法。该方法负责组装微信统一下单所需参数,生成签名,发送HTTP请求获取二维码地址。
- 目的:获取微信生成的付款码URL。
- 关键步骤:
- 根据订单ID查询订单详情,确保订单存在。
- 构建参数Map,包含
appid、mch_id、随机串nonce_str、商品描述body、商户订单号out_trade_no、金额total_fee(单位:分)、终端IPspbill_create_ip、回调地址notify_url及交易类型NATIVE。 - 使用工具类将Map转换为XML格式字符串并进行签名。
- 通过HTTP Client发送POST请求到微信统一下单接口
https://api.mch.weixin.qq.com/pay/unifiedorder。 - 解析返回的XML响应,提取
code_url。
@Service
public class WeiXinServiceImpl implements WeiXinService {
@Autowired
private PaymentInfoService paymentInfoService;
@Autowired
private OrderInfoService orderInfoService;
@Override
public Map createNative(Long orderId) {
// 1. 查询订单
OrderInfo orderInfo = orderInfoService.getById(orderId);
if (orderInfo == null) {
throw new OrderException(20001, "订单不存在");
}
// 记录支付流水
paymentInfoService.savePaymentInfo(orderInfo, PaymentTypeEnum.WEIXIN.getStatus());
try {
// 2. 封装参数
Map paramMap = new HashMap();
paramMap.put("appid", ConstantPropertiesUtils.APPID);
paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
String body = "就诊" + orderInfo.getDepname(); // 示例业务描述
paramMap.put("body", body);
paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
// 注意:实际生产中金额需从数据库读取,此处为测试金额1分
paramMap.put("total_fee", "1");
paramMap.put("spbill_create_ip", "127.0.0.1");
paramMap.put("notify_url", "http://your-notify-url/callback");
paramMap.put("trade_type", "NATIVE");
// 3. 发送请求
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
client.setHttps(true);
client.post();
// 4. 解析结果
String resultXml = client.getContent();
Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXml);
// 5. 返回前端所需数据
Map responseMap = new HashMap();
responseMap.put("orderId", orderId);
responseMap.put("totalFee", orderInfo.getAmount());
responseMap.put("codeUrl", resultMap.get("code_url"));
return responseMap;
} catch (Exception e) {
throw new RuntimeException("生成二维码失败", e);
}
}
}
第4步:Controller暴露接口
提供REST接口供前端调用:
@RestController
@RequestMapping("/api/order/weixin")
public class WeixinController {
@Autowired
private WeiXinService weixinPayService;
@GetMapping("/createNative/{orderId}")
public R createNative(@PathVariable Long orderId) {
Map map = weixinPayService.createNative(orderId);
return R.ok().data(map);
}
}
第5步:前端Vue集成显示二维码
前端需安装 vue-qriously 插件以渲染二维码。
- 安装:
npm install vue-qriously - 组件示例:在订单详情页弹出Dialog,接收后端返回的
codeUrl并渲染。
<!-- 模板部分 -->
<el-dialog :visible.sync="dialogPayVisible">
<qriously :value="payObj.codeUrl" :size="220"/>
<p>请使用微信扫一扫扫描二维码支付</p>
</el-dialog>
<!-- JS逻辑 -->
pay() {
this.dialogPayVisible = true;
weixinApi.createNative(this.orderId).then(response => {
this.payObj = response.data;
if (this.payObj.codeUrl) {
// 开启定时器轮询支付状态
this.timer = setInterval(() => {
this.queryPayStatus(this.orderId);
}, 3000);
}
});
}
3. 支付状态查询与通知处理
由于前端无法实时获取支付结果,通常采用轮询机制。同时后端也需支持主动查询。
第6步:后端实现支付状态查询
调用微信“查询订单”接口 https://api.mch.weixin.qq.com/pay/orderquery。
@Override
public Map queryPayStatus(Long orderId, String paymentType) {
OrderInfo orderInfo = orderInfoService.getById(orderId);
if (orderInfo == null) throw new RuntimeException("订单不存在");
try {
Map paramMap = new HashMap();
paramMap.put("appid", ConstantPropertiesUtils.APPID);
paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
client.setHttps(true);
client.post();
Map<String, String> resultMap = WXPayUtil.xmlToMap(client.getContent());
return resultMap;
} catch (Exception e) {
throw new RuntimeException("查询失败", e);
}
}
第7步:前端轮询与状态更新
前端每3秒调用一次查询接口。若后端返回 trade_state 为 SUCCESS,则停止轮询,提示用户支付成功,并关闭弹窗。
4. 实现微信退款功能
退款接口与支付不同,涉及资金回退,因此需要双向SSL证书认证,安全性要求更高。
第8步:配置退款证书
下载微信支付平台证书的 .p12 文件,并在配置文件中指定其本地路径:
weixin.cert=C:\\apiclient_cert.p12
第9步:后端Service层封装退款逻辑
退款接口地址为 https://api.mch.weixin.qq.com/secapi/pay/refund。需注意以下几点:
- 必须开启证书认证:
client.setCert(true)。 - 设置证书密码,通常为商户MCH_ID。
- 参数中包含原交易ID
transaction_id或商户订单号out_trade_no,以及退款金额refund_fee。
@Override
public Boolean refund(Long orderId) {
// 1. 获取原支付信息
PaymentInfo paymentInfo = paymentInfoService.getByOrderId(orderId);
try {
// 2. 封装退款参数
Map<String, String> paramMap = new HashMap();
paramMap.put("appid", ConstantPropertiesUtils.APPID);
paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
paramMap.put("transaction_id", paymentInfo.getTradeNo());
paramMap.put("out_trade_no", paymentInfo.getOutTradeNo());
paramMap.put("out_refund_no", "tk" + paymentInfo.getOutTradeNo());
// 退款金额和总金额,单位分
paramMap.put("total_fee", "1");
paramMap.put("refund_fee", "1");
// 3. 发起请求
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");
client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
client.setHttps(true);
client.setCert(true);
client.setCertPassword(ConstantPropertiesUtils.PARTNER); // 证书密码即商户号
client.post();
// 4. 解析结果
String xml = client.getContent();
Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
return "SUCCESS".equals(resultMap.get("result_code"));
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
以上就是Spring Boot整合Vue实现微信扫码支付以及微信退款功能的详细内容,更多关于Spring Boot Vue微信支付的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









