微信内置H5支付
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
场景是用户通过微信扫app内的收款码,跳到一个h5页面。然后完成支付。
代码实现的整体流程:
使用微信扫码,码是app内生成的,码的内容是一个h5页面链接,扫码完成后跳转到自定义的h5支付界面。
扫码进入后,将页面展示所需要的参数进行缓存起来,存到本地。 然后需要微信静默授权。
- 微信静默授权的流程: 配置appid、redirect_uri等参数,从项目页面跳转到微信授权页面:
https://open.weixin.qq.com/connect/oauth2/authorize
详细参考[ 微信官方文档]open.weixin.qq.com/connect/oau…
参数说明
1 2 3 4 5 6 7 8 | // 示例 let ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) == 'micromessenger' ) { // 回调地址:域名加页面路径 let hdurl = encodeURIComponent( 'https://.../#/page_wallet' ); let appId = '申请项目的appid' ; window.location.href = `https: //open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${hdurl}&response_type=code&scope=snsapi_base#wechat_redirect`; } |
- 当授权后,会自动跳转到配置回调页面,也就是配置的‘redirect_uri’ 相当携带这code,重新打开了项目
- 然后解析url中的code,将code取出,支付的时候将code传给后端。
点击支付的时候,请求接口,使用微信浏览器内置对象WeixinJSBridge
调起微信支付,使用方法如下所示,data就是由后端返回的数据。
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 | function onBridgeReady(data) { WeixinJSBridge.invoke( "getBrandWCPayRequest" , { // 公众号名称,由商户传入 appId: data.appId, // 时间戳,自1970年以来的秒数 timeStamp: data.timeStamp, // 随机串 nonceStr: data.nonceStr, package: data.package, // 微信签名方式: signType: "MD5" , // 微信签名 paySign: data.paySign, }, function (res) { if (res.err_msg == "get_brand_wcpay_request:ok" ) { // 使用以上方式判断前端返回,微信团队郑重提示: // res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } } ) } if ( typeof WeixinJSBridge == "undefined" ) { if (document.addEventListener) { document.addEventListener( "WeixinJSBridgeReady" , onBridgeReady, false ); } else if (document.attachEvent) { document.attachEvent( "WeixinJSBridgeReady" , onBridgeReady); document.attachEvent( "onWeixinJSBridgeReady" , onBridgeReady); } } else { onBridgeReady(); } |
在使用uniapp开发中使用的代码如下:
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | <template> <view v-show= "show" > ...内容省略 <view @click= "confirmPay" >付款</view> </view> </template> <script> // 支付接口 import { payment_code } from '@/api/wallet' ; export default { data() { return { show: true , // 控制页面展示 user: {}, // 页面信息 form: { price: '' , type: 0, code: null , receiver_id: null }, // 提交参数 paydata: {} //返回的支付信息 }; }, onLoad(e) { // 扫码后第一次进入该页面时 if (e.id) { this .user = { name: e.name, id: e.id, }; this .form.receiver_id = e.id; // 将信息存到本地 uni.setStorageSync( 'userpay' , this .user); } else { // 第二次进入(授权成功后,通过回调进入的页面) let data = uni.getStorageSync( 'userpay' ); this .user = { name: data.name, id: data.id, }; this .form.price = data.price; this .form.receiver_id = data.id; let ua = window.navigator.userAgent.toLowerCase(); //判断是不是微信 if (ua.match(/MicroMessenger/i) == 'micromessenger' ) { // 第二次进来时,路径上已经携带了code,获取code。 this .form.code = this .getUrlParam( 'code' ); } } // 去授权 this .goAuthorization() }, methods:{ // 授权方法 goAuthorization(){ let ua = window.navigator.userAgent.toLowerCase(); // //判断是不是微信 if (ua.match(/MicroMessenger/i) == 'micromessenger' ) { // 判断是否已经获取了code if ( this .form.code == null || this .form.code === '' ) { // 如果还没有code,就跳转授权页面 let hdurl = encodeURIComponent( 'https://.../#/page_wallet' ); let appId = '申请项目的appid' ; window.location.href = `https: //open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${hdurl}&response_type=code&scope=snsapi_base#wechat_redirect`; } else { // 有code的话,就将页面内容显示出来 this .show = true ; } } } }, // 点击支付后,调用 confirm(e) { uni.showLoading({}); uni.$u.http.post( '支付接口' , this .form).then(res=>{ uni.hideLoading(); // 将返回的data赋值 this .paydata = res.data.data; let that = this ; // 绑定事件 if ( typeof WeixinJSBridge == 'undefined' ) { if (document.addEventListener) { document.addEventListener( 'WeixinJSBridgeReady' , that.wxonBridgeReady, false ); } else if (document.attachEvent) { document.attachEvent( 'WeixinJSBridgeReady' , that.wxonBridgeReady); document.attachEvent( 'onWeixinJSBridgeReady' , that.wxonBridgeReady); } } else { this .wxonBridgeReady(); } }). catch ((err) => { // 如果接口调用失败了,将信息存起来,再走一遍授权。 this .user.price = this .form.price; uni.setStorageSync( 'userpay' , this .user); this .form.code = null ; this .goAuthorization(); }); }, // 微信支付 wxonBridgeReady(){ let that = this ; WeixinJSBridge.invoke( 'getBrandWCPayRequest' , { appId: that.paydata.appId, timeStamp: that.paydata.timeStamp, nonceStr: that.paydata.nonceStr, package: that.paydata.package, signType: that.paydata.signType, paySign: that.paydata.paySign }, function (res) { // 如果取消了支付,就关闭当前h5页面,直接返回微信,也可以进行其他操作,通过res.err_msg来判断即可 if (res.err_msg == 'get_brand_wcpay_request:cancel' ) { //关闭当前浏览器 WeixinJSBridge.call( 'closeWindow' ); } // 这里是支付成功 if (res.err_msg == 'get_brand_wcpay_request:ok' ) { // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } } ) }, // 获取路径上参数的方法,用于获取code getUrlParam(name) { const url = window.location.href; const queryString = url.split( '?' )[1]; if (!queryString) return null ; const params = queryString.split( '&' ); for ( const param of params ) { const [key, value] = param.split( '=' ); if (key === name) { return decodeURIComponent(value); } } return null ; }, } </script> |
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
2023-06-29 记录--写一个高德地图巡航功能的小DEMO
2022-06-29 记录--Vue常问问题整合