当前位置:   article > 正文

SpringBoot整合Vue实现微信扫码支付、微信退款功能_string xml = client.getcontent() 微信退款返回null

string xml = client.getcontent() 微信退款返回null

直接上代码,在order模块添加依赖

  1. <dependency>
  2. <groupId>com.github.wxpay</groupId>
  3. <artifactId>wxpay-sdk</artifactId>
  4. <version>0.0.3</version>
  5. </dependency>

 在配置类添加申请的商家号信息

  1. #关联的公众号appid
  2. weixin.pay.appid=wxXXXXXXX
  3. #商户号
  4. weixin.pay.partner=XXXXXXXXX
  5. #商户key
  6. weixin.pay.partnerkey=XXXXXXXXXX

添加微信生成二维码service

  1. @Service
  2. public class WeiXinServiceImpl implements WeiXinService {
  3. @Autowired
  4. private PaymentInfoService paymentInfoService;
  5. @Autowired
  6. private OrderInfoService orderInfoService;
  7. @Autowired
  8. private WeiXinService weiXinService;
  9. //生成支付的二维码
  10. @Override
  11. public Map createNative(Long orderId) {
  12. //支付记录表添加数据
  13. //根据单号查询订单相关信息
  14. OrderInfo orderInfo = orderInfoService.getById(orderId);
  15. if (orderInfo == null){
  16. throw new OrderException(20001,"订单不存在");
  17. }
  18. //添加订单状态
  19. paymentInfoService.savePaymentInfo(orderInfo,PaymentTypeEnum.WEIXIN.getStatus());
  20. //调用微信接口返回二维码
  21. try {
  22. //2 调用微信接口,得到二维码地址等信息
  23. //封装传递微信地址参数
  24. Map paramMap = new HashMap();
  25. paramMap.put("appid", ConstantPropertiesUtils.APPID); //公众号id
  26. paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER); //商户号
  27. paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串,调用工具类
  28. Date reserveDate = orderInfo.getReserveDate();
  29. String reserveDateString = new DateTime(reserveDate).toString("yyyy/MM/dd");
  30. String body = reserveDateString + "就诊"+ orderInfo.getDepname();
  31. paramMap.put("body", body);//扫码后手机显示内容
  32. paramMap.put("out_trade_no", orderInfo.getOutTradeNo()); //订单流水号
  33. //paramMap.put("total_fee", order.getAmount().multiply(new BigDecimal("100")).longValue()+"");
  34. paramMap.put("total_fee", "1");//TODO 为了测试 支付金额
  35. paramMap.put("spbill_create_ip", "127.0.0.1"); //终端ip
  36. paramMap.put("notify_url", "http://xxxxxxxxx");//回调地址
  37. paramMap.put("trade_type", "NATIVE"); //二维码类型
  38. //请求微信生成二维码接口
  39. HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
  40. //设置post请求相关参数
  41. //微信支付要求传递参数xml格式
  42. //把封装map集合变成xml,加密处理,传输
  43. String xml = WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY);
  44. client.setXmlParam(xml);
  45. //支持https协议
  46. client.setHttps(true);
  47. //发送
  48. client.post();
  49. //调用微信接口,返回数据,xml格式的数据
  50. String resultXml = client.getContent();
  51. System.out.println("微信二维码:"+resultXml);
  52. //把xml格式数据转换map
  53. Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXml);
  54. Map map = new HashMap<>();
  55. map.put("orderId", orderId);
  56. map.put("totalFee", orderInfo.getAmount());
  57. map.put("resultCode", resultMap.get("result_code"));
  58. map.put("codeUrl", resultMap.get("code_url")); //微信二维码地址
  59. return map;
  60. } catch (Exception e) {
  61. e.printStackTrace();
  62. throw new orderException(20001,"生成二维码失败");
  63. }
  64. }
  65. }

控制层

  1. @RestController
  2. @RequestMapping("/api/order/weixin")
  3. public class WeixinController {
  4. @Autowired
  5. private WeiXinService weixinPayService;
  6. /**
  7. * 下单 生成二维码
  8. */
  9. @GetMapping("/createNative/{orderId}")
  10. public R createNative(
  11. @ApiParam(name = "orderId", value = "订单id", required = true)
  12. @PathVariable("orderId") Long orderId) {
  13. Map map = weixinPayService.createNative(orderId);
  14. return R.ok().data(map);
  15. }
  16. }

前端微信支付二维码,wx.js定义方法

  1. createNative(orderId) {
  2. return request({
  3. url: `/api/order/weixin/createNative/${orderId}`,
  4. method: 'get'
  5. })
  6. }

显示二维码需要前端安装插件    安装npm install vue-qriously

