H5呼起微信支付(个人实践总结)

news2024/11/18 21:29:46

H5呼起微信支付存在两种场景

第一种:其他浏览器呼起微信支付。

第二种:微信内部呼起微信支付。

项目说明:

我这边的项目要求的两种方式均要适用。 产品要求是当支付失败时或者未支付情况是停留在支付订单页面,可再次发起订单请求(新订单),故我在这项目中,把支付成功页面和订单页面在同一页(根据订单状态去展示)。

前期准备:

公众号设置:

内部呼起微信搭桥,需要配置一个网页授权域名,用于前端内部呼起微信生成对应的code给到后端。

image.png 需要注意的是,填入域名即可,不用在域名前加【http://】,不然会提示【域名或路径格式不正确,请参考注意事项】。别问我怎么知道的,因为我删掉了我写的前面【http://】就配置通过了。

后端涉及到支付,要配置支付授权。

公众平台配置位置:微信支付-开发设置-支付授权目录

image.png

前端代码

判断浏览器情况

初始化时判断浏览器内核,并针对不同情况做不同的事情。

init(){
    this.wechatFlag = this.isWeChat();//本人项目提交时需要判断区分,所以就定义了全局
    if(this.wechatFlag){
        //当前在微信内部 do someThing
        // 比方判断是否有授权code
          let code = this.getQueryObject().code;
          if (code == null || code == '') {
            this.redirectPage();//重定向获取code
          } else {
            this.code = code;
          }
    }else{
        //外部浏览器 do someThing
        //项目里,我设置的支付订单页和成功页在同一个页面
        //所以外部浏览器付费与否都回到这个页面
        //所以我这要获取成功后的订单参数
        if (this.$route.query.orderNumber) {//外部浏览器跳转重定向
            //从微信里重定向回来
            this.orderId = this.$route.query.orderNumber;//订单参数
            //this.getMyOrder();//请求订单数据
          }
    }
} 

判断是否在微信内部浏览器(浏览器内核)isWeChat()

isWeChat(){
      //判断是否为微信内部登录
      var ua = window.navigator.userAgent.toLowerCase();
      //console.log(ua);
      if (ua.match(/MicroMessenger/i) == 'micromessenger') {
        return true;//是微信内部
      } else {
        return false;
      }
    }
} 

外部浏览器成功回调后url传参获取getQueryObject()【公用函数】

getQueryObject(url){可当成一个公用方法
  url = url == null ? window.location.href : url;
  let search = url.substring(url.lastIndexOf("?") + 1);
  let obj = {};
  let reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, function (rs, $1, $2) {
    let name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
} 

第一种:其他浏览器呼起微信支付。

思路:其他浏览器呼起微信支付,更多的是依靠后台接口返回数据。

请求微信支付的接口 --> 接口返回一个链接 --> 跳转连接

 async submitOrder(){
  this.isDisabledSubmitBtn = true //防止用户点击多次
    let params= {};//项目支付相关的参数
    try {
          let {
            retBody,
            retMsg
          } = await requestPay (params)//请求接口
          if (retStatus === 'success') {//成功判断依据
            if (retBody) {//直接跳转链接
              window.location.href = retBody;
            }
          } else {
            this.$notify(retMsg || '提交订单失败')
            this.isDisabledSubmitBtn = false //防止用户点击多次
          }
        } catch (error) {
          this.error = true
          this.$notify('提交订单失败' || error)
          this.isDisabledSubmitBtn = false //防止用户点击多次
    }
  }

}

跳转回来之后就在会重新create了,获取与后台约定参数重新查询订单数据即可。 

第二种:微信内部浏览器

需要前端搭桥呼起浏览器内置方法

重定向获取用户code

