微信支付

1、创建二维码

1、安装 qrcodejs2 (注意:安装的是qrcodejs2,不要安装qrcode ---> 会报错)

npm install  qrcodejs2 --save

2、页面中引入

<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>
</el-dialog><script>
import QRCode from 'qrcodejs2'; // 引入qrcodejsexport default {name: "Index",components: {Header,Footer,QRCode  // 声明组件},data() {return {dialogFormVisible: false, // 是否显示登录框,true:显示,false:隐藏};},methods: {// 购买课程buy(courseid) {//alert("购买第【" + courseid + "】门课程成功,加油!");this.dialogFormVisible = true; //显示提示框// 待dom更新之后再用二维码渲染其内容this.$nextTick(function(){this.createCode(); // 直接调用会报错:TypeError: Cannot read property 'appendChild' of null});},// 生成二维码createCode(){// QRCode(存放二维码的dom元素id,二维码的属性参数)let qrcode = new QRCode('qrcode',{width:200,  // 二维码的宽度height:200,  // 二维码的高度text:"我爱你中国"  // 二维码中包含的信息});},},
};
</script>

2、准备工作

2.1 名词介绍

参数 说明
appid 微信公众帐号或开放平台APP的唯一标识
partner 商户号(配置文件中的partner:账户)
partnerkey 商户密钥(密码)
sign 数字签名,根据微信官方提供的密钥和一套算法生成的一个加密信息,就是为了保证交易安全
  • 如果获得这些信息?

    • 需要注册认证公众号,费用300元/次

2.2 获取认证的流程

1) 注册公众号(类型:服务号)

根据营业执照类型选择以下主体注册: 个体工商户 | 企业/公司 | 政府 | 媒体 | 其他类型

2) 认证公众号

公众号认证后才申请微信支付:300元/次

3) 提交材料申请微信支付

登录公众平台,左侧菜单【微信支付】,开始填写资料等待审核,审核时间1~5工作日 这里需要提交的资料有营业执照!

4) 开户成功,登录商户平台进行验证

资料审核通过后,请登录联系人邮箱查收商户号和密码,并登录商户平台填写财付通备付金打的小额资金数额,完成账户验证。

5) 在线签署协议

本协议为线上电子协议,签署后方可进行交易及资金结算,签署完立即生效。

6) 查看自己的公众号的参数

public class PayConfig {//企业公众号IDpublic static String appid="wx307113892f15a42e";//财付通平台的商户帐号public static String partner="1508236581";//财付通平台的商户密钥public static String partnerKey="HJd7sHGHd6djgdgFG5778GFfhghghgfg";//回调URLpublic static String notifyurl="http://localhost:8004/order/wxCallback";
}

3、支付流程

4、工具介绍

4.1 SDK

https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=11_1

<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);

