uniApp H5微信网页授权,微信支付
用于记录 uniapp 编译成H5后,完成微信授权和微信支付,微信浏览器中主要看场景二
业务场景介绍
业务需要在H5中完成支付功能(微信支付)
使用场景介绍
1、H5运行在普通浏览器中;
2、H5运行在微信浏览器中。
分析过程
场景一:H5运行在普通浏览器中
H5普通浏览器支付过程并不复杂,大致流程如下:
a、前端发起支付请求给后端,后端收到后,调用微信支付接口下单;
b、微信支付接口会返回一个支付链接给到后端;
c、后端把微信返回的支付链接通过支付请求(a)接口返回给前端;
d、前端拿到链接之后,跳转到此链接,开启轮询调用后端接口查询是否支付成功;
e、在跳转之后的链接完成支付动作的操作,用户自己点击返回到发起支付的页面。
微信H5支付开发文档
// 页面卸载时清除计时器,停止轮询,用于页面计时器重复启用onUnload() {clearTimeout(this.payTime);}// 如下为methods:{}中代码的一部分
// 同意支付方法 agreePayFn(price) {let params = {};params.price = price; //价格params.id = this.estimateSchemeId; //支付的产品IDthis.getWxPayCb(); //获取支付是否成功的回调方法 ,用于轮询后端接口h5WxPay(params).then(res => { // 发起微信支付请求给后端,res是后端返回的支付链接params = null; //释放内存location.href = res; //跳转到支付链接});},// 获取微信支付结果getWxPayCb() {const self = this;let params = {};params.id = this.estimateSchemeId; //产品IDclearTimeout(this.payTime); //清除计时器function next() { //用于轮询的函数getWxPayReuslt(params) //获取微信支付结果接口.then(res => {if (res == true) { //后台返回 true 成功// doSomethingreturn;}if (res == false) { //后台返回 false 失败 // doSomethingshowToast('支付失败,请重新支付', 'none', 2000); //此方法是自己封装的uni.showToast方法return;}// 无结果时每隔一秒轮询接口self.payTime = setTimeout(() => {clearTimeout(self.payTime);next();}, 1000);}).catch(e => { //接口出现异常时处理self.payTime = setTimeout(() => {clearTimeout(self.payTime);next();}, 1000);});}next(); //进入就进行调用}
场景二:H5运行在微信浏览器【此文的重点】
H5支付是指商户在微信客户端外的移动端网页展示商品或服务
因此在微信浏览器支付时需要,使用另外一套支付过程----微信jsapi传送门
根据微信【JSAPI】支付开发的要求,则需要完成2步操作
1、有支付功能的页面,需要通过微信网页授权获取code,并把code传给后台获得当前用户的openid,openid将用于后台统一下单时使用;
2、发起支付(有两种方式,a、直接调用;b、通过jssdkapi调用)
问题难点,hash 模式下网页授权获取code
由于uniapp开发的H5采用的hash路由模式,在网页授权时,微信会扰乱带#号的参数,以至于回调时不能回到发起页面。
解决方案
1、需要授权的页面,在授权之前,把带#号的url转换成不带#号的url;
2、微信授权回来之后,在项目入口,把不带#号的url转换成带#号的url。
封装WX_JS_SDK 文件
// 引入qs解析包,用于将URL解析成对象
import qs from 'qs'
// 引入微信jsapi包
import wx from 'weixin-jsapi';
// 引入自己定义的微信配置和请求
import { weChatConfig, callSever } from '../api/requestConfig.js';
// 需要用到的微信api接口
const jsApiList = ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareTimeline','onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareQZone', 'onMenuShareWeibo', 'chooseWXPay'
];// 注入微信权限验证配置
let injectionWxConfig = function(params) {const { timestamp, nonceStr, signature } = paramswx.config({debug: false,appId: weChatConfig.appId, // 必填,公众号的唯一标识timestamp: parseInt(timestamp), // 必填,生成签名的时间戳 nonceStr: nonceStr, // 必填,生成签名的随机串signature: signature, // 必填,签名jsApiList: jsApiList // 必填,需要使用的JS接口列表})
}/*** 调起微信支付* params 支付参数timestamp: '', 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符nonceStr: '', 支付签名随机串,不长于 32 位package: '', 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)signType: '', 签名方式,默认为'SHA1',使用新版支付需传入'MD5'paySign: '', 支付签名signature: '' //签名 用于权限注入使用* successCallBack 成功回调* failCallBack 失败回调* cancelBack 取消回调*/
const wxPay = (params, successCallBack, failCallBack, cancelBack) => {injectionWxConfig(params)wx.ready(() => {wx.chooseWXPay({timestamp: params.timestamp,nonceStr: params.nonceStr,package: params.package,signType: params.signType,paySign: params.paySign,success: successCallBack,fail: failCallBack,cancel: cancelBack})})
}//-------------------------------------------------------------------------------------//
/*** 如下配置是为了在微信浏览器环境中,网页拿去授权* 由于采用的hash模式路由,会导致授权后的链接被扰乱(微信会处理掉#号) redirect_uri* 解决方案:* 1、授权前重置 redirect_uri 改为没有#号的url,把当前页面的原有参数信息,额外信息,codePath参数(用来指定跳转页面的,此处为授权发起页)* 2、项目入口处,将没有#号的url改回到 带#号的url,跳转到指定页面*//*** 微信授权-需要授权的页面: [页面用到的参数key] * 参数key适用于获取微信回调跳传回来时的参数(授权时传了此参数,如未传则不填,也不用写页面)*/
const plagForm = {'/pages/interestModule/interestLoan/interestLoan': ['']
}/*** 重置redirect_uri 需要用到的页面使用* 把有#号的url改为没有#号的url,* scope 授权作用域 snsapi_base(静默授权) snsapi_userinfo(弹框授权)* path 授权所在的页面路径*/
const getWxCode = function(scope = 'snsapi_base', path) {let homeUrl = '',searchObj = {},searchStr = '';let oriUrls = location.href.split('?');let baseShareUrl = location.origin + location.pathnamehomeUrl = baseShareUrl// 如果有携带参数,把参数进行拼接,参数不能带codeif (oriUrls.length > 1) {let searchUrls = oriUrls[1].split('#')let searchUrlReal = searchUrls[0]searchObj = qs.parse(searchUrlReal)let { code } = searchObjif (code) {delete searchObj.code}}// 路径存入到codePath中,用于微信回调时入口处处理searchObj.codePath = pathsearchStr = `?${qs.stringify(searchObj)}`homeUrl += searchStrlet redirect_uri = encodeURIComponent(homeUrl)let response_type = 'code'let state = ''let url =`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${weChatConfig.appId}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}#wechat_redirect`location.href = url
}/*** 重置redirect_uri 项目入口处使用* 将没有#号的url改回到 带#号的url* 如果地址有页面需要传递的参数,需要在 plagForm 进行设置* 返回之后的例子:* https://xxxx.com/?codePath=%2Fpages%2FinterestModule%2FinterestLoan%2FinterestLoan&code=021cZo0002D87L1BSH200bPoNK3cZo0Z&state=#/pages/indexTabBar/index*/
const urlResetForWxCode = function() {let needRedirect = false,homeUrl = '',searchObj = {},searchStr = '';let oriUrls = location.href.split('?');let baseShareUrl = location.origin + location.pathnamehomeUrl = baseShareUrlif (oriUrls.length > 1) {let searchUrls = oriUrls[1].split("#")let searchUrlReal = searchUrls[0]let searchObjReal = {}searchObj = qs.parse(searchUrlReal)let { codePath } = searchObjneedRedirect = codePathif (codePath) {plagForm[codePath].forEach(item => searchObjReal[item] = searchObj[item])if (plagForm[codePath].length) {searchStr = `?${qs.stringify(searchObjReal)}`}homeUrl += `#${codePath}` + (searchstr.length > 1 ? searchstr : '')}}return {needRedirect, //需要重定向homeUrl, //跳转链接search: searchObj //存着code信息和codePath信息等}
}
const WX_JS_SDK = {urlResetForWxCode,getWxCode,wxPay
}
export default WX_JS_SDK
在main.js中引用刚刚封装好的WX_JS_SDK文件
import WX_JS_SDK from './utils/WX_JS_SDK.js';
//添加到原型中
Vue.prototype.$wxSdk = WX_JS_SDK
第一步:需要授权的页面,把带#号的地址更换成不带#号的地址,用于获取微信code
onLoad(options) {// 如果是微信环境,且没有wxCode,则需要进行网页授权const wxCode = uni.getStorageSync('wxCode');console.log('是否浏览器环境','isWeChatH5--自定义的判断是否是浏览器环境')if (isWeChatH5) {if (isEmpty(wxCode)) {this.$wxSdk.getWxCode('snsapi_base', '/pages/interestModule/interestLoan/interestLoan');return;} else {// 通过code调取接口获取openID,用于 统一下单接口 预支付}}},
第二步:项目入口处APP.VUE,处理微信返回的地址,把不带#号的地址更换成带#号的地址,跳转到指定页面
import { getSystemInfo, isWeChatH5 } from '@/utils/index.js';
export default {onLaunch: function(options) {getSystemInfo();// 如果是在微信环境,有通过授权页面回来时if (isWeChatH5) {let { needRedirect, homeUrl, search } = this.$wxSdk.urlResetForWxCode();if (needRedirect) {uni.setStorageSync('wxCode', search.code); //本地存入codelocation.href = homeUrl; //跳转到发起授权的页面return}}//其它业务逻辑 。。。。。}
};
第三步,需要支付的页面调用 WX_JS_SDK 封装的方法
// 同意支付agreePayFn(price) {let params = {};params.price = price;params.id = this.estimateSchemeId;if (isWeChatH5) {//微信浏览器环境,调用微信api支付方法,如需直接支付可以看场景二的直接调用支付this.$wxSdk.wxPay(params,sucess => {// 成功回调console.log('成功回调了')},fail => {// 失败回调console.log('失败回调了')},cancel => {// 取消回调console.log('取消回调了')});} else {// 非微信浏览器环境 支付,可看场景一this.getWxPayCb();h5WxPay(params).then(res => {params = null;uni.removeStorageSync('from');location.href = res;});}},
uniApp H5微信网页授权,微信支付相关推荐
- 微信开发---微信网页授权、JS-SDK和微信公众号的基本设置
用了好几个小时的时间,整理了一下关于公众号的思维导图,由于CSDN不能上传相对应的文件,所以萍子一一的分解开的截图附上来,希望对大家有所帮助哦~ 因为是电脑设备自动截图,又鉴于内容比较多,可能不是太清 ...
- 使用微信开发者工具调试微信网页授权登录-react
转:https://www.jianshu.com/p/9ced1a297c95 1.使用localhost本地调试 使用微信开发者工具, 选择微信网页授权, 微信团队为广大的开发者提供了一个测试账号 ...
- uniapp微信H5公众号授权与支付
目录 前言 准备工作 配置回调域名 授权方式 参数 完整代码 前言 网页授权微信官方文档:网页授权 | 微信开放文档 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基 ...
- 微信H5端网页授权流程(在H5中的openid获取,网页绑定微信)
说明:微信网页授权有两种 1.单独获取openid,属于静默获取,用于绑定微信(scope为snsapi_base) 2.获取用户的基本信息,需要用户点击同意(scope为snsapi_userinf ...
- H5页面使用微信网页授权实现登录认证
在用H5开发微信公众号页面应用时,往往需要获取微信的用户信息,H5页面在微信属于访问第三方网页,因此通过微信网页授权机制,来获取用户基本信息,此处需要用户确认授权才能获取,用户确认授权后,我们可以认为 ...
- 微信公众号H5【微信网页授权快照页】复现情况,以及解决方法(详细,成功,forcePopup,forceSnapShot,is_snapshotuse)
(上班时间写的!!,大哥们看完记得点赞) 1.官方回答(稀碎) 快照页将会默认对用户屏蔽网页授权弹窗,用户在快照页中仅可进行滑动浏览操作,其他交互将被限制,并提示用户 "该网页需获取个人信息 ...
- 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP)
wechat github 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP) 概述 公众号开发是痛苦的,痛苦在好多问题开发者文档是没有提到的,是需要你猜的. 在开发过程中 ...
- uniapp/通用: 微信网页授权登录
说明一下我现在的具备的条件:开发阶段,没有外网地址,也没有域名 建议可以先安装一个微信开发者工具,方便调试,如果不安装也可以,直接用pc微信访问,下载地址 微信开发者工具 准备一个域名,如果没有申请好 ...
- android user-agent iso-8859-1,微信网页授权,错误40163,ios正确,安卓错误?
2018-07-18:一年时间过去了,我又回来填自己挖的坑了!! 2017年7月,我遇到了这个问题,当时在这里提了问,后来又跟踪了两天,也没彻底搞懂,反正时好时坏,,后来自己主要精力放在H5+开发上, ...
- 微信网页授权,获取微信code,获取access_tocken,获取用户信息
微信开发中,经常有这样的需求:获得用户头像.绑定微信号给用户发信息.. 那么实现这些的前提就是授权! 1.配置安全回调域名: 在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的" ...
最新文章
- 一个女生不主动联系你还有机会吗?
- javascript高级程序设计(第3版)之《script元素》
- 乐安全 支持x86_国产EDA又进一步!芯华章发布全新仿真技术:x86、ARM等架构通吃...
- 年轻人买菜只愿意走670米,每日优鲜、叮咚买菜等生鲜电商们依然“难送达”
- 实验二 初始化阶段-source.c
- mockito mock void方法_使用 Junit + Mockito 实践单元测试!
- Linux加密框架 crypto RC4
- linux虚拟机中安装java软件,在 Linux 中安装 JAVA 虚拟机
- Learning Modern 3D Graphics Programming笔记
- 一旦辞职,应该立即批准。留一段时间没有好处
- 计算机最新一区sci,人工智能容易发的SCI期刊_2019中科院jcr期刊分区_2019中科院最新分区...
- 根据两点坐标计算两点距离
- python爬虫:用scrapy框架爬取链家网房价信息并存入mongodb
- win10系统Windows 资源保护无法启动修复服务该如何解决?
- openCv 图像顺时针 逆时针旋转
- 初学者计算机电脑怎样学,初学者怎样学习电脑能够快速入门(免费科普电脑基础知识)...
- ANU COMP1100 Lab1简介
- 鸿蒙系统的理解,我所理解的鸿蒙系统
- 手机端(APP点灯blinker)-PC端(Node-red)-设备端(ESP32)-客户端(MQTTX客户端)四者之间的通信——通过MQTT通信(上)
- shell遍历多个数组