用于记录 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微信网页授权,微信支付相关推荐

  1. 微信开发---微信网页授权、JS-SDK和微信公众号的基本设置

    用了好几个小时的时间,整理了一下关于公众号的思维导图,由于CSDN不能上传相对应的文件,所以萍子一一的分解开的截图附上来,希望对大家有所帮助哦~ 因为是电脑设备自动截图,又鉴于内容比较多,可能不是太清 ...

  2. 使用微信开发者工具调试微信网页授权登录-react

    转:https://www.jianshu.com/p/9ced1a297c95 1.使用localhost本地调试 使用微信开发者工具, 选择微信网页授权, 微信团队为广大的开发者提供了一个测试账号 ...

  3. uniapp微信H5公众号授权与支付

    目录 前言 准备工作 配置回调域名 授权方式 参数 完整代码 前言 网页授权微信官方文档:网页授权 | 微信开放文档 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基 ...

  4. 微信H5端网页授权流程(在H5中的openid获取,网页绑定微信)

    说明:微信网页授权有两种 1.单独获取openid,属于静默获取,用于绑定微信(scope为snsapi_base) 2.获取用户的基本信息,需要用户点击同意(scope为snsapi_userinf ...

  5. H5页面使用微信网页授权实现登录认证

    在用H5开发微信公众号页面应用时,往往需要获取微信的用户信息,H5页面在微信属于访问第三方网页,因此通过微信网页授权机制,来获取用户基本信息,此处需要用户确认授权才能获取,用户确认授权后,我们可以认为 ...

  6. 微信公众号H5【微信网页授权快照页】复现情况,以及解决方法(详细,成功,forcePopup,forceSnapShot,is_snapshotuse)

    (上班时间写的!!,大哥们看完记得点赞) 1.官方回答(稀碎) 快照页将会默认对用户屏蔽网页授权弹窗,用户在快照页中仅可进行滑动浏览操作,其他交互将被限制,并提示用户 "该网页需获取个人信息 ...

  7. 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP)

    wechat github 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP) 概述 公众号开发是痛苦的,痛苦在好多问题开发者文档是没有提到的,是需要你猜的. 在开发过程中 ...

  8. uniapp/通用: 微信网页授权登录

    说明一下我现在的具备的条件:开发阶段,没有外网地址,也没有域名 建议可以先安装一个微信开发者工具,方便调试,如果不安装也可以,直接用pc微信访问,下载地址 微信开发者工具 准备一个域名,如果没有申请好 ...

  9. android user-agent iso-8859-1,微信网页授权,错误40163,ios正确,安卓错误?

    2018-07-18:一年时间过去了,我又回来填自己挖的坑了!! 2017年7月,我遇到了这个问题,当时在这里提了问,后来又跟踪了两天,也没彻底搞懂,反正时好时坏,,后来自己主要精力放在H5+开发上, ...

  10. 微信网页授权,获取微信code,获取access_tocken,获取用户信息

    微信开发中,经常有这样的需求:获得用户头像.绑定微信号给用户发信息.. 那么实现这些的前提就是授权! 1.配置安全回调域名: 在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的" ...

最新文章

  1. 一个女生不主动联系你还有机会吗?
  2. javascript高级程序设计(第3版)之《script元素》
  3. 乐安全 支持x86_国产EDA又进一步!芯华章发布全新仿真技术:x86、ARM等架构通吃...
  4. 年轻人买菜只愿意走670米,每日优鲜、叮咚买菜等生鲜电商们依然“难送达”
  5. 实验二 初始化阶段-source.c
  6. mockito mock void方法_使用 Junit + Mockito 实践单元测试!
  7. Linux加密框架 crypto RC4
  8. linux虚拟机中安装java软件,在 Linux 中安装 JAVA 虚拟机
  9. Learning Modern 3D Graphics Programming笔记
  10. 一旦辞职,应该立即批准。留一段时间没有好处
  11. 计算机最新一区sci,人工智能容易发的SCI期刊_2019中科院jcr期刊分区_2019中科院最新分区...
  12. 根据两点坐标计算两点距离
  13. python爬虫:用scrapy框架爬取链家网房价信息并存入mongodb
  14. win10系统Windows 资源保护无法启动修复服务该如何解决?
  15. openCv 图像顺时针 逆时针旋转
  16. 初学者计算机电脑怎样学,初学者怎样学习电脑能够快速入门(免费科普电脑基础知识)...
  17. ANU COMP1100 Lab1简介
  18. 鸿蒙系统的理解,我所理解的鸿蒙系统
  19. 手机端(APP点灯blinker)-PC端(Node-red)-设备端(ESP32)-客户端(MQTTX客户端)四者之间的通信——通过MQTT通信(上)
  20. shell遍历多个数组

热门文章

  1. 阿里拍卖全链路导购策略首次揭秘
  2. 深入浅出了解OCR识别票据原理
  3. 新一代数据仓库:Snowflake 弹性数仓介绍
  4. 12306系统升级对电力营销系统改造的启示
  5. 素数筛【埃筛,欧拉筛(线性筛)】
  6. 华为社招16级待遇2020_2020年3月16日乌鲁木齐沙依巴克区发生3.5级地震简报
  7. linux清除回收站权限错误,在Ubuntu 14.04 中修复无法清空回收站的问题
  8. WDF 驱动程序echo安装
  9. win10桌面排序计算机,Windows10正式版下设置桌面自动排列图标的详细步骤
  10. 进程间通信方式有哪些?各自有哪些优缺点?