redirectPage(){
  //微信内部则重定向页面 
  let local = window.location.href;//当前地址
  let appId = 'thisistheappid';//填写公众号APPID
  window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURIComponent(local)}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`  //跳转授权链接
}, 

提交函数

submitOrderInside(){
    let params = {
    code:this.code,
    };//微信内部添加的订单,后台需要我传多一个用户code
    //因为code有时效性,所以失效了或者使用过之后需要重新获取个新的code
    try {
          let {
            retStatus,
            retBody,
            retMsg
          } = await requestPayInside(params)//支付接口
          if (retStatus === 'success') {
            this.orderId = retBody.orderNumber;
            this.weChatParameter = {//微信搭桥需要的数据
              appid: retBody.appid,
              timeStamp: retBody.timeStamp,
              nonceStr: retBody.nonceStr,
              packageValue: retBody.packageValue,
              signType: retBody.signType,
              paySign: retBody.paySign,
            };
            this.wechatPay();//微信内置对象判断
          } else {
            this.$notify(retMsg || '提交订单失败')
            this.isDisabledSubmitBtn = false //防止用户点击多次
            this.redirectPage();//重定向获取新的code
          }
        } catch (error) {
          this.error = true
          this.$notify('提交订单失败' || error)
          this.isDisabledSubmitBtn = false //防止用户点击多次
           this.redirectPage();//重定向获取新的code
        }

    } 

wechatPay()解决微信内置对象报错

//搭桥前先解决微信内置对象报错
weixinPay (params) {
      var that = this;
      if (typeof WeixinJSBridge == "undefined") {
        if (document.addEventListener) {
          document.addEventListener('WeixinJSBridgeReady', that.onBridgeReady(params), false);
        } else if (document.attachEvent) {
          document.attachEvent('WeixinJSBridgeReady', that.onBridgeReady(params));
          document.attachEvent('onWeixinJSBridgeReady', that.onBridgeReady(params));
        }
      } else {
        that.onBridgeReady();
      }
    }, 

搭桥onBridgeReady()

 //微信内置浏览器类
onBridgeReady () {
  var that = this;
  var timestamp = Math.round(that.weChatParameter.timeStamp).toString();
  window.WeixinJSBridge.invoke(
    'getBrandWCPayRequest', {
    debug: false,
    "appId": that.weChatParameter.appid,     //公众号名称,由商户传入
    "timeStamp": timestamp, //时间戳,自1970年以来的秒数
    "nonceStr": that.weChatParameter.nonceStr, //随机串
    "package": that.weChatParameter.packageValue,
    "signType": that.weChatParameter.signType, //微信签名方式:
    "paySign": that.weChatParameter.paySign, //微信签名
    jsApiList: [
      'chooseWXPay'
    ]
  },
    function (res) {
      // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      if (res.err_msg == "get_brand_wcpay_request:ok") { //支付成功后的操作
        that.isDisabledSubmitBtn = true;
        //支付成功
        that.getMyOrder();//请求成功后重新请求订单数据
      } else if (res.err_msg == 'get_brand_wcpay_request:cancel') { //取消支付的操作
        that.isDisabledSubmitBtn = false //按钮恢复高亮
        that.redirectPage();//重定向获取新的code
        //取消支付
      } else {
        //支付失败
        that.isDisabledSubmitBtn = false //按钮恢复高亮
        that.redirectPage();//重定向获取新的code

      }
    }
  );
} 

以上就是个人微信支付的思路以及部分代码。仅供参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/409395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3下使用Vuex(store)实现响应式全局变量

Vue3下使用Vuex store1 安装2 编写vuex配置文件2.1 目录及文件结构2.2 index.js文件2.3 编写vuex模块级参数文件2.4 index.js中引入模块级参数3 引入4 使用5 持久化5.1 vuex值存储在sessionStorge中5.1 vuex值存储在localStorge中注意本文记录了如何使用vuex建立响应式全局变量…

Java后端Date类型返回给前端变为时间戳解决方法

今天在制作个人博客的分页功能时候,发现了这个问题 后端查询数据正确,2022-11-12 数据库MySQL5.7 用的date类型 因为写文章一般yyyy-MM-dd 类型就够用了 如果你需要yyyy-MM-dd HH-mm-SS 这种带时分秒的用datetime类型 数据存的也是2022-11-12 格式正确…

【JSP入门】只知道HTML却不知道JSP?

前言 今天我们继续来总结学习JSP相关知识,上一篇我们学习了Servlet的基础入门,如果你还对Servlet那么建议你先去看一下上篇博客再回来。 传送门:【Servlet入门】一篇文章让你从没听过到了熟于心 在之前我们已经学习了HTML,CSS&…

html静态登录、注册页面

登录 代码如下 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <style> body { background: url(https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.j…

windows7安装node14版本及以上

前言&#xff1a; gitee上拉了一个项目&#xff0c;npm install一直报错。一直没有解决&#xff0c;就去gitee上看前端启动教程。作者说要运行在node14或者16上。我就去官网下载node14的msi。这个是不支持windows7的。我就百度&#xff0c;他们说要下载压缩包。 我之前走了好…

sourcemap文件泄露漏洞

最近进行渗透测试时&#xff0c;时常遇到xray扫出sourcemap文件&#xff0c;每次扫到都要百度&#xff0c;因此做个笔记。 漏洞原理 在日常测试时&#xff0c;经常会遇到以js.map为后缀的文件 这是jQuery中的一个新功能&#xff0c;支持Source Map 非常多Webpack打包的站点都…

Vue3: vue3 props接多个不同类型的参数,默认false

哪天的问题来着...嘶...(挠头)... 之所以会卡在这里&#xff0c;是因为在我的经验及认知里&#xff0c;封装组件中props的使用&#xff0c;接参时从来都是一个参数对应一个值&#xff0c;尤其是在ts中&#xff0c;还更为严格地设定了参数类型&#xff0c;所以我的业务需求不知道…

保姆级教程!如何在安卓手机上安装使用油猴脚本

浏览器插件成千上万&#xff0c;但是大家都有一个共识&#xff0c;那就是油猴无插件能敌&#xff0c;原因就在于它一个插件就可以实现众多插件的功能。 首先需要明确一点的是&#xff0c;油猴插件本身是没有任何功能的&#xff0c;它需要依靠脚本来实现功能。至于脚本&#xf…

红队web打点信息收集

目录 红蓝对抗 ICP备案查询—查询主域 主站域名一键查询 敏感信息收集 googlehack语法 目标邮箱号收集 子域名收集 被动信息收集 证书透明 fofa_viewer 在线子域名查询 第三方DNS服务 google语法 主动信息收集 oneforall Sylas—从burp历史记录中提取子域 Lay…

【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件

目录 前言 初识express 使用express创建基本的web服务器 初识express路由 路由匹配概念 路由模块化 中间件 中间件和路由的区别 定义中间件函数 中间件作用 局部生效中间价 中间件分类 1.应用级别中间件 2.路由级别的中间件 3.错误级别中间件 4.内置中间件 5.自定义…

带你深入理解js事件循环机制

同步任务和异步任务&#xff08;微任务和宏任务&#xff09; JavaScript是一门单线程语言 分为同步任务和异步任务 同步任务是指在主线程上排队执行的任务&#xff0c;只有前一个任务执行完毕&#xff0c;才能继续执行下一个任务。 异步任务指的是&#xff0c;不进入主线程…

Pro1:图片的隐藏和显示

什么是JavaScript&#xff1f;实现目标实现代码实现效果实现方法&#x1f49b;作者主页&#xff1a;静Yu &#x1f9e1;简介&#xff1a;CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家&#xff0c;前端知识交流社区创建者 &#x1f49b;社区地址&#xff1a;前端知识交…

axios 中如何取消请求_从不会使用到精通原理_番茄出品

start 最近频繁遇到一个问题&#xff0c;axios 是如何取消请求的&#xff1f;这篇文章将从新手小白的视角出发&#xff0c;从 axios 取消逻辑的基础使用&#xff0c;到原理分析&#xff0c;带你彻底了解并掌握 axios 中取消请求的“秘密”。编写时间&#xff1a;2023/02/24-23…

520到了,教你做个JavaWeb表白墙小项目

目录 1.配置 Maven 项目 1.1 创建 Maven 项目 1.2 引入相关依赖 1.3 项目总结构 2. 约定前后端交互接口 3.服务端代码 3.1 创建Message类 3.2 创建工具类 3.3 添加信息类&#xff08;AddMessage&#xff09; 3.4 查询信息类&#xff08;MessageList&#xff09; 4. …

vue3中的配置代理

如图&#xff0c;配置代理就是在客户端与服务器中充当中介的角色 目录 关于配置代理&#xff0c;首先我们的要知道为什么要配置代理&#xff0c;配置代理做了什么事情 一、跨域是什么 二、如何解决 三、配置代理案例 1. 下面是我自己在后端尝试解决跨域的例子 2.然后在vue中…

【Vue项目实战】Vue3中动态修改样式和级联样式优先顺序详解

Vue实战笔记目录前言一、ref修改样式1、通过 Vue 的 ref 组件获取 DOM 元素节点注&#xff1a;这边比较一下&#xff0c;和 DOM操作 document.getElementById(id) 这个方法有什么区别2、通过 ref 修改 DOM 元素节点样式二、通过v-bind对Html元素的样式(style)进行动态绑定三、v…

端午假期整理了仿天猫H5 APP项目vue.js+express+mongo

效果 源码 源码太多&#xff0c;放github上了点击 遇到的问题 连接mongodb数据库多个集合&#xff08;model文件&#xff09; mongodb与mysql数据库连接不同&#xff0c;sql在定义查询语句时可以连接不同的表mongodb需要在开始定义好连接要用到的表 module.exports {dbPr…

echarts-wordcloud 血泪总结使用说明 (配置项及其不足点优化)

基本使用方法 echarts-wordcloud是基于echarts的一个词云库&#xff0c;是我常用的一个组件&#xff0c;业务上用的多一点&#xff0c;但是这个库在echarts的官网文档里面没有说明&#xff0c;git上的说明也很少&#xff0c;有些配置需要自己摸索&#xff0c;下面都是我的血泪…

css动画效果

动画1&#xff08;沿着椭圆转动&#xff09; 其实是个2D转动&#xff0c;只不过咱们设置椭圆&#xff0c;然后加上scale缩放&#xff08;近大远小&#xff09;&#xff0c;看上去就是3D效果 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head…

使用Node.js手撸一个建静态Web服务器,内部CV指南

文章里有全部代码&#xff0c;也可以积分下载操作步骤如上图文章结束 话说这个键盘真漂亮~~ 文章目录使用Node.js手撸一个建静态Web服务器一、动静态服务器的概念1.1 静态Web服务器概念1.2 静态Web服务器的优点1.3 快速搭建的途径二、 手撸指南2.1 框架搭建2.2 CtrlC/V2.3 启动…