輕輕一掃,馬上扣款,付款碼背後的原理你不想知道嗎?|原創

前言

最近因爲業務需求,須要開發付款碼功能,該接口底層將會聚合市面上主流錢包 APP 的付款碼功能,如微信支付,支付寶支付。安全

ps:付款碼支付別稱有不少,如微信支付端支付產品爲付款碼支付(以前的文檔叫作刷卡支付),而支付寶端產品爲當面付-條支付,而有些文檔會成爲二維碼被掃支付微信

下文統一使用微信的定義方式,統稱爲付款碼支付。異步

可能有些同窗對於付款碼支付這個聽起來很陌生,其實這個功能咱們可能天天都在被使用。ide

像咱們在便利店買個早飯,最後結帳時,使用支付寶/微信支付付款。收銀員會讓咱們展現支付寶/微信付款碼,而後使用掃碼槍獲取此碼,最後上送給微信/支付寶服務端完成一次扣款。測試

以支付寶爲例,具體用戶端支付流程以下:微信支付

來源自支付寶官網

付款碼支付後臺調用流程以下:idea

付款碼支付詳細版流程

微信/支付寶付款碼支付調用流程大同小異,官網寫的都比較清楚,這裏直接用支付寶的官網的流程。設計

img

從上面的流程能夠看到,付款碼支付能夠說是一個同步的接口,即接口同步返回扣款結果,無需經過另外異步通知獲取結果。3d

不過這裏咱們須要注意,因爲涉及安全風控等問題,付款碼支付過程用戶端可能須要輸入密碼確認支付,此時付款碼接口將會返回等待用戶支付。code

接入時務必這正確判斷返回信息,若返回如下結果,表明此時用戶正在輸入密碼。

  • 微信支付: err_code=USERPAYING 或 err_code=SYSTEMERROR
  • 支付寶: code=10003 或 code=20000

微信付款碼支付在如下狀況須要輸入密碼二次確認。

支付寶官方文檔暫未找到相關規則,通過測試當支付金額大於 2000 ,須要輸入密碼。若是有熟悉其餘驗密規則的同窗,能夠在評論區留言一下。

另一點須要注意的是,微信/支付寶其餘支付接口,支付成功以後,微信/支付寶服務端將會發送消息通知支付結果。可是付款碼不同,該接口是不會有消息通知。

因此若是付款碼支付若返回等待用戶輸入密碼,商家後臺服務必須定時調用調用微信支付/支付寶查詢接口,獲取支付結果。

撤銷支付

若是在一段時間內好比 30s,輪詢查詢支付結果返回都是等待用戶支付,或者支付交易過程返回失敗或支付系統超時,這兩種狀況官方文檔都是建議馬上調用撤銷接口撤銷交易。

若是此訂單用戶支付失敗,撤銷接口將會訂單關閉;若是用戶支付成功,撤銷接口將會訂單資金退還給用戶。

也就是說撤銷支付接口功能上等同與關閉訂單加上退款。雖然撤銷也具備退款功能,可是二者存在比較大的區別:

支付類型限制

微信/支付寶撤銷支付僅能撤銷付款碼支付類型的訂單,而退款能夠支持多種支付類型的訂單。

退款金額

撤銷接口只能是全額退款,而退款接口支持傳入金額,能夠全額退款,也能夠部分退款。

時間限制

撤銷接口時間限制比較短,好比微信支付撤銷支持 7 天內的訂單,而支付寶撤銷接口僅支持當天的訂單。

可是退款接口能夠支持較長時間訂單退款,好比微信支付退款支持一年內的訂單,而支付寶僅支持 3 個月內訂單。

基於以上區別,其餘正常支付的單如需實現相同功能請調用退款接口,官方文檔建議僅在異常的狀況下才建議調用撤銷支付接口。

另外再說一點,有些地方這個功能接口稱爲衝正接口,以下面工商二維碼支付。

0

實際上提供的功能與微信/支付寶撤銷相似,這裏須要各家支付公司提供文檔具體研究。

撤銷支付相關問題

因爲撤銷支付,可能致使退款,也可能關閉訂單,接入以前一直有些問題弄不清楚,在官方文檔處也沒有查詢到任何資料,沒辦法只好實測驗證相關問題。

