微信支付
微信支付分為JSAPI支付,掃碼支付,APP支付,小程式支付等不同的支付方式。但大體的支付過程是一致的,本文以JSAPI支付,也就是微信內的H5支付為例,描述一下支付的整個開發流程。
配置
商戶需要提前開通商戶平臺,並去公眾平臺或開放平臺提交微信支付申請,獲得商戶號和祕鑰。
ofollow,noindex" target="_blank">詳細文件可以看這裡
支付流程
微信支付的流程圖畫的很完整,開發前要把整個流程研究清楚。
整個流程,服務端需要做的有三件事。
- 前端支付按鈕被觸發後,服務端要去呼叫 統一下單 介面,把預付單資訊、支付引數和引數簽名返回給前端。前端根據這些引數喚起支付。
- 當用戶支付成功後,微信會給我們一個回撥通知,告知我們支付結果。這一步要實現“完成訂單”操作,標記使用者已經成功支付,進入“發貨”流程。
- 提供一個查詢介面,讓前端再次確認是否支付成功。
統一下單
在支付前,商戶系統先呼叫該介面在微信支付後臺生成預支付交易單,同樣的,商戶系統也需要在自己的表裡記錄一筆“未完成訂單”。生成之後返回正確的預付單資訊、支付引數和引數簽名返回給前端。前端根據這些引數喚起支付。
介面
https://api.mch.weixin.qq.com/pay/unifiedorder
引數巨多,具體還是看文件
這裡需要說明的一點是,我們在呼叫這個介面時,需要籤一次名用來給微信做校驗,微信也返回了一個新的簽名用來給我們做校驗,然後我們還要返回給前端一個簽名,用來喚起支付。這三個簽名都不是同一個。
我們不能直接把呼叫統一下單介面返回的簽名返回給前端,而是 根據前端喚起支付的引數去重新簽名 。
注意,是 根據前端喚起支付的引數去重新簽名 ,因為前端的引數名和後端的引數名會略微有差別,這裡需要小心。
說明:簽名的意圖是用來校驗身份,當前端把這些引數傳給微信,微信會把呼叫引數除去簽名後重新簽名,用來校驗簽名的正確性,所以用來簽名的引數名要和前端引數一致。
支付結果通知
在統一下單時我們填了一個引數叫 notify_url
,這是一個服務端的介面地址,微信在使用者支付成功後,會回撥這個地址,告知我們支付結果。
在這一步還是需要做多點校驗的,免得被人有機可乘。
- 校驗支付是否成功,不成功直接返回"FAIL"
- 校驗簽名和appid
- 校驗訂單是否完成(冪等校驗,防止微信多次回撥導致多次訂單寫入)
- 訂單金額校驗
一通校驗完事之後就可以做業務相關的事了。記得所有操作結束後返回"SUCCESS",不然微信會不斷髮起回撥。
總結
- 流程圖描述的很清楚,要仔細閱讀流程圖。
- 呼叫完下單介面後要進行二次簽名,簽名的引數要看前端驗籤用哪些引數,即使是同一個引數,欄位名也會跟第一次加簽不一樣。
- 前端支付完成之後微信會有一個回撥,我們需要做以下幾點校驗:
- 做冪等處理(因為同樣的通知微信可能傳送多次)。
- 校驗簽名,校驗APPID。
- 校驗訂單金額。
- 訂單狀態分為 0-未支付 1-支付完成 2-支付失敗:
- 使用者觸發支付元件然後關閉或者殺掉程序微信不會給到後臺任何回覆,始終處於 0-未支付,所以這個狀態也是一個支付失敗狀態。
- 支付失敗比較少見(到現在沒有遇到過),比如簽名錯誤(發生在除錯階段)。
- 微信回執表儘量詳細的記錄微信傳回的所有必有引數,以備出問題時排查。
- 至今還沒有找到微信本地除錯的方法。