首頁 >微信小程式 >小程式開發 >從前端的角度來整理微信支付的流程

從前端的角度來整理微信支付的流程

coldplay.xixi
coldplay.xixi轉載
2020-12-09 17:56:595138瀏覽

微信小程式開發教學梳理微信支付的流程

從前端的角度來整理微信支付的流程

#推薦:#微信小程式開發教學

因為業務需要,開發微信支付功能,涉及三種支付方式:

  • JSAPI 支付:微信內網頁支付,需要開通微信服務號碼
  • 小程式支付:在小程式中支付,需要開通小程式
  • H5 支付:在手機瀏覽器(出微信內網爺)中網頁支付

使用微信支付的前提必開通微信商家號,要使用到那種的支付方式要前需在商家平台開通(要審核)。

支付的錢最終都會到商戶號碼裡(一般由公司財務開通)。

開發微信支付的過程中大大小小坑還是踩了不少,終於做完了,整理下開發流程。

參考:

  • 微信支付-存取指引
  • 微信支付-開發文件

小程式支付

開發流程

  1. 小程式端請求建立訂單接口,後端統一下單取得orderId 並返回
  2. 小程式端取得透過wx.login ()取得code
  3. 小程式端拿這codeorderId請求後端接口,取得支付所需資料
  4. 取得支付所需資料之後,小程式端呼叫wx.requestPayment()接口,直接呼叫起支付頁面
  5. 判斷是否支付成功後的邏輯

async function wxPay(goodId) {
  // 1. 创建订单 获取orderId
  let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
    goodId, // 商品id
  });
  // 2. 获得 code
  let code = await wxlogin(); // 基于pr封装的wx.login()方法
  // 3. 获取支付的数据
  let payData = await ajax("POST", "/api/OrderProgram/WxXcxPay", {
    orderId,
    code,
  });
  // 4. 发起支付
  let res = await payment(payData); // 基于pr封装的wx.requestPayment()方法
  // 5. 判断是否支付成功
  let payResult = res.errMsg;
  if (payResult == "requestPayment:ok") {
    console.log("支付成功");
  } else if (payResult == "requestPayment:fail cancel") {
    console.log("用户取消支付");
  } else {
    console.log("支付失败");
  }
}

注意事項

  1. 申請微信小程式帳號
    申請成功可拿到AppID(小程式id)和AppSecret(小程式金鑰)
    申請類型為企業性質,否則無法接入微信支付
  2. 微信小程式認證
    通過認證的小程式才能接入微信支付和綁定商家平台
  3. 申請商家平台帳號
    需要第一步驟申請的AppID
    申請成功可拿到MchID(商家id)和MchKey(商家金鑰)
  4. 信小程式關聯商家號碼
    微信與商家都認證成功後,在微信後台微信支付選單中進行關聯
  5. 存取微信支付
    在微信後台微信支付選單中進行存取

H5 支付

開發流程

  1. 前端端請求創建訂單接口,後端統一下單獲取orderId# 並返回
  2. #前端帶著orderId 請求支付接口,獲得mweb_url
  3. 然後跳轉mweb_url 會跳轉微信自動調用微信支付
  4. 支付後返回支付頁,判斷是否支付成功(需發送請求後端查詢)
    4.1 重新整理頁面,取得最新的付款(訂單)狀態。
    4.2 設定一個的按鈕"我已付款",讓使用者點擊自動查詢狀態。

偽代碼

async function wxH5Pay(goodId) {
  // 1. 创建订单 获取orderId
  let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
    goodId, // 商品id
  });
  // 2. 获取支付跳转的URL
  let mweb_url = await ajax("POST", "/api/OrderProgram/WxH5Pay", { orderId });
  // 3. 跳转URL去微信支付
  if (mweb_url) {
    location.href = mweb_url;
  } else {
    console.log("回调地址出错");
  }
  // 4. 支付后返回支付页,判断是否支付成功
  // 4.1 刷新页面,获取最新的订单(商品)状态。
  // 4.2 设置一个"我已支付"的按钮,让用户点击之后查询状态。
}

