支付系統返回碼設計及映射避坑指南

0 評論 1501 瀏覽 5 收藏 13 分鐘

在支付系統的構建與管理中,返回碼的設計和映射是確保交易順暢進行的關鍵環節。本文將深入探討支付系統返回碼的重要性、常見問題及其解決方案,旨在幫助開發者和支付系統管理者避免潛在的陷阱,提升用戶體驗,并確保交易的準確性和安全性。


我在支付行業呆了十來年,和返回碼映射導致的線上生產問題交手無數次,有很多是因為影響用戶體驗,也有一些直接導致了線上資損,所以有必要開一篇小文聊一下。

一、返回碼還是錯誤碼

有些人喜歡用“返回碼”,有些人喜歡用“錯誤碼”。兩者本質相同,都是用于標識通信或交易的狀態。但我更傾向于使用“返回碼”,因為它不僅涵蓋錯誤狀態,還包括成功狀態,而成功并非錯誤,所以使用“返回碼”更為合適。

二、返回碼的本質

我很喜歡探尋事物的本質,那么返回碼的本質是什么?我覺得是解決2個問題:

  1. 標識單一系統內的業務處理結果:在一個單一系統內,如何表達業務處理的結果,比如參數不對,余額不足,還是成功等。
  2. 完成異構系統或應用之間的處理結果同步:在多個系統之間如何同步業務處理的結果,比如渠道的結果同步給支付平臺的網關系統,網關系統同步給支付引擎等。

三、返回碼最核心的關注點

返回碼最核心的關注點也只有2個:

  1. 同一系統內定義是否足夠清晰明確。減少歧義,減少誤解。
  2. 異構系統或應用之間的映射是否足夠準確。映射不好,輕則影響用戶體驗,重則有資損。

四、曾經碰到過的坑

踩過的坑很多,大致可以歸為以下幾類:

  1. 對客映射不準確,導致用戶持續重試失敗,影響用戶體驗。比如“余額不足”或“風控不過”,返回給用戶“系統異常,請重試”,有些用戶就瘋狂地重試。
  2. 外部渠道沒有明確成功或失敗,內部映射成明確成功或失敗造成資損。比如:

支付同步請求渠道響應還沒有回來,發起了查詢,查詢返回“訂單不存在”,直接推進失敗,但最后銀行扣款成功。

退款同步請求渠道響應返回“系統異?!?,直接推進到失敗,但最后銀行退款成功。

3. 外部渠道有雙層返回碼,沒有做完整判斷。比如第1層只表示接口是否成功(通信層面),第2層才是表示業務是否成功,但是只判斷了接口層面,就推進了內部訂單的業務狀態。

4. 返回碼制定過于籠統或太細。

五、最佳實踐

5.1. 基本原則

  • 制定統一返回碼規范:在團隊或公司層面制定統一的返回碼規范,明確各個返回碼的含義,確保各模塊一致性。
  • 嚴格遵守返回碼定義:研發人員在編碼時,應嚴格按照規范返回對應的返回碼,確保返回碼與實際狀態匹配。明確成功才推進成功,明確失敗才推進失敗,其它全部按“未知”處理
  • 區分接口/通信成功與業務成功。
  • 流入到平臺的(支付、充值等),謹慎映射到成功。從平臺流出的(提現,代發等),謹慎映射到失敗。

5.2. 三級返回碼體系

外部商戶對接支付平臺,支付平臺內部有自己的業務處理,同時還對接了外部的很多渠道,所以需要管理三套返回碼

  • 提供給商戶OpenAPI使用的返回碼:這塊可以直接參考微信支付、支付寶等機構的門戶網站。
  • 內部各應用使用的標準返回碼:用于內部業務的處理。
  • 渠道返回碼:外部渠道提供的返回碼,每個渠道都不一樣,需要映射到內部標準返回碼。

為什么需要三層?主要有3個原因:

  1. 內部應用使用的標準返回碼需要精確,便于內部系統運行的監控。
  2. 給商戶OpenAPI的返回碼需要業務語義明確,但不能過于精確。比如內部出現“卡的有效期不正確”,對外則是“卡號或持卡人或有效期不正確”,避免輪詢攻擊。
  3. 外部渠道返回碼不能全部一對一映射到內部,因為外部渠道太多,容易膨脹。

5.3. 商戶OpenAPI返回碼設計

這部分建議直接參考微信支付、支付寶或者ISO20022標準,這幾家代表了行業的最高水準。

一般來說最少有兩個字段:resultCode和message,一個表示碼,一個表示碼的描述。

也可以增加一個參數result,使用S,F,U表示業務狀態的成功、失敗、未知。

如果是查詢類接口,一定要明確說明是接口成功,還是業務成功。

5.4. 內部標準返回碼設計

