因業務須要,開發微信支付功能,涉及三種支付方式:php
使用微信支付的前提必開通微信商戶號,要使用到那種的支付方式要前需在商戶平臺開通(要審覈)。html
支付的錢最終都會到商戶號裏(通常由公司財務開通)。前端
開發微信支付的過程當中大大小小坑仍是踩了很多,終於作完了,整理下開發流程。ios
參考:web
orderId
並返回code
code
和orderId
請求後端接口,獲取支付所需數據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("支付失敗"); } }
orderId
並返回orderId
請求支付接口,得到 mweb_url
,mweb_url
會跳轉微信自動調用微信支付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 設置一個"我已支付"的按鈕,讓用戶點擊以後查詢狀態。 }
redirect_url
進行urlencode
處理orderId
orderId
跳轉到支付頁,獲取 code
ajax
code
code
,請求數據跳轉受權頁面,code
會經過回調地址一塊兒返回回來code
,發送給後端,後端解析到 openid
,保存好。點擊肯定支付按鈕,觸發 wxPay()
方法npm
orderId
給後端,獲取 wxData
wxData
中包含 wx.config
和 wx.chooseWXPay
兩個接口的數據。wx.config()
而後在調用 wx.chooseWXPay()
,若是一切正常,支付頁面就會彈出。// 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";
<template> <div> <button @click="wxPay">點擊支付</button> </div> </template>
支付頁 JSaxios
// 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("支付失敗"); }, }); }, }
// 在建立訂單以後,就判斷環境使用哪一種方法支付。 if (isWx()) { this.WXPay(orderId); // 帶着orderId跳轉到支付頁邏輯 } else { this.H5Pay(orderId); // 執行上面H5支付中的建立訂單以後的邏輯 } // 判斷是不是微信瀏覽器 function isWx() { let uAgent = navigator.userAgent.toLowerCase(); reutrn(/micromessenger/.test(uAgent)) ? true : false; }
www.xx.com/pay
,最後獲取的 code 會拼在此回調地址後返回,返回後如www.xx.com/pay?code=xxxx
)參考 1獲取 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-sdknpm
包weixin-js-sdkwx.config
的參數wx.chooseWXPay
所需的參數整個流程走下來,給個人體驗是:小程序支付最方面(由於配置少),其次是 H5,JSAPI 支付最麻煩(文章一多半都在寫它)
在微信支付功能開發過程當中,其實最麻煩的不是開發流程,而是他的各類配置和受權流程,爲了拿到所需的參數而來回折騰。
開發過程當中的一些參數是常常用到的,如 appid、openid、orderId
支付流程大徑相同,先獲取到用戶的 openid,知道你是誰,而後統一下單拿到 orderId 再去處理不一樣平臺的支付方式
開發時候用到的相關文檔,必定要仔細閱讀二遍以上爲止!!
遇到問題不要死剛,多百度多 Google,說不許你遇到的問題已經有無數的人遇到過而且已經有成熟的解決方案了。
前端和後端要多溝通,有什麼問題(難點)隨時反饋,須要什麼參數好好說,遇到觀點不一致的時候千萬要注意控制住情緒,切莫撕逼(.——.)。
由於本人水平有限,對後端流程懂得很少,只能之前端的角度來梳理整個支付流程。
以上,但願對你有所幫助。