注意事項

  • 在商家平台設定正確的支付網域
  • 偵錯需要在線上,如果嫌麻煩可以使用內網穿透(Ngrok 或花生殼)
  • 需對redirect_url進行urlencode處理
  • H5 付款不能直接在微信客戶端內調起,請在外部瀏覽器調起。

參考

  • 微信支付-H5 支付-開發步驟

JSAPI 支付(微信內網頁支付)

#開發流程

  • 商品頁
  1. 前端商品頁建立訂單,在後端統一下單後取得orderId
  2. 前端帶著orderId 跳到支付頁,
  • 支付頁
  1. #取得

    code

      第一次進入頁面,判斷是否路徑中有
    1. code
    2. #沒有
    3. code,請求資料跳轉授權頁面,code 會透過回呼位址一起回傳回來
    4. 拿到
    5. code,傳送給後端,後端解析到openid ,保存好。
  2. 點擊確定支付按鈕,觸發

    wxPay() 方法

      發送
    1. orderId 給後端,取得wxData
    2. wxData 中包含wx.configwx.chooseWXPay 兩個介面的資料。
    3. 先呼叫
    4. wx.config()然後在呼叫 wx.chooseWXPay(),如果一切正常,付款頁面就會彈出。
  3. 支付狀態透過後端去查詢
偽代碼

    商品頁
// 1. 创建订单 获取orderId
let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
  goodId, // 商品id
});
// 2. 携带id 跳转到支付页
this.$router.push({ name: "wx_pay_page", params: { orderId: id } });
    入口檔案(
  • main.js)
// main.js 引入 js-sdk
import wx from "weixin-js-sdk";
  • #付款頁HTML##
    <template>
      <p>
        <button @click="wxPay">点击支付</button>
      </p>
    </template>
付款頁JS