支付平臺內部也分了不同域,建議使用一個共同的規范,比如:RS+子系統編號+錯誤級別+具體返回碼。具體如下圖所示:

支付系統返回碼設計及映射避坑指南_v0.2

說明:

  • 1-2位:固定值RS,Result縮寫。
  • 3-5位:子系統編號。比如001:收銀支付,002:會員等??煞奖愣ㄎ荒膫€系統出的問題。
  • 6位:錯誤類或等級。比如:0:正常,1:業務級異常,2:系統級異常。
  • 7-9位:各業務線自己定。比如:1xx:參數相關,2xx:數據庫相關,3xx:賬戶狀態/Token狀態相關等。
  • 這樣的好處在于,每個子域或子系統既有全局的規范,又有自己的靈活性,減少溝通成本。
  • 注意:上面只是寫了resultCode,還需要有message,用于描述這個碼代表什么語義。
  • 核心代碼(注:使用chatGPT o1生成,請自行增刪):
public interface IResultCode {
    String getResultCode();
    String getMessage();
}
public enum PaymentResultCode implements IResultCode {
    SUCCESS( "0000", "success"),
    FAIL("2998", "fail"),
    SYSTEM_ERROR("2999","system error"),
    // 額度相關 11XX
    INSUFFICIENT_FUND("1101", "insufficient fund"),
    // 風控相關 12XX
    RISK_REJECTED("1201", "risk rejected"),
    // DB相關 21XX    ;
    private static final String PREFIX = "RS";
    private static final String SYSTEM_CODE = "101";
    private String codeNumber;
    private String message;
    @Override
    public String getResultCode() {
        return PREFIX + SYSTEM_CODE + codeNumber;
    }
    @Override
    public String getMessage() {
        return message;
    }
    PaymentResultCode(String codeNumber, String message) {
        this.codeNumber = codeNumber;
        this.message = message;
    }
}

5.5. 渠道返回碼映射

每個渠道的返回碼都是不一樣的,所以需要設計外部渠道返回碼映射到內部標準返回碼。需要遵守幾個原則:

  1. 只有明確成功,才能映射到成功
  2. 只有明確失敗,才能映射到失敗。比如渠道返回:訂單不存在,或者系統異常,不能直接映射到失敗,因為有可能會成功。
  3. 涉及個人敏感信息或內部系統敏感信息的,需要轉成模糊返回碼和描述出去,不能給最終用戶展示精確信息。比如內部一個系統宕機,不能直接把異常拋出去。有效期錯誤也需要映射成“卡號或姓名或有效期不正確”。
  4. 與敏感信息無關的,越準確越好,避免用戶無謂的重試。比如余額不足,就不要映射成“系統異常,請重試”。
  5. 查詢類接口,務必要區分是接口成功,還是業務成功。

具體的技術實現,通過使用映射表就足夠,加到緩存中,增加運算速度。如果找不到映射關系,就全部轉到一個默認的返回碼上面,同時對這個默認返回碼做監控,定期把這些沒有做映射的返回碼映射到正確的返回碼上面去。避免應該把類似“余額不足”映射成了“系統異常請重試”的場景。

5.6. 返回碼監控與告警

大部分團隊都會監控成功率,只有少數團隊會監控返回碼或定期分析返回碼。然而當交易量足夠大時,成功率的波動可能只有0.5%,很難看出異常,而如果去分析返回碼,則可以快速看出并定位問題。

一般來說,有幾個建議:

  1. 實時監控返回碼的突變異常。比如:最近10分鐘,某個返回碼突然增加50%,或者比明天突然增加50%等。都需要介入看看。
  2. 定期觀察返回碼曲線表。如果某個返回碼連續多天持續在上升,一般都是有問題的。
  3. 建立返回碼全鏈路映射大盤。比如渠道返回“余額不足”或“風控不通過”,映射到用戶展示“系統異常,請重試”,那就有問題。而且類似這種情況還非常常見。
  4. 定期分析用戶支付行為。以前在分析用戶行為時,發現同一用戶重試了20多次,最后排查發現,就是返回碼映射不準確,導致用戶無謂的重試。

六、結束語

卷用戶體驗和成功率時,往往需要于細微處見真章,而返回碼的設計和映射就是如此。做得不好,輕則影響用戶體驗,重則資損。

希望對大家在設計標準返回碼及映射時有所啟發,也歡迎點贊轉發。

這是《圖解支付系統設計與實現》專欄系列文章中的第(48)篇。歡迎和我一起深入解碼支付系統的方方面面。

作者:隱墨星辰,公眾號:隱墨星辰

本文由 @隱墨星辰 原創發布于人人都是產品經理。未經作者許可,禁止轉載

題圖來自Unsplash,基于CC0協議

該文觀點僅代表作者本人,人人都是產品經理平臺僅提供信息存儲空間服務

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發揮!