🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
场景是用户通过微信扫app内的收款码,跳到一个h5页面。然后完成支付。
代码实现的整体流程:
使用微信扫码,码是app内生成的,码的内容是一个h5页面链接,扫码完成后跳转到自定义的h5支付界面。
扫码进入后,将页面展示所需要的参数进行缓存起来,存到本地。 然后需要微信静默授权。
- 微信静默授权的流程:
配置appid、redirect_uri等参数,从项目页面跳转到微信授权页面:https://open.weixin.qq.com/connect/oauth2/authorize
详细参考[ 微信官方文档]open.weixin.qq.com/connect/oau…
参数说明
// 示例
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就是由后端返回的数据。
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开发中使用的代码如下:
<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') {// 判断是否已经获取了codeif (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,但并不保证它绝对可靠。}})},// 获取路径上参数的方法,用于获取codegetUrlParam(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>
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。