1. SpringBoot+Vue實現(xiàn)微信掃碼支付、退款功能

        共 8973字,需瀏覽 18分鐘

         ·

        2022-10-27 14:05

        直接上代碼,在order模塊添加依賴
        <dependency>    <groupId>com.github.wxpay</groupId>    <artifactId>wxpay-sdk</artifactId>    <version>0.0.3</version></dependency>

        在配置類添加申請的商家號信息

        #關聯(lián)的公眾號appidweixin.pay.appid=wxXXXXXXX#商戶號weixin.pay.partner=XXXXXXXXX#商戶keyweixin.pay.partnerkey=XXXXXXXXXX


        添加微信生成二維碼service

        @Servicepublic class WeiXinServiceImpl implements WeiXinService {    @Autowired    private PaymentInfoService paymentInfoService;    @Autowired    private OrderInfoService orderInfoService;    @Autowired    private WeiXinService weiXinService;    //生成支付的二維碼    @Override    public Map createNative(Long orderId) {        //支付記錄表添加數(shù)據(jù)        //根據(jù)單號查詢訂單相關信息        OrderInfo orderInfo = orderInfoService.getById(orderId);        if (orderInfo == null){            throw new OrderException(20001,"訂單不存在");        }        //添加訂單狀態(tài)        paymentInfoService.savePaymentInfo(orderInfo,PaymentTypeEnum.WEIXIN.getStatus());        //調用微信接口返回二維碼        try {            //2 調用微信接口,得到二維碼地址等信息            //封裝傳遞微信地址參數(shù)            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請求相關參數(shù)            //微信支付要求傳遞參數(shù)xml格式            //把封裝map集合變成xml,加密處理,傳輸            String xml = WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY);            client.setXmlParam(xml);            //支持https協(xié)議            client.setHttps(true);            //發(fā)送            client.post();             //調用微信接口,返回數(shù)據(jù),xml格式的數(shù)據(jù)            String resultXml = client.getContent();            System.out.println("微信二維碼:"+resultXml);            //把xml格式數(shù)據(jù)轉換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秒查詢一次支付狀態(tài)          this.timer = setInterval(()=>{            this.queryPayStatus(this.orderId)          },3000)        }      })    },

        查詢訂單支付狀態(tài),添加定時器方法,每隔3秒去查詢一次支付狀態(tài),api

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


        后端,weixinservice封裝信息請求微信提供的接口,判斷是否支付成功,因為微信返回的是xml文件,所以需要轉換

        //調用微信接口查詢支付狀態(tài)@Overridepublic Map queryPayStatus(Long orderId, String paymentType) {    //1 根據(jù)orderId查詢訂單信息    OrderInfo orderInfo = orderInfoService.getById(orderId);    if(orderInfo == null) {        throw new orderException(20001,"訂單不存在");    }    try {        //2 封裝微信接口需要數(shù)據(jù)        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 調用微信接口,傳遞數(shù)據(jù),設置參數(shù) 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 獲取微信接口返回數(shù)據(jù) String xml = client.getContent(); System.out.println("支付狀態(tài)返回xml: "+xml); Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
        return resultMap;
        } catch (Exception e) { e.printStackTrace(); throw new orderException(20001,"查詢失敗"); }}


        支付成功后,更新狀態(tài)


        控制層,查詢狀態(tài)

        @ApiOperation(value = "查詢支付狀態(tài)")@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"))) {//如果成功        //更改訂單狀態(tài),處理支付結果        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中

        //退款@Overridepublic Boolean refund(Long orderId) {    //1 根據(jù)訂單號查詢訂單支付記錄信息    QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();    wrapper.eq("order_id",orderId);    PaymentInfo paymentInfo = paymentInfoService.getOne(wrapper);
        //2 TODO 添加退款信息到退款表
        try { //3 調用微信退款接口 //封裝微信接口需要數(shù)據(jù) 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");
        //設置接口和參數(shù) 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 //發(fā)送post請求 client.post();
        //4、返回退款數(shù)據(jù) String xml = client.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);

        } catch (Exception e) { e.printStackTrace(); }
        return null;}


        入骨相思知不知


        玲瓏骰子安紅豆


        入我相思門,知我相思苦,長相思兮長相憶,短相思兮無窮極。

        瀏覽 60
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 丰满的女人性猛交 | 久久久99国产精品免费 | 欧美国产一二三区小说 | 999免费视频 | 国产精品久久久久久久久久免 |