4.2 JFinal 框架

  • JFinal 是基于Java 语言的极速 web 开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展

  • 取代HttpClient

    <dependency><groupId>com.jfinal</groupId><artifactId>jfinal</artifactId><version>3.5</version>
    </dependency>

    5、构建二维码

  • Course.vue
    <script>
    //  生成二维码createCode () {this.axios.get("http://localhost:80/order/createCode", {params: {courseid: this.course.id,  // 课程编号courseid: this.course.courseName, // 课程名称price: this.course.discounts,  // 优惠价,非原价},}).then((result) => {console.log(result);let qrcode = new QRCode('qrcode',{width:200,height:200,text:result.data.code_url  // 将支付连接嵌入到二维码中});}).catch((error) => {this.$message.error("二维码生成失败!");});}
    </script>

    支付配置

    public class PayConfig {//企业公众号IDpublic static String appid="wx307113892f15a42e";//财付通平台的商户帐号public static String partner="1508236581";//财付通平台的商户密钥public static String partnerKey="HJd7sHGHd6djgdgFG5778GFfhghghgfg";//回调URLpublic static String notifyurl="http://localhost:8004/order/wxCallback";
    }

    createCodeController

    import com.alibaba.fastjson.JSON;
    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 PayAction {@GetMapping("createCode")public Object createCode(String courseid,String coursename, String price) throws Exception {//1.编写商户信息Map<String,String> mm = new HashMap();mm.put("appid",PayConfig.appid); //公众账号IDmm.put("mch_id",PayConfig.mchid);//商户号mm.put("nonce_str",WXPayUtil.generateNonceStr());//随机字符串mm.put("body",coursename); //商品名称String orderId = WXPayUtil.generateNonceStr();System.out.println("订单编号 = "+orderId);mm.put("out_trade_no",orderId); //商户订单号mm.put("total_fee",price+""); //订单金额,单位分mm.put("spbill_create_ip","127.0.0.1"); //终端IPmm.put("notify_url",PayConfig.notifyurl); //通知地址mm.put("trade_type","NATIVE"); //交易类型System.out.println("发送的map = "+mm.toString());//2.生成数字签名,并把上面的map转换成xml格式String xml = WXPayUtil.generateSignedXml(mm,PayConfig.partnerKey);System.out.println("转换后的xml = "+xml);//3.将数据发送给微信后台,并得到微信后台返回的数据String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";String result = HttpKit.post(url,xml);System.out.println("返回的xml = "+result); //如果报错:<![CDATA[签名错误]]> 商户四要素的原因,重置商户API密钥。//4.后台返回的xml格式,转成map,并添加两个参数Map<String,String> resultMap = WXPayUtil.xmlToMap(result);resultMap.put("orderId",orderId);resultMap.put("money",price+"");//5.将map返回给浏览器return resultMap;}@RequestMapping("wxCallback")public String wxCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {InputStream inStream = null;ByteArrayOutputStream outSteam = null;String resultxml = null;try {inStream = request.getInputStream();outSteam = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {outSteam.write(buffer, 0, len);}resultxml = new String(outSteam.toByteArray(), "utf-8");} catch (Exception e) {System.out.println("回调处理失败");}finally {if(null != outSteam) {outSteam.close();}if(null != inStream) {inStream.close();}}System.out.println("wxCallback - 回调请求参数:"+ resultxml);return resultxml;}
    }

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

    6、检查支付状态

    <!-- 微信支付二维码-->
    <el-dialog :visible.sync="dialogFormVisible" :before-close="cancelOrder" :modal="true" :close-on-click-modal="false" 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>
    data() {return {time:null // 定时器};
    },
    // 生成二维码
    createCode(){// 将上一次的二维码清除,防止出现多个二维码document.getElementById("qrcode").innerHTML = "";// 去获取支付连接this.axios.get("http://localhost:8004/order/createCode",{params:{courseid: this.course.id,coursename: this.course.courseName,price:1, //测试支付金额固定为1分钱,真实上线环境再改回此真实价钱:this.course.discounts}}).then((result) => {console.log(result);// QRCode(存放二维码的dom元素id,二维码的属性参数)let qrcode = new QRCode('qrcode',{width:200,height:200,text:result.data.code_url  // 将返回的数据嵌入到二维码中});this.orderNo = result.data.orderId;// 保存订单, 状态为:已创建 0this.saveOrder();// 检查支付状态this.axios.get("http://localhost:8004/order/checkOrderStatus",{params:{orderId: result.data.orderId // 传递 订单编号 进行查询}}).then((result) => {console.log(result.data.trade_state);if(result.data.trade_state=="SUCCESS"){document.getElementById("statusText").innerHTML = "<i style='color:#00B38A' class='el-icon-success'></i> 支付成功!";// 支付成功this.updateOrder(20);// 3秒后关闭二维码窗口let s = 3;this.closeQRForm(s);}/*else if(result.data.trade_state=="NOTPAY"){document.getElementById("statusText").innerHTML = "<i style='color:#00B38A' class='el-icon-success'></i> 未支付!";this.updateOrder(10);}*/}).catch( (error)=>{this.$message.error("查询订单失败!");});}).catch( (error)=>{this.$message.error("生成二维码失败!");console.log(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);this.$router.go(0);//刷新页面
    },
    // 保存订单
    saveOrder(){return this.axios.get("http://localhost:8003/order/saveOrder",{params:{orderNo:this.orderNo,user_id: this.user.content.id,course_id:this.course.id,activity_course_id:this.course.id,source_type:1,}}).then((result) => {// console.log(result);console.log("保存订单");}).catch( (error)=>{this.$message.error("保存订单失败!");});
    },
    // 更新订单的状态
    updateOrder(statusCode){return this.axios.get("http://localhost:8003/order/updateOrder",{params:{orderNo:this.orderNo,status:statusCode,}}).then((result) => {console.log("更新订单【"+this.orderNo+"】状态:" + statusCode);}).catch( (error)=>{this.$message.error("更新订单失败!");});
    },
    // 取消订单
    cancelOrder(){this.dialogFormVisible= false;return this.axios.get("http://localhost:8003/order/deleteOrder",{params:{orderno:this.orderNo,}}).then((result) => {// console.log(result);console.log("取消订单");}).catch( (error)=>{this.$message.error("取消订单失败!");});
    }
    </script>
    @GetMapping("createCode")
    public Object createCode(String courseid,String coursename,String price) throws Exception {// 省略...// 查询订单状态需要订单编号,所以将订单编号保存并返回给前端resultMap.put("out_trade_no",mm.get("out_trade_no"));return resultMap;
    }
    @GetMapping("checkOrderStatus")
    public Object checkOrderStatus(String orderId) throws Exception {//1.编写商户信息Map<String,String> mm = new HashMap();mm.put("appid",PayConfig.appid); //公众账号IDmm.put("mch_id",PayConfig.partner);//商户号mm.put("out_trade_no",orderId);//订单编号mm.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串System.out.println(mm);//2.生成数字签名,并把上面的map转换成xml格式String xml = WXPayUtil.generateSignedXml(mm, PayConfig.partnerKey);System.out.println(xml);//3.将数据发送给微信后台,并得到微信后台返回的数据String url = "https://api.mch.weixin.qq.com/pay/orderquery";//第一次询问时间long beginTime = System.currentTimeMillis();while(true) { //不停的去微信后台询问是否支付String result = HttpKit.post(url, xml);System.out.println(result);//报错:<![CDATA[签名错误]]>//4.后台返回的xml格式,转成map,并添加两个参数Map<String, String> resultMap = WXPayUtil.xmlToMap(result);//5.将map转成json并返回给浏览器//已经成功支付,停止询问if(resultMap.get("trade_state").equalsIgnoreCase("success")){return resultMap;}//超过30秒未支付,停止询问if(System.currentTimeMillis() - beginTime > 30000){return resultMap;}Thread.sleep(3000); //每隔3秒,询问一次微信后台}
    }

微信支付 SpringCloud+Vue相关推荐

  1. pc端支付宝支付和微信支付(vue)

    微信扫码支付 需要用到的插件 : qrcodejs2 先安装 cnpm i qrcodejs2 -S 然后引入:import QRCode from "qrcodejs2"; 配置 ...

  2. vue玩转移动端H5微信支付和支付宝支付

    业务场景介绍: H5移动端支持微信支付 [ 微信支付分为微信内支付(JSAPI支付官方API)和微信外支付(H5支付官方API)] && 支付宝支付 [手机网站支付转 APP 支付 官 ...

  3. vue 停车场车牌号键盘微信支付

    应公司要求现在需做某医院的停车厂微信公众号支付功能 前端框架 Vant https://youzan.github.io/vant/#/zh-CN/intro 预览demo:http://tangyu ...

  4. 移动网页唤起手机内 支付宝 微信支付

    本文链接:https://blog.csdn.net/qq_36710522/article/details/90483194 业务场景介绍: H5移动端支持微信支付 [ 微信支付分为微信内支付(JS ...

  5. Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)二十二(下单和微信支付)

    Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)二十(下单) 0.学习目标 会调用订单系统接口 实现订单结算功能 实现微信支付功能 1.订单 ...

  6. laravel ajax vue6,详解用vue.js和laravel实现微信支付

    注:此项是微信公众号开发,请在往下看之前,先实现网页微信授权登陆功能,具体参看我简书的另一篇文章:https://www.jb51.net/article/117004.htm 1.打开app/con ...

  7. 在vue中获取微信支付code及code被占用问题的解决?

    在vue中获取微信支付code及code被占用问题的解决? 参考文章: (1)在vue中获取微信支付code及code被占用问题的解决? (2)https://www.cnblogs.com/pana ...

  8. vue 微信公众号支付接口_基于vue的h5项目之支付宝支付与微信支付

    本文仅记录基于vue开发h5项目过程中使用支付宝和微信支付过程中的重点与槽点,仅为前端部分,如有疏漏不正之处,请于文末评论探讨.注意:标红部分灰常重要,仔细阅读官方文档非常重要,耐心非常重要,细心非常 ...

  9. vue前端实现微信支付-微信公众号JSSDK

    最近在做支付功能,微信支付准备工作之类的请参考官方说明,注意个人申请的测试号不支持,要申请企业号,还要商户号,开通支付权限,配置域名,JSSDK的权限问题,尽可能都开通吧! 官方地址可参考这里:接入准 ...

最新文章

  1. 深度学习-Tensorflow2.2-深度学习基础和tf.keras{1}-线性回归tf.keras概述-02
  2. 控制是否展示_非线性控制(四)描述函数法
  3. 编程语言也环保?C语言领跑,Python、Perl垫底
  4. vue样式中背景图片路径_vue打包css文件中背景图片的路径问题
  5. 草稿 断开式数据连接
  6. 第 3 章 MybatisPlus 注入 SQL 原理分析
  7. android 5.0论坛,Android 安卓5.0以下版本提权漏洞
  8. 命令行工具恢复文件 foremost 和 extundelete 简介
  9. 一个典型的高精度室内UWB定位系统是怎么炼成的?
  10. iOS永久不掉签名工具,TrollStore超详使用教程
  11. hdu4939思维DP
  12. Mybatis报错: Could not find resource mapper
  13. 教你1分钟学会贴iPhone钢化膜
  14. JavaScript文字转图片
  15. 如何处理Vegas素材中的杂音
  16. particles 粒子效果
  17. Macrorit Partition Expert v5.7.0 硬盘分区管理软件单文件中文版
  18. Selenium+python怎么搭建自动化测试框架、执行自动化测试用例、生成自动化测试报告、发送测试报告邮件
  19. 基于ESP-01S的USB电压电流表
  20. 数据仓库-BI商业智能

热门文章

  1. 一个看着有用,但是没多大用的IDEA插件MybatisCode
  2. oracle 的dba users表,oracle DBA 常用表和视图
  3. c语言程序设计第2章,c语言程序设计(包云)c第2章算法
  4. 用户控制 阻止运行程序_阻止或允许您的孩子通过家长控制使用的程序
  5. 智慧城市,离我们还有多远?
  6. 浏览器必备插件|2022版
  7. 卡巴斯基网络安全解决方案-服务器虚拟化安全2.0安装方法,营销材料(内部)_卡巴斯基网络安全解决方案-虚拟化安全(KSV2.0)_V1.0.docx...
  8. 如何成为用户真正需要的短信验证平台
  9. Tailwind 真香
  10. 更改zabbix数据库mandatory