因爲規定,支付機構不能直連微信/支付寶,因此如下測試基於銀聯微信/支付寶通道。

銀聯提供的接口與直連微信/支付寶存在些許差異,可是主要功能同樣。

重複撤銷

經過實測,微信/支付寶撤銷接口冪等實現,重複撤銷返回結果一致。

不過須要注意須要正確判斷撤銷的返回結果。

好比微信撤銷接口成功判斷還須要結合 recall 字段,支付寶也有相似字段。

訂單狀態

微信/支付寶訂單狀態處理不太一致,微信訂單狀態比較複雜:

微信支付訂單狀態機

也就是說,付款碼訂單一旦被撤銷成功,再次查詢訂單,狀態將會返回爲已撤銷(REVOKED)

另外微信對於付款碼支付訂單有限制,是沒法調用關閉訂單接口關閉訂單,因此在付款碼的場景中,是不存在訂單狀態爲 CLOSED—已關閉

接下來講下支付寶的狀態,支付寶文檔沒要給出相似的訂單狀態機,我根據官方一些文檔,以及一些測試結果總結出下方訂單狀態圖。

因此支付寶的付款碼訂單一旦撤銷成功,再次查詢原單狀態將會返回 TRADE_CLOSED

對帳文件數據

當天產生交易以後,第二天咱們須要拉取微信/支付寶對帳文件,逐一覈對數據,防止少帳,多帳問題。

對帳設計流程能夠參考以前寫過的文章:

聊聊對帳系統的設計方案

微信/支付寶對帳文件只會記錄交易成功的訂單,因此未支付的訂單被撤銷是不會出如今對帳文件中。可是若是支付成功了,而後又被撤銷成功,將會在對帳文件中產生兩筆記錄,一筆正交易,一筆反向退款記錄。

正交易與普通的退款的記錄都比較好識別,通常可使用咱們上送給微信支付寶訂單號。可是撤銷致使退款記錄,咱們沒法僅用一個單號識別,咱們須要結合另外的字段區分判斷。

微信對帳文件撤銷產生那筆退款,交易狀態爲 REVOKED,因此咱們能夠採用商戶訂單號加交易狀態識別出一條記錄是否爲撤銷產生退款記錄。

上面銀聯訂單號能夠當作是微信支付寶內部產生訂單號

支付寶對帳文件比較麻煩,撤銷產生的退款記錄不能跟微信根據交易狀態區分。從對帳文件上看支付寶撤銷產生退款與普通退款接口產生退款記錄是同樣的。

仔細研究對帳文件能夠發現一些區別,撤銷致使退款記錄退款批次與正交易支付寶內部訂單號是一致的。而正常退款記錄,退款批次號是由商戶本身上送的。因此咱們能夠以此篩選出撤銷產生的退款記錄。

撤銷失敗

極端狀況下,有可能產生屢次撤銷都失敗的奇葩狀況,那怎麼辦?

這種狀況下就不用往系統自動處理方向考慮了,經過線下人工介入處理吧,畢竟這種機率過低了。引用知乎**@天順**的文章中一句話:

不少時候人工保障比你動腦筋想異常中的異常如何系統自動處理來得反而高效和低成本

這句話你們仔細品,越品越有道理!

Reference

異步通知如何判斷對應哪筆退款交易

對帳與退款

撤銷接口retry_flag字段說明

退款接口、關閉接口和撤銷接口的區別

最後說一句(求點贊)

付款碼支付接入其實比較簡單,主要難點在於撤銷接口引入以後對於現有的系統的改造,好比撤銷成功的訂單以後,是直接修改原單的成功狀態到撤銷狀態,仍是說再建立一條撤銷記錄?還有對帳系統覈對時,對端記錄可能比本端多,如何覈對?這些問題你們在接入以後必定結合現有系統好好思考一下。

最後,文章不免存在一些疏漏,你們若是發現,能夠在評論區留言指出,謝謝支持。

若是你也在從事支付,或者正在對接支付,歡迎加我微信,一塊兒討論問題,一塊兒成長~

歡迎關注個人公衆號:程序通事,得到平常乾貨推送。若是您對個人專題內容感興趣,也能夠關注個人博客:studyidea.cn

公號底圖
相關文章
相關標籤/搜索