// Vue
data(){
    return {
        orderId: this.$route.params.orderId, // 订单id
        url: '',// 获取code的url
        wxData: null,// js-sdk接口所需的数据
    }
},
mounted(){
    // 判断是否有code
    this.getCode()
}
methods: {
    getCode() {
        var code = this.getUrlPram("code");
        if (code != null) {
            this.code = code;
            // 拿到 code 发给 后端
            this.sendCode(code);
        } else {
            // 去拿code
            this.getUrl();
        }
    },
    getUrl() {
        // 请求后端拿到url所需数据,然后跳转页面在通过回调地址返回,获取code.
        this.axios
            .post("/api/OrderProgram/GetOpenidAndAccessToken", {
                orderId: this.orderId,
            })
            .then((data) => {
                this.url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${data.appId}&redirect_uri=${data.redirect_uri}&response_type=${data.response_type}&scope=${data.scope}&state=${data.state}`;
                window.location.href = this.url;
            })
            .catch((err) => {
                console.log(err);
            });
    },
    sendCode(code) {
        // 发送code给后端 后端解析出openid
        this.axios
            .post("/api/OrderProgram/GetOpenidAndAccessTokenFromCode", {
                code: code,
            })
            .then((res) => {
                console.log(res);
            })
            .catch((err) => {
                console.log(err);
            });
    },
    wxPay: async function() {
        // 发送orderid,获取wx.chooseWXPay和wx.config所需的参数
        this.wxData = await this.axios.post(
            "/api/OrderProgram/WxJSAPIPay",
            { orderId: this.orderId }
        );
        let wxConfigData = this.wxData.wxConfigData // 获取wx.chooseWXPay()所需数据
        let wxPayData = this.wxData.wxPayData;// 获取wx.config()所需数据
        this.$wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: wxConfigData.appId, // 必填,公众号的唯一标识
            timestamp: wxConfigData.timeStamp, // 必填,生成签名的时间戳
            nonceStr: wxConfigData.nonceStr, // 必填,生成签名的随机串
            signature: wxConfigData.paySign, // 必填,签名
            jsApiList: [
                "chooseWXPay",
            ],
        });
        // 执行支付
        this.$wx.chooseWXPay({
            timestamp: wxPayData.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
            nonceStr: wxPayData.nonceStr, // 支付签名随机串,不长于 32 位
            package: wxPayData.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
            signType: wxPayData.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
            paySign: wxPayData.paySign, // 支付签名
            success: (res) => {
                this.$toast("支付成功");
            },
            fail: (err) => {
                this.$toast("支付失败");
            },
        });
    },
}

同时支持 H5 支付和 JSAPI 支付

// 在创建订单之后,就判断环境使用哪种方法支付。
if (isWx()) {
  this.WXPay(orderId); // 带着orderId跳转到支付页逻辑
} else {
  this.H5Pay(orderId); // 执行上面H5支付中的创建订单之后的逻辑
}
// 判断是否是微信浏览器
function isWx() {
  let uAgent = navigator.userAgent.toLowerCase();
  reutrn(/micromessenger/.test(uAgent)) ? true : false;
}

注意事项

  • 开通微信商户号 - 设置支付目录(如果是 Vue 这类 SPA 页面,到根目录即可,也就是#号之前的地址)
  • 开通微信公众号(服务号) - 设置安全域名、设置授权域名
  • 收集参数:appId 和 AppSecret
  • 添加 Web 开发工具开发者(需要开发者同时开发者关注开发的微信公众号和微信公众账号安全助手)参考文档
    [图片上传失败...(image-b07878-1605777597831)]
  • 设置回调域名(例如:www.xx.com/pay,最后获取的 code 会拼在此回调地址后返回,返回后如www.xx.com/pay?code=xxxx
  • 获取 code

    • 参考获取 code 文档
    • 在微信客户端网页打开授权地址,跳转之后,在返回的回调地址之后拿到 code
https://open.weixin.qq.com/connect/oauth2/authorize
?appid=你的appid
&redirect_uri=你的回调地址(拿到code后返回)
&response_type=code(返回类型,默认code)
&scope=snsapi_base(授权范围,静默授权拿到openid)
&state=STATE(自定义状态,非必填)
#wechat_redirect(重定向使用必须携带)

redirect_uri参数要和你在微信公众号里设置的回调域名一致(例如:www.xx.com/pay),需要注意的是这 url 需要urlEncode

请求这个地址之后,code 会以你设置的redirect_uri地址里的参数带回来,拿到之后传给后端就行了。

  • 前端引入 js-skd

    • 使用script引入js-sdk
    • 下载使用 npm 包weixin-js-sdk
  • 获取 wx.config 的参数
  • 获取 wx.chooseWXPay 所需的参数

参考

  • 微信支付-JSAPI
  • 微信公众号-网页授权
  • JS-SDK 开发文档

总结

整个流程走下来,给我的体验是:小程序支付最方面(因为配置少),其次是 H5,JSAPI 支付最麻烦(文章一多半都在写它)

在微信支付功能开发过程中,其实最麻烦的不是开发流程,而是他的各种配置和授权流程,为了拿到所需的参数而来回折腾。

开发过程中的一些参数是经常用到的,如 appid、openid、orderId

支付流程大径相同,先获取到用户的 openid,知道你是谁,然后统一下单拿到 orderId 再去处理不同平台的支付方式

开发时候用到的相关文档,一定要仔细阅读二遍以上为止!!

遇到问题不要死刚,多百度多 Google,说不准你遇到的问题已经有无数的人遇到过并且已经有成熟的解决方案了。

前端和后端要多沟通,有什么问题(难点)随时反馈,需要什么参数好好说,遇到观点不一致的时候千万要注意控制住情绪,切莫撕逼(.——.)。

因为本人水平有限,对后端流程懂得不多,只能以前端的角度来梳理整个支付流程。

以上,希望对你有所帮助。

以上是從前端的角度來整理微信支付的流程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除