----------------------------------------------------------------------------------------------------------------------------
(下圖:微信支付流程圖)
2 微信公衆號支付的基本邏輯如下
《1》---配置好一個url,直接通過window.location.href的方式訪問 ,與此同時會重定向到配置好的redicturl中,微信會給改url自動加上兩個參數:code和state
《2》---前端截取到code參數,訪問後端接口拿到如下參數
"appId":self.appId, //公衆號名稱,由商戶傳入
"nonceStr":self.nonceStr, //隨機串
"package":self.package,
"paySign":self.paySign,//微信簽名
"signType":self.signType, //微信簽名方式:
"timeStamp":self.timeStamp,
《3》拿到後端給與的參數以後,就可以監聽微信提供的事件來喚醒微信支付,只要微信提供的事件被監聽到,就會出現金額彈窗進行支付
如下:
onBridgeReady(){
let self=this
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":self.appId, //公衆號名稱,由商戶傳入
"nonceStr":self.nonceStr, //隨機串
"package":self.package,
"paySign":self.paySign,//微信簽名
"signType":self.signType, //微信簽名方式:
"timeStamp":self.timeStamp, //時間戳,自1970年以來的秒數
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
console.log("支付成功",res)
window.location.href=`http://http://testaa.bb.net/#/pay?orderCode=${decodeURIComponent(self.orderCode)}&isWxPayOk=true`
}else if(res.err_msg == "get_brand_wcpay_request:cancel"){
console.log("取消支付")
window.location.href='http://testaa.bb.net/#/pay/#/myOrder/1'
}else if(res.err_msg == "get_brand_wcpay_request:fail"){
console.log("支付失敗")
// WeixinJSBridge.call('closeWindow');
window.location.href=`http://testaa.bb.net/#/pay?orderCode=cls${decodeURIComponent(self.orderCode)}`
}
});
},
再說一說h5支付。h5支付再喚醒微信支付時候的邏輯基本一致,都是先有一個配置好的url然後重定向到對應 的
redirecturl地址然後獲取code,再向後端發請求拿到appid等參數,最後通過這些參數調用微信提供的方法喚醒微信支付。
但是在配置url時有一個地方卻迥然不同。
對於微信瀏覽器,
const wxurl="https://open.weixin.qq.com/connect/oauth2/authorize"
let deCodeUrl=encodeURIComponent('http://testaa.bb.net/#/pay')---->這裏是你要重定向的頁面地址
const httpWxUrl=wxurl+`?appid=wx12345678&redirect_uri=${deCodeUrl}&response_type=code&scope=snsapi_base&state=123#wechat_redirect`
然後通過window.location.href=httpWxUrl
而對於其他瀏覽器而言:
這個wxurl地址卻並非我們寫死的。是需要後端提供的。所以h5支付在喚醒微信支付的時候流程應該是這樣的:
(1)請求後端接口獲取到一個url,本例中的mwebUrl,
(2)拼接一個帶有redirectur的新的地址,本例中的url
(3)重定向到這個地址,頁面打開獲取code---->請求接口獲取appid等參數---->調用微信提供的WeixinJSBridgeReady方法在改方法內通過 WeixinJSBridge.invoke的回調內處理成功或失敗的跳轉邏輯
let orderCode=db.ls.get("vuex").user.orderCode
let res= await orderApi.wxCreateOrder({...data,tradeType:'MWEB'})
console.log("獲取微信支付參數,",res.data.data.mwebUrl)
let mwebUrl=res.data.data.mwebUrl||""
let url=`${mwebUrl}&redirect_url=${encodeURIComponent('http://testaa.bb.net/#/pay?orderCode='+orderCode+'&isWxPayOk=true')}`
window.location.href=url
接下來說一說踩坑
1 微信支付的回調函數
onBridgeReady(){
let self=this
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":self.appId, //公衆號名稱,由商戶傳入
"nonceStr":self.nonceStr, //隨機串
"package":self.package,
"paySign":self.paySign,//微信簽名
"signType":self.signType, //微信簽名方式:
"timeStamp":self.timeStamp, //時間戳,自1970年以來的秒數
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
console.log("支付成功",res)
window.location.href=`http://testaa.bb.net/#/pay/#/pay?orderCode=${decodeURIComponent(self.orderCode)}&isWxPayOk=true`
// self.$router.push({path:"/pay",query:{orderCode:decodeURIComponent(self.orderCode),isWxPayOk:true}})
}else if(res.err_msg == "get_brand_wcpay_request:cancel"){
console.log("取消支付")
window.location.href=`http://testaa.bb.net/#/pay?orderCode=${decodeURIComponent(self.orderCode)}`
}else if(res.err_msg == "get_brand_wcpay_request:fail"){
console.log("支付失敗")
// WeixinJSBridge.call('closeWindow');
window.location.href=`http://testaa.bb.net/#/pay?orderCode=cls${decodeURIComponent(self.orderCode)}`
}
}
對於微信瀏覽器內打開的網頁進行支付,取消支付,支付成功,和支付失敗都會有觸發,也就是裏面的console.log()
但是對於h5支付而言。也即是除了微信瀏覽器而言。不管是取消還是成功或是失敗。都會都get_brand_wcpay_request:ok"成功的回調。
也正是如此,微信官方希望在取消支付或者支付成功的redirecturl裏開發者自己設計一個彈窗,讓用戶手動點擊,而點擊的時候走自己後端的接口
從而確定訂單是否真實完成。
既然上面提到了獲取code需要通過重定向一個頁面。然後通過該頁面的url截取到code。那容易就想到做一箇中間頁面,這樣在點擊支付的時候
跳轉到該頁面獲取到code,但是這也是坑的開始。因爲每次在支付成功以後返回都會退回到這個中間頁,再返回才能回到之前的支付頁面。而正常的交互
顯然不是這樣的,用戶支付成功以後點擊退回應該是支付頁面纔對。而且還有一個問題是因爲返回到了中間頁,而中間頁此時url沒有code,(只有正常點擊
支付按鈕走支付進入到中間頁此時中間頁的url纔會出現code,所以獲取不到code。也就意味着請求後端的接口走不通),這時就會出現一旦用戶取消獲取支付成功
以後返回就會報錯appid不存在之類的。
所以能不能不走中間頁,直接在點擊支付的前一個頁面獲取到code
所以正確的流程應該是
在進入支付頁面的前一個頁面進行重定向,在支付頁面獲取code
在這個頁面重定向
代碼如下:主要要區分下h5瀏覽器還是微信瀏覽器
在支付頁面
1 獲取code
2 通過code請求後端接口獲取openid
3用戶點擊支付 ,先走後端接口,傳入openid和其他參數,獲取到appid,nonceStr,signType等參數
4 在步驟3的成功回調裏拿到appid,nonceStr,signType等參數,觸發微信內置的函數喚醒微信支付
5觸發步驟4的函數邏輯裏將有成功,失敗,取消等相應,前端進行相應的邏輯跳轉