微信支付前端對接流程


以vue spa項目為例,測試微信支付對接。

  1. 在index.html中添加sdk
 <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

在main.js中注冊wx全局變量

Vue.prototype.$wx = window.wx

特別說明: 如果使用了weixin-js-sdk的npm包,在測試環境會導致wx的值是undefined,在本地環境沒問題,具體原因未知,因此還是建議在index.htlm中引入sdk。

  1. 在支付后台配置支付域名,建議是一級域名,如payment.domain.com,也就是前端的訪問域名,主要用於回調跳轉。

調試過程中如果遇到微信提示“回調地址未注冊”,說明地址配置錯了。地址不支持配置192.168類型的地址,因此調試支付的時候,建議放到測試環境或者使用類似ngrok的代理工具。

  1. 流程說明:獲取微信授權code,用code請求后端接口獲取openid,openid用於唯一標識當前用戶,因此openid是不變的,但是code每次授權都是不一樣的並且有時效性,所以應該建議每次打開頁面都獲取最新的code。
<template>
  <div>
    <button @click="handlePay">支付</button>
  </div>
</template>

<script>
import axios from "axios";
export default {
  data() {
    return {
      browser: "",
      code: "",
      openid: "",
      orderNo: "xxxxxxxxxxx",
      appId: "wxxxxxxxxxx",
    };
  },
  mounted() {
    if (navigator.userAgent.indexOf("MicroMessenger") > -1) {
      this.browser = "wechat";
    } else if (navigator.userAgent.indexOf("AlipayClient") > -1) {
      this.browser = "alipay";
    } else {
      this.browser = "other";
    }

    if (this.browser === "wechat") {
      this.getCode();
    }
  },
  methods: {
    handlePay() {
      const url = "http://dev.domain.com/order-center/pay/wxPayment";
      axios
        .post(url, {
          orderNo: this.orderNo,
          payAmount: "0.01",
          payType: "2", // 1-支付寶;2-微信;3線下支付
          openId: this.openid,
        })
        .then(({ data }) => {
          if (this.browser === "wechat") {
            const wxConfig = data.data;
            // signature
            this.$wx.config({
              debug: false, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。
              appId: wxConfig.appId, // 必填,公眾號的唯一標識
              timestamp: wxConfig.timeStamp, // 必填,生成簽名的時間戳
              nonceStr: wxConfig.nonceStr, // 必填,生成簽名的隨機串
              signType: wxConfig.signType,
              paySign: wxConfig.paySign, // 必填,簽名
              jsApiList: ["chooseWXPay"],
            });
            this.$wx.chooseWXPay({
              appId: wxConfig.appId,
              timestamp: wxConfig.timeStamp, // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。(但最新版的支付后台生成簽名使用的timeStamp字段名需大寫其中的S字符,因此后端返回的是駝峰)
              nonceStr: wxConfig.nonceStr, // 支付簽名隨機串,不長於 32 位
              package: wxConfig.package, // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=\*\*\*)
              signType: wxConfig.signType, // 簽名方式,默認為'SHA1',使用新版支付需傳入'MD5'
              paySign: wxConfig.paySign, // 支付簽名
              success: (res) => {
                this.$toast("支付成功");
              },
              fail: (err) => {
                this.$toast("支付失敗");
              },
            });
          }
        });
    },
    getCode() {
      const code = this.getUrlPram("code");
      if (code != null) {
        this.code = code;
        // 拿到 code 發給 后端
        this.sendCode(code);
      } else {
        // 去拿code
        this.getUrl();
      }
    },
    sendCode(code) {
      // 發送code給后端 后端解析出openid
      axios
        .get("http://dev.domain.com/notify/authCodeToOpenid/" + code)
        .then((res) => {
          this.openid = res.data.openid;
        })
        .catch((err) => {
          console.log(err);
        });
    },
    getUrlPram(name, url) {
      if (!url) url = location.href;
      name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
      var regexS = "[\\?&]" + name + "=([^&#]*)";
      var regex = new RegExp(regexS);
      var results = regex.exec(url);
      return results == null ? null : results[1];
    },
    getUrl() {
      // 獲取微信code,獲取到后code會掛到re_url上
      // state用於追加需要回調的數據,你希望授權后把原來路由上的數據能帶回來,比如說orderId、orderState,拼接方式:state=xxxxxx,xxxxxx
      const re_url = encodeURIComponent(
        "http://payment.test.domain.com/index.html#/new-pay"
      );
      this.url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appId}&redirect_uri=${re_url}&response_type=code&scope=snsapi_base&state=${this.orderNo}`;
      window.location.href = this.url;
    },
  },
};
</script>

<style lang="less" scoped>
</style>

當我點擊支付按鈕,用當前用戶的openid發起支付請求,后端返回我們拉起支付需要的參數(前端不參與加密的任何過程),特別要注意的是timestamp的s是小寫,如果支付返回“簽名驗證失敗”可能是這個問題導致的,我被這個問題坑了一下。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM