
在串接金流的時候,API 的傳遞參數通常會有「背景通知付款結果網址」與「結帳完成後重新導向網址」這兩個參數要傳,近期處理的是站內付信用卡,原先的資訊傳遞是同步的,也就是顧客在站內付款 → 付款資訊傳到金流商 → 金流商回傳付款結果 → 網站將結果寫入資料庫 → 顯示結帳完成頁。
在這樣的情境下結帳頁可以正確拿到已寫入資料庫的付款結果,但由於站內付不會重新導向至第三方金流頁,為了安全性的考量,在串接時預設就開啟 3D 驗證,藉此確保每一次的刷卡都有經過銀行端的確認。
但開啟 3D 驗證後問題就來了,發現到結帳完成頁並沒有顯示付款結果的資訊且訂單狀態為未付款,檢查資料庫發現相關資訊都有正確寫入,但就是無法正確顯示於結帳完成頁,必須要重新整理一次頁面才會顯示,研究許久才發現到這樣的結帳流程變成是非同步狀態。
問題出在接收 3D 驗證的「背景通知付款結果網址」與「結帳完成後重新導向網址」不同,顧客在付款完成會先重新導向至後者,而在這之前背景付款通知結果還沒有寫進資料庫,因此造成結帳完成頁沒有取得付款結果的資訊。
為了解決這問題進行了以下幾種思路:首先是顧客在進入結帳完成頁後,用 PHP 或 JS 去自動重整頁面一次,藉此取得已經寫入資料庫的付款結果,但這做法會讓顧客先看到錯誤的完成頁,雖然重新載入後可以看到正確的,但有可能會造成顧客誤認重複付款的機會。
第二條路是修改「結帳完成後重新導向網址」,從原本的結帳完成頁改為自訂的 wc-api 路徑,然後在該路徑裡面去等待背景通知付款結果寫入資料庫後,再重新導向至結帳完成頁。但這會牽涉到 PHP 的非同步機制,這部分沒處理過感覺很複雜,留作最後的下下解。
後來突發奇想,何不把「結帳完成後重新導向網址」也改成「背景通知付款結果網址」,也就是這兩個網址都收得到背景通知付款結果,等到寫入資料後再重新導向至網站的結帳完成頁,這樣就可以省去資料不同步的問題。
實作後果然解決了,暫時也沒有衍伸其他問題,PHP 的非同步等下次有機會再玩了XD