我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringBoot整合Vue实现微信扫码支付以及微信退款功能详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringBoot整合Vue实现微信扫码支付以及微信退款功能详解

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

        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>

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

#关联的公众号appid
weixin.pay.appid=wxXXXXXXX
#商户号
weixin.pay.partner=XXXXXXXXX
#商户key
weixin.pay.partnerkey=XXXXXXXXXX

添加微信生成二维码service

@Service
public class WeiXinServiceImpl implements WeiXinService {
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private WeiXinService weiXinService;
    //生成支付的二维码
    @Override
    public Map createNative(Long orderId) {
        //支付记录表添加数据
        //根据单号查询订单相关信息
        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); //公众号id
            paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER); //商户号
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串,调用工具类
 
            Date reserveDate = orderInfo.getReserveDate();
            String reserveDateString = new DateTime(reserveDate).toString("yyyy/MM/dd");
            String body = reserveDateString + "就诊"+ orderInfo.getDepname();
            paramMap.put("body", body);//扫码后手机显示内容
 
            paramMap.put("out_trade_no", orderInfo.getOutTradeNo()); //订单流水号
            //paramMap.put("total_fee", order.getAmount().multiply(new BigDecimal("100")).longValue()+"");
            paramMap.put("total_fee", "1");//TODO 为了测试  支付金额
            paramMap.put("spbill_create_ip", "127.0.0.1");  //终端ip
            paramMap.put("notify_url", "http://xxxxxxxxx");//回调地址
            paramMap.put("trade_type", "NATIVE"); //二维码类型
            //请求微信生成二维码接口
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
            //设置post请求相关参数
            //微信支付要求传递参数xml格式
            //把封装map集合变成xml,加密处理,传输
            String xml = WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY);
            client.setXmlParam(xml);
            //支持https协议
            client.setHttps(true);
            //发送
            client.post();
 
            //调用微信接口,返回数据,xml格式的数据
            String resultXml = client.getContent();
            System.out.println("微信二维码:"+resultXml);
            //把xml格式数据转换map
            Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXml);
 
            Map map = new HashMap<>();
            map.put("orderId", orderId);
            map.put("totalFee", orderInfo.getAmount());
            map.put("resultCode", resultMap.get("result_code"));
            map.put("codeUrl", resultMap.get("code_url"));  //微信二维码地址
 
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            throw new orderException(20001,"生成二维码失败");
        }
    }
}

控制层

@RestController
@RequestMapping("/api/order/weixin")
public class WeixinController {
    @Autowired
    private WeiXinService weixinPayService;
    
    @GetMapping("/createNative/{orderId}")
    public R createNative(
            @ApiParam(name = "orderId", value = "订单id", required = true)
            @PathVariable("orderId") Long orderId) {
        Map map = weixinPayService.createNative(orderId);
        return R.ok().data(map);
    }
}

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

createNative(orderId) {
 return request({
 url: `/api/order/weixin/createNative/${orderId}`,
 method: 'get'
 })
}

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

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

import weixinApi from '@/api/yygh/wx'
 
<!-- 微信支付弹出框 -->
    <el-dialog :visible.sync="dialogPayVisible" style="text-align: left" :append-to-body="true" width="500px" @close="closeDialog">
      <div class="container">
        <div class="operate-view" style="height: 350px;">
          <div class="wrapper wechat">
            <div>
              <qriously :value="payObj.codeUrl" :size="220"/>
              <div style="text-align: center;line-height: 25px;margin-bottom: 40px;">
                请使用微信扫一扫<br/>
                扫描二维码支付
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
    
 //生成二维码
    pay() {
      //弹框
      this.dialogPayVisible = true
      //调用接口
      weixinApi.createNative(this.orderId).then(response => {
        this.payObj = response.data
        if(this.payObj.codeUrl == '') {
          this.dialogPayVisible = false
          this.$message.error("支付错误")
        } else {
          //每隔3秒查询一次支付状态
          this.timer = setInterval(()=>{
            this.queryPayStatus(this.orderId)
          },3000)
        }
      })
    },

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

queryPayStatus(orderId) {
 return request({
 url: `/api/order/weixin/queryPayStatus/${orderId}`,
 method: 'get'
 })
},

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

//调用微信接口查询支付状态
    @Override
    public Map queryPayStatus(Long orderId, String paymentType) {
        //1 根据orderId查询订单信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        if(orderInfo == null) {
            throw new orderException(20001,"订单不存在");
        }
        try {
            //2 封装微信接口需要数据
            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());
 
            //3 调用微信接口,传递数据,设置参数
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
            client.setHttps(true);
            client.post();
 
            //4 获取微信接口返回数据
            String xml = client.getContent();
            System.out.println("支付状态返回xml: "+xml);
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
 
            return resultMap;
 
        } catch (Exception e) {
            e.printStackTrace();
            throw new orderException(20001,"查询失败");
        }
    }

支付成功后,更新状态

控制层,查询状态

@ApiOperation(value = "查询支付状态")
@GetMapping("/queryPayStatus/{orderId}")
public Result queryPayStatus(
        @ApiParam(name = "orderId", value = "订单id", required = true)
        @PathVariable("orderId") Long orderId) {
    //调用查询接口
    Map<String, String> resultMap = weixinPayService.queryPayStatus(orderId, PaymentTypeEnum.WEIXIN.name());
    if (resultMap == null) {//出错
        return Result.fail().message("支付出错");
    }
    if ("SUCCESS".equals(resultMap.get("trade_state"))) {//如果成功
        //更改订单状态,处理支付结果
        String out_trade_no = resultMap.get("out_trade_no");
        paymentInfoService.paySuccess(out_trade_no, PaymentTypeEnum.WEIXIN.getStatus(), resultMap);
        return Result.ok().message("支付成功");
    }
    return Result.ok().message("支付中");
}

退款

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

weixin.cert=C:\\apiclient_cert.p12

weixinservice中

//退款
    @Override
    public Boolean refund(Long orderId) {
        //1 根据订单号查询订单支付记录信息
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderId);
        PaymentInfo paymentInfo = paymentInfoService.getOne(wrapper);
 
        //2 TODO 添加退款信息到退款表
 
        try {
            //3 调用微信退款接口
            //封装微信接口需要数据
            Map<String,String> paramMap = new HashMap<>(8);
            paramMap.put("appid",ConstantPropertiesUtils.APPID);       //公众账号ID
            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",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
            //       paramMap.put("refund_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
            paramMap.put("total_fee","1");
            paramMap.put("refund_fee","1");
 
            //设置接口和参数
            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);//证书密码 商户key
            //发送post请求
            client.post();

            //4、返回退款数据
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

总结

到此这篇关于SpringBoot整合Vue实现微信扫码支付以及微信退款功能的文章就介绍到这了,更多相关SpringBoot整合Vue微信扫码支付退款内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SpringBoot整合Vue实现微信扫码支付以及微信退款功能详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录