订单详情页,修改order/show.vue组件

  1. import weixinApi from '@/api/yygh/wx'
  2. <!-- 微信支付弹出框 -->
  3. <el-dialog :visible.sync="dialogPayVisible" style="text-align: left" :append-to-body="true" width="500px" @close="closeDialog">
  4. <div class="container">
  5. <div class="operate-view" style="height: 350px;">
  6. <div class="wrapper wechat">
  7. <div>
  8. <qriously :value="payObj.codeUrl" :size="220"/>
  9. <div style="text-align: center;line-height: 25px;margin-bottom: 40px;">
  10. 请使用微信扫一扫<br/>
  11. 扫描二维码支付
  12. </div>
  13. </div>
  14. </div>
  15. </div>
  16. </div>
  17. </el-dialog>
  18. //生成二维码
  19. pay() {
  20. //弹框
  21. this.dialogPayVisible = true
  22. //调用接口
  23. weixinApi.createNative(this.orderId).then(response => {
  24. this.payObj = response.data
  25. if(this.payObj.codeUrl == '') {
  26. this.dialogPayVisible = false
  27. this.$message.error("支付错误")
  28. } else {
  29. //每隔3秒查询一次支付状态
  30. this.timer = setInterval(()=>{
  31. this.queryPayStatus(this.orderId)
  32. },3000)
  33. }
  34. })
  35. },

查询订单支付状态,添加定时器方法,每隔3秒去查询一次支付状态,api

  1. queryPayStatus(orderId) {
  2. return request({
  3. url: `/api/order/weixin/queryPayStatus/${orderId}`,
  4. method: 'get'
  5. })
  6. },

后端,weixinservice封装信息请求微信提供的接口,判断是否支付成功,因为微信返回的是xml文件,所以需要转换

  1. //调用微信接口查询支付状态
  2. @Override
  3. public Map queryPayStatus(Long orderId, String paymentType) {
  4. //1 根据orderId查询订单信息
  5. OrderInfo orderInfo = orderInfoService.getById(orderId);
  6. if(orderInfo == null) {
  7. throw new orderException(20001,"订单不存在");
  8. }
  9. try {
  10. //2 封装微信接口需要数据
  11. Map paramMap = new HashMap<>();
  12. paramMap.put("appid", ConstantPropertiesUtils.APPID);
  13. paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
  14. paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
  15. paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
  16. //3 调用微信接口,传递数据,设置参数
  17. HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
  18. client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
  19. client.setHttps(true);
  20. client.post();
  21. //4 获取微信接口返回数据
  22. String xml = client.getContent();
  23. System.out.println("支付状态返回xml: "+xml);
  24. Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
  25. return resultMap;
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. throw new orderException(20001,"查询失败");
  29. }
  30. }

支付成功后,更新状态

控制层,查询状态

  1. @ApiOperation(value = "查询支付状态")
  2. @GetMapping("/queryPayStatus/{orderId}")
  3. public Result queryPayStatus(
  4. @ApiParam(name = "orderId", value = "订单id", required = true)
  5. @PathVariable("orderId") Long orderId) {
  6. //调用查询接口
  7. Map<String, String> resultMap = weixinPayService.queryPayStatus(orderId, PaymentTypeEnum.WEIXIN.name());
  8. if (resultMap == null) {//出错
  9. return Result.fail().message("支付出错");
  10. }
  11. if ("SUCCESS".equals(resultMap.get("trade_state"))) {//如果成功
  12. //更改订单状态,处理支付结果
  13. String out_trade_no = resultMap.get("out_trade_no");
  14. paymentInfoService.paySuccess(out_trade_no, PaymentTypeEnum.WEIXIN.getStatus(), resultMap);
  15. return Result.ok().message("支付成功");
  16. }
  17. return Result.ok().message("支付中");
  18. }

退款

退款与支付唯一不同的是需要在下载微信提供的退款证书,下载好后通过配置文件加载退款证书路径

weixin.cert=C:\\apiclient_cert.p12

weixinservice中

  1. //退款
  2. @Override
  3. public Boolean refund(Long orderId) {
  4. //1 根据订单号查询订单支付记录信息
  5. QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
  6. wrapper.eq("order_id",orderId);
  7. PaymentInfo paymentInfo = paymentInfoService.getOne(wrapper);
  8. //2 TODO 添加退款信息到退款表
  9. try {
  10. //3 调用微信退款接口
  11. //封装微信接口需要数据
  12. Map<String,String> paramMap = new HashMap<>(8);
  13. paramMap.put("appid",ConstantPropertiesUtils.APPID); //公众账号ID
  14. paramMap.put("mch_id",ConstantPropertiesUtils.PARTNER); //商户编号
  15. paramMap.put("nonce_str",WXPayUtil.generateNonceStr());
  16. paramMap.put("transaction_id",paymentInfo.getTradeNo()); //微信订单号
  17. paramMap.put("out_trade_no",paymentInfo.getOutTradeNo()); //商户订单编号
  18. paramMap.put("out_refund_no","tk"+paymentInfo.getOutTradeNo()); //商户退款单号
  19. // paramMap.put("total_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
  20. // paramMap.put("refund_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
  21. paramMap.put("total_fee","1");
  22. paramMap.put("refund_fee","1");
  23. //设置接口和参数
  24. HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");
  25. client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
  26. client.setHttps(true);
  27. client.setCert(true);//退款证书
  28. client.setCertPassword(ConstantPropertiesUtils.PARTNER);//证书密码 商户key
  29. //发送post请求
  30. client.post();
  31. //4、返回退款数据
  32. String xml = client.getContent();
  33. Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. return null;
  38. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/308146
推荐阅读
相关标签
  

闽ICP备14008679号