美文网首页vueJs使用Vue Vue
vue中使用微信支付

vue中使用微信支付

作者: MrHong_bfea | 来源:发表于2021-05-03 10:34 被阅读0次

    今天是五一的第三天假,咱来聊聊微信支付吧,现在网上的微信支付的相关文章不是直接照搬官网就是互抄,如果刚接触微信支付时候去搜相关文章时你会发现很混乱,所以特此总结一篇微信支付的文章,写下自己踩过的坑,也给需要的人一些帮助,我的项目是在vue移动端的项目上,所以我会总结两种微信支付的方式(JSAPI:在微信浏览器上的微信支付,MWEB:在微信以外的浏览器上的支付)。

    项目是用vue+ts的,如果项目上没有ts的就把一些类型声明去掉,下面就开始步入正题了。

    1.如果你的下一个页面要进行微信支付,那就要在上一个页面提前判断是否在微信里面,如果在微信里面是要获取到code值才能进行JSAPI支付的。

     // 判断是否在微信浏览器  1为微信浏览器 2为其他  这个方法定义在外面,后面也会用到
      _isweixin() {
        return new Promise((resolve: any) => {
          const ua: any = window.navigator.userAgent.toLowerCase();
          //userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。
          if (ua.match(/MicroMessenger/i) == "micromessenger") {
            resolve(1);
          } else {
            resolve(2);
          }
        });
      }
    

    注意:hostUrl是对应参数redirect_uri的,我刚开始踩坑的时候是redirect_uri域名与后台配置不一致,所以一定这个要跟配置网页授权域名的人拿,如果没有配置是拿不了code值,就没法进行第二步了,获取code的步骤在这里

    //然后下面这个方法是跳转到需要微信支付的页面
     async _nextTournamentPackage({ bagId }: any) {
        const isweixin = await this._isweixin();
        if (isweixin === 1) {
         //这里我是外部引入,需要的话自己引入APPID,hostUrl
          const appid = APPID; 
          const redirecturi: any = encodeURIComponent(
            `${hostUrl}/#/package?data=${JSON.stringify(
              Object.assign({}, { bagId })
            )}`
          );
          window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirecturi}&response_type=code&scope=snsapi_base#wechat_redirect`;
        } else {
          this.$router.push({
            name: "package",
            query: { data: JSON.stringify(Object.assign({}, { bagId })) },
          });
        }
      }
    

    2.第二步是拿到code值,后面就是要获取签名之类的,文档在这里,这个签名这些可以后台配置给你,也可以前端自己生成。具体看文档。

    // wechatPay.ts文件
    import { Vue } from "vue-property-decorator";
    declare let WeixinJSBridge: any  // 解决 WeixinJSBridge 在TS编译会报错
    export interface Res { // 微信需要传入的数据,数据格式定义
      appId?: string;
      timeStamp?: string;
      nonceStr?: string;
      package?: string;
      signType?: string;
      sign?: string;
    }
    
    export default class WechatPay extends Vue {
      public payType = ''
      public res: Res = {}  // 数据由后端返回
      /**
       * 微信JS支付,在点击支付时启用
       */
      public WeChartJSBridge(callback:any):void {
        if (typeof WeixinJSBridge === 'undefined') { // WeixinJSBridge 在TS编译会报错,因为该对象只在微信浏览器中存在,在文件头部声明 declare let WeixinJSBridge: any 即可
          if (document.addEventListener) {
            // 监听调用,可有可无
            document.addEventListener('WeixinJSBridgeReady', () => {
              this.onBridgeReady(this.res, callback)
            }, false)
          } 
            else if ((document as any).attachEvent) { // attachEvent()只在IE中有用,IE11已经不再支持
            (document as any).attachEvent('WeixinJSBridgeReady', this.onBridgeReady);
            (document as any).attachEvent('onWeixinJSBridgeReady', this.onBridgeReady);
          }
        } else {
          this.onBridgeReady(this.res, callback)
        }
      }
      public onBridgeReady(res: Res,callback:Function): void {
        WeixinJSBridge.invoke('getBrandWCPayRequest', {
          appId: res.appId,
          // 公众号名称,由商户传入
          timeStamp: res.timeStamp,
          // 时间戳,自1970年以来的秒数
          nonceStr: res.nonceStr,
          // 随机串
          package: res.package,
          signType: res.signType,
          // 微信签名方式:
          paySign: res.sign
          // 微信签名
        },
         (res: any) => {
            if (res.err_msg === 'get_brand_wcpay_request:ok') {
              // 使用以上方式判断前端返回,微信团队郑重提示:
              // res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                callback()
            }
            if (res.err_msg === 'get_brand_wcpay_request:cancel') {
                // 支付取消
                
            }
            
            if (res.err_msg === 'get_brand_wcpay_request:fail') {
                // 支付失败
            }
          })
      }
    }
    
    //这是跳转过来的package的页面
    // 引入上面那个文件
    import WechatPay from "@/utils/wechatPay";
    // 确认人民币付款
      async confirmRmbPay() {
        const params: any = {
          id: '你请求接口传的id',
          payType: "wechatPay"
        };
        const isweixin = await this._isweixin();
        if (isweixin === 2) {
          alert("请在微信以外的浏览器里打开并支付!");
          // params.payScenes = "MWEB";
          // orderPay(params)
          //   .then((res: any) => {
          //     if (Number(res.code) === 0) {
          // 调用直接跳转后台返回给你的url地址,类似下面的地址
          //       //     window.location.href =
          //       // "weixin://wap/pay?prepayid=xxxxxxxxx&package=xxxxxx";
          //     } else {
          //       Toast.info(res.msg);
          //     }
          //   })
          //   .catch(() => {
          //     
          //   });
        } else {
          // 这个是在微信浏览器里的支付,获取code值后调用支付
          const search: any = window.location.search;
          const searchString = search.length > 0 ? search.substring(1) : "";
          const args = searchString.length > 0 ? searchString.split("&") : [];
          const items: any = {};
          for (let i = 0, length = args.length; i < length; i++) {
            const name = decodeURIComponent(args[i].split("=")[0]);
            const item = decodeURIComponent(args[i].split("=")[1]);
            items[name] = item;
          }
          if (!items["code"]) {
            Toast.info("生成订单错误");
            return;
          }
          params.code = items["code"];
          params.payScenes = "JSAPI";
          //orderOay是调用支付的接口,自己定义
          orderPay(params)
            .then((res: any) => {
              if (Number(res.code) === 0) {
                const wechatpay = new WechatPay();
                const payParams: any = {
                  appId: APPID,
                  timeStamp: res.result.timeStamp,
                  nonceStr: res.result.nonceStr,
                  package: `prepay_id=${res.result.prepayId}`,
                  signType: "MD5",
                  sign: res.result.paySign
                };
                wechatpay.res = Object.assign({}, payParams);
              //下面wechatpay.WeChartJSBridge里面是一个成功支付的回调,在里面你可以做回调成功的操作
                wechatpay.WeChartJSBridge(() => {
                    return (window.location.href = `${hostUrl}/#/ordergroup2`)
                });
              } else {
                Toast.info(res.msg);
              }
            })
            .catch(() => {
            });
        }
      }
    

    所有过程都结束了,如果喜欢的可以点个赞哦,谢谢各位,有不懂的欢迎私信!

    相关文章

      网友评论

        本文标题:vue中使用微信支付

        本文链接:https://www.haomeiwen.com/subject/lvqfdltx.html