pc端微信二维码支付流程及问题排查
場景
在做pc端的支付時,我們常用的就是生成二維碼讓用戶去掃碼支付。
like this:
當然你想像我一樣有個二維碼支付的圖片,還需要先申請微信支付的native支付功能。
native支付會提供一個二維碼供用戶掃碼。
頁面內,通常會有一個按鈕,通過按鈕的點擊事件來調用支付接口,支付接口返回的數據如下:
這里面的qrcodeUrl是一個base64格式的圖片數據,我們使用image的src屬性接收這個數據就能得到一個二維碼圖片了。
問題
通常的話,會使用一個彈窗內嵌image標簽展示二維碼,這樣就存在一個重復支付的隱患:
用戶在掃碼支付完成后,如果頁面的彈窗未關閉,那二維碼就會一直呈現在頁面內,會給用戶造成未支付的錯覺。那么用戶就會再次掃描二維碼進行支付,這樣就會造成重復支付的問題。
所以呢,我們需要在用戶支付成功之后把彈窗關閉,這樣就可以解決這個問題了。
具體的實現方式就是—>
彈窗內部進行支付結果監測的輪詢,一旦支付結果監測出為支付成功,就把彈窗關閉。
實現
說起輪詢,其實就是頻繁的調取接口訪問某個狀態的變化。
這樣的話很容易想起setInterval,但是使用setInterval會有一個問題就是:很任性!
不管不顧:在它內部執行的指令,它可不管你是執行與否,到時間就再次執行。
setInterval的機制就是執行一個異步隊列,每次都會把事件添加到隊列里面。當前隊列為空的時候,會到事件隊列里面去取,如果當前隊列執行時間長了點,事件隊列里面就會被添加很多事件,當前隊列執行完成后,事件隊列的事件就會短時間內連續觸發,相較于我們使用setInterval進行輪詢的初衷就會背道而馳。
所以,可以使用setTtimeout來代替setinterval進行實現。在settimeout中循環調用達到輪詢的效果,并且settimeout的機制保證了每個事件都是在前一個執行完畢后再執行的。
OK,方法確定下來就可以著手效果實現了。
使用watch監聽彈窗v-model綁定的屬性:
visible的true和false控制彈窗的開、閉。
watch進行監聽可以執行異步方法。在handle函數內使用setTimeout調用支付結果監測的接口進行輪詢,并通過接口返回的支付狀態字段清除定時器和關閉彈窗。
具體的代碼實現就是:
這里看著是不是思路清晰,邏輯無誤?
可憐見的,我寫好的時候也是美滋滋的,直到—>
彈窗關不了!彈窗關不了!彈窗關不了!
沒關系!我自查:
我在this.visible=false下面打印this.visible
控制臺顯示:
這沒錯啊,既然是false,說明我改visible的值是改好的呀,那為什么彈窗不關閉呢?
想不通……
中午吃飯在想、路上在想、去洗手間在想、喝水在想……
小小的腦袋大大的疑惑,到底這是為什么!
電光火石之間(腦子抽抽),我在this.visible=false上面打印了this.visible
是的,把它當成三明治夾起來,上下都打印,出現了這個:
undefined!!!
很明顯,我的data里面是有這個屬性,否則我不可能打開彈窗,現在出現undefined是在表明什么???
我是個笨蛋:
明明函數的嵌套關系很多了,明明使用了settimeout函數,明明函數內還使用this,我還是沒有考慮this的指向問題,倒是用它用的起勁,出現問題抓耳撓腮就是找不到源頭,要不是腦子抽抽,今天晚上睡覺估計夢里都是我改了visible的值,彈窗還是沒關,到底為什么。
好在這下找到問題了。
兩個解決方案:
①settimeout等函數使用箭頭函數(死去的ES6語法突然攻擊我)
②在未進入定時器的函數內使用that保存this的屬性值,再進行改變值的時候就能直接操作到visible本身了。
至于this.visible=false上面打印出來undefined,下面倒是false是因為這個過程相當于屬性重新創建的過程。
可喜可賀,問題順利排查出來,并且解決方法也有了,這下可以實現了(我用了第二種):
效果
點擊支付操作,內部的click事件調用native支付接口返回qrcodeurl,就是二維碼圖片
把二維碼圖片放在彈窗的image標簽內
用戶掃碼,彈窗內進行輪詢事件檢測支付狀態,支付成功彈窗關閉并刷新頁面(處理支付狀態顯示的問題)。
整個流程是不是很清晰,并且相關問題的解決方案也有提供多種噢~
如果這篇文章對您有用,麻煩:
總結
以上是生活随笔為你收集整理的pc端微信二维码支付流程及问题排查的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为手机热点无法连接_为什么华为手机开热
- 下一篇: 一份优秀的大数据开发简历是怎么样的?