java之学习记录 8 - 2 - vue + java 微信支付

3 篇文章 0 订阅

vue前端

  • 安装 qrcodejs2 (注意:安装的是qrcodejs2,不要安装qrcode ---> 会报错)
npm install qrcodejs2 --save
  • 页面中引入
<!-- 微信支付二维码 -->
<el-dialog :visible.sync="dialogFormVisible" style="width:800px;margin:0px auto;">
    <h1 style="font-size:30px;color:#00B38A">微信扫一扫支付</h1>
    <div id="qrcode" style="width:210px;margin:20px auto;"></div>
    <h2 id="statusText"></h2>
    <p id="closeText"></p>
</el-dialog>

<script>
import QRCode from "qrcodejs2"; // 引入qrcodejs
import { setInterval, clearInterval } from 'timers';
export default {
  name: "Course",
  components: {
    QRCode // 声明组件
  },
  data() {
    return {
      dialogFormVisible: false, // false默认隐藏,true 显示
      time:null, // 计时对象
    };
  },
  methods: {
    // 购买
    buy(courseid) {
      // alert("购买第【" + courseid + "】门课程成功,加油!");
      this.dialogFormVisible = true; //显示提示框
      // 待dom更新之后再用二维码渲染其内容
      this.$nextTick(function() {
        this.createCode(); // 直接调用会报错:TypeError: Cannot read property 'appendChild' of null
      });
    },
    // 生成支付二维码
    createCode() {
      // 去获取支付链接
      this.axios
        .get("http://localhost:80/order/createCode", {
          params: {
            courseId: this.course.id,
            courseName: this.course.courseName,
            price: this.course.discounts
          }
        })
        .then(res => {
          console.log(res);
          // QRCode (存放二维码的dom元素的id,二维码的属性参数)
          let qrcode = new QRCode("qrcode", {
            width: 200,
            height: 200,
            text: res.data.result_url // 将返回的数据嵌入到二维码中
          });
          this.orderNo = res.data.orderId;
        
          // *****************************************
          // 真实的修改数据库 保存订单
          // this.saveOrder();
          // *****************************************

          // 检查支付状态
          this.axios
          .get("http://localhost:80/order/checkOrderStatus", {
            params: {
              orderId: res.data.orderId // 传递订单编号 进行查询
            }
          })
          .then(res => {
              console.log(res);
              if(res.data.trade_state == "SUCCESS"){
                document.getElementById("statusText").innerHTML = "<i style='color:#00B38A' class='el-icon-success'></i>支付成功"

                // *****************************************
                // 支付成功后 写后续的逻辑(如更改订单状态)
                // *****************************************

              } 
              
              // 3s后关闭二维码窗口
              let s = 3; // 倒计时的秒数
              this.closeQRForm(s); // 关闭二维码窗口
            })
            .catch(err => {
              this.$message.error("生成订单失败!");
            });
        })
        .catch(err => {
          this.$message.error("生成支付二维码失败!");
        });
    },
    // 倒计时关闭二维码窗口
    closeQRForm(s){
      let that = this;
      that.time = setInterval(function(){
        document.getElementById("closeText").innerHTML = "("+ s-- +")秒后关闭本窗口";
        if(s == 0){
          clearInterval(that.time); // 停止计时器
          that.dialogFormVisible = false; // 二维码窗口隐藏
          that.isBuy = true;// 修改购买状态(已购买)
        }
      },1000)
    },
  }
}

</script>

Java后端

支付配置类

package commons;

/**
 * 微信支付商户配置类
 */
public class Payconfig {
    //企业公众号ID
    public static String appid = "";
    // 财付通平台的商户帐号
    public static String partner = "";
    // 财付通平台的商户密钥
    public static String partnerKey = "";
    // 回调URL
    public static String notifyurl = "";
}

依赖

        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>
主要使用 sdk 中的三个功能:
  • 1、获取随机字符串(生成订单编号)
WXPayUtil.generateNonceStr();
  • 2 、将 map 转换成 xml 字符串(自动添加签名)
WXPayUtil.generateSignedXml(map,partnerKey);
  • 3、将xml字符串转换整map
WXPayUtil.xmlToMap(result);
JFinal 框架
  • JFinal 是基于Java 语言的极速 web 开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展
  • 取代HttpClient
         <dependency>
            <groupId>com.jfinal</groupId>
            <artifactId>jfinal</artifactId>
            <version>3.5</version>
        </dependency>

构建二维码

  • createCodeController
package com.lagou.wx;

import com.github.wxpay.sdk.WXPayUtil;
import com.jfinal.kit.HttpKit;
import commons.Payconfig;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付相关控制
 */
@RestController
@RequestMapping("order")
public class WxPayController {

    // 创建支付二维码
    @GetMapping("createCode")
    public Object createCode(String courseId,String courseName,String price) throws Exception {
        // 编写商品信息写入到map中
        Map<String ,String> map = new HashMap();
        map.put("appid", Payconfig.appid); // 公众号id
        map.put("mch_id",Payconfig.partner); // 商户号
        map.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串
        courseName = new String(courseName.getBytes("ISO-8859-1"),"UTF-8");
        map.put("body",courseName); // 商品简单描述
        map.put("out_trade_no",WXPayUtil.generateNonceStr()); // 随机生成的商户订单号
        map.put("total_fee",price); // 订单金额  单位为分,只能为整数
        map.put("spbill_create_ip","127.0.0.1"); // 终端ip
        map.put("notify_url",Payconfig.notifyurl); // 通知地址
        map.put("trade_type","NATIVE"); // 交易类型
        System.out.println("商户信息 = " + map);

        // 生成数字签名,并发商户信息转换成xml格式
        String xml = WXPayUtil.generateSignedXml(map, Payconfig.partnerKey);
        System.out.println("商户的xml信息 = " + xml);

        // 将xml数据发送给微信支付平台,从而生成订单
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        // -- 发送请求,返回一个xml格式的字符串
        String result = HttpKit.post(url, xml);

        // 微信支付平台返回xml格式数据,将其转换成map格式并返回给前端
        Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
        resultMap.put("orderId",map.get("out_trade_no"));
        System.out.println("返回的xml,转换成map = " + resultMap);

        return resultMap;
    }

    // 查看支付状态
    @GetMapping("checkOrderStatus")
    public Object checkOrderStatus(String orderId) throws Exception {
        // 编写商户信息
        // 编写商品信息写入到map中
        Map<String ,String> map = new HashMap();
        map.put("appid", Payconfig.appid); // 公众号id
        map.put("mch_id",Payconfig.partner); // 商户号
        map.put("out_trade_no",orderId); // 商户订单号
        map.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串
        // 生成数字签名
        String xml = WXPayUtil.generateSignedXml(map, Payconfig.partnerKey);
        // 发送查询请求给微信支付平台
        String url = "https://api.mch.weixin.qq.com/pay/orderquery";
        // 查询订单状态的开始时间点
        long beginTime = System.currentTimeMillis();
        // 不停的去微信支付平台询问是否支付成功
        while (true){
            // 对微信支付平台返回的查询结果进行处理
            String result = HttpKit.post(url, xml);
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            // 已经支付成功,不再询问
            if(resultMap.get("trade_state").equalsIgnoreCase("SUCCESS")){
                return resultMap;
            }
            // 超过30s 未支付 ,停止询问
            if (System.currentTimeMillis() - beginTime > 30000){
                return resultMap;
            }
            Thread.sleep(3000); // 每隔3s,询问一次微信支付平台
        }


    }
}

解决中文乱码

new String(coursename.getBytes("ISO-8859-1"),"UTF-8");

支付流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值