
转载声明:文章来源:https://blog.csdn.net/weixin_46699908/article/details/110843314
项目中常见的支付方式
1.支付宝支付
2.微信支付
支付宝支付
项目难点:
页面是h5网页,用支付宝支付必须得到支付宝授权,调用支付宝的api
支付宝支付的一般过程是:
1.调用订单接口,获得订单号,支付金额等。
2.传递订单号,金额 至预支付接口
3.后台会返回来一个form,然后提交form自动跳转到支付宝支付页面
支付过程:
当我们选中支付宝,radio=1;
当我们点击支付按钮,pay()方法执行
此时我们调用后端支付接口,传入接口文档要求字段,订单号,金额等。
后台回传给我们一个{code:201,data:""};
此时我们把form注入到我们页面中,让form表单提交,跳转到支付宝页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | topay(){ switch ( this .radio){ case '3' : this .yuer(); break ; case '1' : this .zhifubao(); case '0' : this .getWechatCode(); } }, zhifubao(){ payByZhifubao( { OutTradeNo: 'Oct20200909095646265303127' , //商户订单号,商户网站订单系统中唯一订单号,必填 。需要保证商户端唯一。 Subject: "手机网站支付测试" , //主题 ProductCode: "QUICK_WAP_WAY" , body: "手机网站支付描述信息" , //商品描述,可空 TotalAmount: 20 //付款金额,必填 } ).then(res=>{ console.log(res); if (res.code === 201) { //将数据存到vuex中 // this.$store.dispatch('addAliFrom', res.data.data) this .html = res.data; var form = res.data; const div = document.createElement( "div" ); div.innerHTML = form; //此处form就是后台返回接收到的数据 document.body.appendChild(div); document.forms[0].submit(); //return this.$router.push('/aliPay') } else { return alert(res.data.msg); } }) }, ``` ### 微信支付 步骤: 1. 微信支付后台程序员会给你返一个地址,首先我们需要安装qrcodejs2将地址转换成二维码,需要先npm install qrcodejs2 2. 然后需要一个div来存放这个微信二维码,宽高样式各位自己可以去css里写,我在这里还加了一个loading,有需要的也可以自己加 ```html <div id= "wechatcode" v-loading= "loading" <br= "" >element-loading-text= "拼命加载中" element-loading-spinner= "el-icon-loading" element-loading-background= "rgba(0, 0, 0, 0.8)" > </div> |
导入模块
1 | import QRCode from 'qrcodejs2' // 引入qrcode |
下面是接口数据获取然后操作二维码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | getWechatCode() { Models .getModel( "wechatpay" ) .get({ orderId: this .orderId }) .then(res => { if (res.data.code == 200){ this .wechatPayUrl = res.data.resultData if (! this .flag){ //重点是这里,其余的是为了我的切换业务逻辑和接口 let wechatcode = new QRCode( 'wechatcode' , { width: 200, height: 200, text: this .wechatPayUrl, // 二维码地址 colorDark: "#000" , colorLight: "#fff" , }) } this .flag = true this .loading = false this .isWechatCodeShow = true } }) }, ``` 在微信扫描支付完之后,后台人员可以拿到支付成功结果,返给前台人员,那么前端人员只能不断去调接口查询是否已支付,在这里我们可以用生命周期来做轮询,在跳出之后需要销毁 ```js mounted() { this .getWechatCode() //实现轮询 this .interval = window.setInterval(() => { setTimeout( this .getOrderStatus(), 0); }, 3000); }, beforeDestroy() { //清除轮询 clearInterval( this .interval) this .interval = null }, |
这里的`getOrderStatus()方法是为了查询后台支付状态的,如果成功跳转到支付页面,做个If else判断即可
微信支付
1.在订单组件中选择支付方式之后在支付页面先去判断是否是在微信内:
1 2 3 4 5 6 7 8 9 | //判断是否微信 is_weixn(){ var ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) == 'micromessenger' ){ return true ; } else { return false ; } }, |
2.触发立即支付方法,根据微信内外的不同请求后端不同的接口,如果是微信外支付非常简单了~
3.【微信外支付】下面先看微信外支付,官方文档也写的很清楚,后端返回一个url地址,前端的工作就是拿到这个url地址进行跳转就可以了,看一下2-3步代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | handelPay() { if ( this .wechatpayType == 'wxpay' ){ // console.log("微信内支付") let data={ amount: this .number, } this .$http.insideWeChatPay(data).then( res => { if (res.data.code === 200){ this .weChatParameter=res.data.data // console.log(this.weChatParameter,"微信内支付需要参数") this .weixinPay() } else { Toast({ message: res.data.msg, position: 'middle' , duration: 1000 }); } }); } else if ( this .wechatpayType == 'wxpay_php' ){ // console.log("微信外支付") let data={ amount: this .number, } this .$http.outsideWeChatPay(data).then( res => { if (res.data.code === 200){ let url=res.data.data window.location.replace(url) //这里是后端返回的URL直接进行跳转即可完成微信外支付 } else { Toast({ message: res.data.msg, position: 'middle' , duration: 1000 }); } }); } }, |
4.在调起支付的页面监听从其他页面返回的事件,进行一些刷新业务逻辑的实现即可,至此微信外支付已经完成。
1 2 3 | document.addEventListener( "visibilitychange" , function () { //需要的操作 }); |
5.【微信内支付】微信内支付比起微信外支付稍微复杂一点,但是也不难,(3步骤代码里面已经请求支付方式接口拿到了微信内支付所需要的参数)根据官方API
微信内置js对象 WeixinJSBridge,进行开发,至此微信浏览器内支付已经完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | //解决微信内置对象报错 weixinPay(data){ var vm= this ; if ( typeof WeixinJSBridge == "undefined" ){ if ( document.addEventListener ){ document.addEventListener( 'WeixinJSBridgeReady' , vm.onBridgeReady(data), false ); } else if (document.attachEvent){ document.attachEvent( 'WeixinJSBridgeReady' , vm.onBridgeReady(data)); document.attachEvent( 'onWeixinJSBridgeReady' ,vm.onBridgeReady(data)); } } else { vm.onBridgeReady(); } }, //微信内置浏览器类,weChatParameter对象中的参数是3.步骤代码中从后端获取的数据 onBridgeReady(){ var vm = this ; var timestamp=Math.round(vm.weChatParameter.timeStamp).toString(); WeixinJSBridge.invoke( 'getBrandWCPayRequest' ,{ debug: true , "appId" :vm.weChatParameter.appId, //公众号名称,由商户传入 "timeStamp" :timestamp, //时间戳,自1970年以来的秒数 "nonceStr" :vm.weChatParameter.nonceStr, //随机串 "package" :vm.weChatParameter.package, "signType" :vm.weChatParameter.signType, //微信签名方式: "paySign" :vm.weChatParameter.paySign, //微信签名 jsApiList: [ 'chooseWXPay' ] }, function (res){ // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 if (res.err_msg == "get_brand_wcpay_request:ok" ){ Toast({ message: '支付成功' , position: 'middle' , duration: 3000 }); vm.number= null vm.$router.go(-1) //window.location.href = vm.BASE_URL + 'index.html#/depositResult' } else { Toast({ message: '支付失败' , position: 'middle' , duration: 3000 }); } } ); }, |
6.微信内部浏览器支付也可以封装一下,在全局都可以直接调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | //微信浏览器支付 function wxpay(params,callback){ if ( typeof WeixinJSBridge == "undefined" ){ if ( document.addEventListener ){ document.addEventListener( 'WeixinJSBridgeReady' , onBridgeReady(params,callback), false ); } else if (document.attachEvent){ document.attachEvent( 'WeixinJSBridgeReady' , onBridgeReady(params,callback)); document.attachEvent( 'onWeixinJSBridgeReady' , onBridgeReady(params,callback)); } } else { onBridgeReady(params,callback); } } function onBridgeReady(params,callback){ var that = this WeixinJSBridge.invoke( 'getBrandWCPayRequest' , { "appId" :params.appId, "timeStamp" :params.timeStamp, "nonceStr" :params.nonceStr, "package" :params.package, "signType" :params.signType, "paySign" :params.paySign }, function (res){ callback(res) } ); } |
7.组件中调用微信支付:
1 2 3 4 5 | this .commonUtils.wxpay(res.data.data, function (payResult){ if (payResult.err_msg == "get_brand_wcpay_request:ok" ){ //执行 } }) |