前言
最近由于業務需求,需要開發付款碼功能,該接口底層将會聚合市面上主流錢包 APP 的付款碼功能,如微信支付,支付寶支付。
❝
ps:付款碼支付别稱有很多,如微信支付端支付産品為「付款碼支付(之前的文檔叫做刷卡支付)」,而支付寶端産品為「當面付-條支付」,而有些文檔會成為「二維碼被掃支付」。
下文統一使用微信的定義方式,統稱為付款碼支付。
❞
可能有些同學對于付款碼支付這個聽起來很陌生,其實這個功能我們可能每天都在被使用。
像我們在便利店買個早飯,最後結賬時,使用支付寶/微信支付付款。收銀員會讓我們展示支付寶/微信付款碼,然後使用掃碼槍獲取此碼,最後上送給微信/支付寶服務端完成一次扣款。
以支付寶為例,具體用戶端支付流程如下:
來源自支付寶官網
付款碼支付後台調用流程如下:
付款碼支付詳細版流程
微信/支付寶付款碼支付調用流程大同小異,官網寫的都比較清楚,這裡直接用支付寶的官網的流程。
從上面的流程可以看到,付款碼支付可以說是一個「同步」的接口,即接口同步返回扣款結果,無需通過另外異步通知獲取結果。
不過這裡我們需要注意,由于涉及「安全風控」等問題,付款碼支付過程用戶端可能需要輸入密碼确認支付,此時付款碼接口将會返回等待用戶支付。
接入時務必這正确判斷返回信息,若返回以下結果,代表此時用戶正在輸入密碼。
- 微信支付: 「err_code=USERPAYING 或 err_code=SYSTEMERROR」
- 支付寶: 「code=10003 或 code=20000」
微信付款碼支付在以下情況需要輸入密碼二次确認。
支付寶官方文檔暫未找到相關規則,經過測試當支付金額大于 「2000」 ,需要輸入密碼。如果有熟悉其他驗密規則的同學,可以在評論區留言一下。
另外一點需要注意的是,微信/支付寶其他支付接口,支付成功之後,微信/支付寶服務端将會發送消息通知支付結果。但是付款碼不一樣,該接口是不會有消息通知。
所以如果付款碼支付若返回等待用戶輸入密碼,商家後台服務必須定時調用調用微信支付/支付寶查詢接口,獲取支付結果。
撤銷支付
如果在一段時間内比如 「30s」,輪詢查詢支付結果返回都是等待用戶支付,或者支付交易過程返回失敗或支付系統超時,這兩種情況官方文檔都是建議立刻調用撤銷接口撤銷交易。
如果此訂單用戶支付失敗,撤銷接口将會訂單關閉;如果用戶支付成功,撤銷接口将會訂單資金退還給用戶。
也就是說撤銷支付接口功能上等同與「關閉訂單」加上「退款」。雖然撤銷也具有退款功能,但是兩者存在比較大的區别:
「支付類型限制」
微信/支付寶撤銷支付「僅能撤銷付款碼支付類型的訂單」,而退款可以支持多種支付類型的訂單。
「退款金額」
撤銷接口隻能是「全額退款」,而退款接口支持傳入金額,可以全額退款,也可以部分退款。
「時間限制」
撤銷接口時間限制比較短,比如微信支付撤銷支持 「7 天」内的訂單,而支付寶撤銷接口僅支持當天的訂單。
但是退款接口可以支持較長時間訂單退款,比如微信支付退款支持「一年内」的訂單,而支付寶僅支持 「3 個月」内訂單。
「基于以上區别,其他正常支付的單如需實現相同功能請調用退款接口,官方文檔建議僅在異常的情況下才建議調用撤銷支付接口。」
另外再說一點,有些地方這個功能接口稱為「沖正接口」,如下面工商二維碼支付。
實際上提供的功能與微信/支付寶撤銷類似,這裡需要各家支付公司提供文檔具體研究。
撤銷支付相關問題
由于撤銷支付,可能導緻退款,也可能關閉訂單,接入之前一直有些問題弄不清楚,在官方文檔處也沒有查詢到任何資料,沒辦法隻好實測驗證相關問題。
❝
由于規定,支付機構不能直連微信/支付寶,所以以下測試基于銀聯微信/支付寶通道。
銀聯提供的接口與直連微信/支付寶存在些許差别,但是主要功能一樣。
❞
重複撤銷
通過實測,微信/支付寶撤銷接口幂等實現,重複撤銷返回結果一緻。
不過需要注意需要正确判斷撤銷的返回結果。
比如微信撤銷接口成功判斷還需要結合 recall 字段,支付寶也有類似字段。
訂單狀态
微信/支付寶訂單狀态處理不太一緻,微信訂單狀态比較複雜:
微信支付訂單狀态機
也就是說,付款碼訂單一旦被撤銷成功,再次查詢訂單,狀态将會返回為「已撤銷(REVOKED)」。
另外微信對于付款碼支付訂單有限制,是無法調用關閉訂單接口關閉訂單,所以在付款碼的場景中,是不存在訂單狀态為 「CLOSED—已關閉」。
接下來說下支付寶的狀态,支付寶文檔沒要給出類似的訂單狀态機,我根據官方一些文檔,以及一些測試結果總結出下方訂單狀态圖。
所以支付寶的付款碼訂單一旦撤銷成功,再次查詢原單狀态将會返回 「TRADE_CLOSED」。
對賬文件數據
當天産生交易之後,次日我們需要拉取微信/支付寶對賬文件,逐一核對數據,防止少賬,多賬問題。
對賬設計流程可以參考之前寫過的文章:
聊聊對賬系統的設計方案
微信/支付寶對賬文件隻會記錄交易成功的訂單,所以未支付的訂單被撤銷是不會出現在對賬文件中。但是如果支付成功了,然後又被撤銷成功,将會在對賬文件中産生「兩筆記錄」,一筆正交易,一筆反向退款記錄。
正交易與普通的退款的記錄都比較好識别,一般可以使用我們上送給微信支付寶訂單号。但是撤銷導緻退款記錄,我們無法僅用一個單号識别,我們需要結合另外的字段區分判斷。
微信對賬文件撤銷産生那筆退款,交易狀态為 「REVOKED」,所以我們可以采用商戶訂單号加交易狀态識别出一條記錄是否為撤銷産生退款記錄。
❝
上面銀聯訂單号可以當做是微信支付寶内部産生訂單号
❞
支付寶對賬文件比較麻煩,撤銷産生的退款記錄不能跟微信根據交易狀态區分。從對賬文件上看支付寶撤銷産生退款與普通退款接口産生退款記錄是一樣的。
仔細研究對賬文件可以發現一些區别,撤銷導緻退款記錄退款批次與正交易支付寶内部訂單号是一緻的。而正常退款記錄,退款批次号是由商戶自己上送的。所以我們可以以此篩選出撤銷産生的退款記錄。
撤銷失敗
極端情況下,有可能産生多次撤銷都失敗的奇葩情況,那怎麼辦?
這種情況下就不用往系統自動處理方向考慮了,通過線下人工介入處理吧,畢竟這種概率太低了。引用知乎@天順的文章中一句話:
❝
很多時候人工保障比你動腦筋想異常中的異常如何系統自動處理來得反而高效和低成本
❞
這句話大家仔細品,越品越有道理!
最後說一句(求點贊)
付款碼支付接入其實比較簡單,主要難點在于撤銷接口引入之後對于現有的系統的改造,比如撤銷成功的訂單之後,是直接修改原單的成功狀态到撤銷狀态,還是說再創建一條撤銷記錄?還有對賬系統核對時,對端記錄可能比本端多,如何核對?這些問題大家在接入之後一定結合現有系統好好思考一下。
最後,文章難免存在一些疏漏,大家如果發現,可以在評論區留言指出,謝謝支持。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!