vue中使用微信支付

今天是五一的第三天假,咱来聊聊微信支付吧,现在网上的微信支付的相关文章不是直接照搬官网就是互抄,如果刚接触微信支付时候去搜相关文章时你会发现很混乱,所以特此总结一篇微信支付的文章,写下自己踩过的坑,也给需要的人一些帮助,我的项目是在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中使用微信支付)