支付系統訂單模型該如何設計?

技術瑣話發表於2019-02-18

本文轉載自無敵碼農,獲授權釋出。

導讀

最近經歷了一件事,就是小碼農所在的公司因為被某大廠收購之後要進行融合了,其他方面的融合就沒必要說了,今天我們們只是聊一下支付系統融合的事情。首先從很多網際網路公司的發展經驗來看,隨著多條業務線的發展,最終都是會催生出建設統一支付系統的強烈需求。

這是為什麼呢?因為支付系統太重要了,它擁有公司所有的現金流水,是進行業務清算、財務核算、上市審計以及後續各類財務資訊管理的關鍵系統之一。一家公司被收購後新老闆們最關心的事也莫過於財務資料的準確性了,之前小碼農從事支付系統的研發工作加入的都是已經比較成熟的團隊,去建設的支付系統也都是為了幫助所在公司來實現上述的目標和戰略,而所採用的策略也都是在強大的上層的支援下進行業務線統一支付入口的歸集。

只不過這一次作者所加入的是一家網際網路創業公司,而在支付系統的建設上,也屬於比較混亂和初級的階段,因此在被收購後屬於是在另外一個強大上層的支援下而被統一的一方而已。當然從客觀的角度看,這也是一件非常合理的事情,因為一個大的集團公司無論是從成本還是統一管理的角度看都是沒有必要重複建設多套支付系統的,而對一家被收購的公司而言,其支付系統肯定也是首先需要被融合的關鍵系統之一。

作者對此持開放和樂觀的態度,即使這個過程對個人會有一些影響。只是因為在此之前經歷了很多的坎坷,覺得有很多事情還是值得總結一下,因此才想著寫一篇文章來回憶下這個過程。而總結的目的,也只是希望能夠對未來會經歷這樣一個過程的公司,有一點參考價值,因為即便是被融合,如果做的比較好的話也會讓融合的過程會更加容易一些,至少還能得到一些口碑,否則就很容易遭人罵了,而從技術本身看也會是一種失敗。

被忽視的團隊

關於支付團隊是否是被忽視的團隊的問題,可能因公司而異(或者也許因不同公司處於關鍵崗位的技術Leader是否具備這樣的經驗和遠見而異),可能有一些網際網路創業公司在發展初期並不是很Care這件事,因為早期的業務也確實沒有那麼複雜,在業務程式碼中接個微信、支付寶能有多難,兩三個人都嫌多還想引起什麼樣的重視?

的確,作者最開始加入這家網際網路創業公司時,真的就只是在業務程式碼中對接了一個支付寶、微信,看起來好像真的是沒有那麼複雜,在人員方面也就是兩個沒有太多支付經驗的研發而已,連正式的支付訂單流水錶都沒有,還基本上是與業務訂單耦合在一起的那種。

然而,似乎這一切好像也並沒有影響公司業務的蓬勃發展,線上收款業務量也是增長迅速,每天好幾個億的進賬。只是這個時候,會偶爾出現很多掉單而已,反正使用者投訴了,寫條SQL改下訂單狀態,要麼退款,要麼用SQL進行下業務處理。

總之,看起來一切並沒有那麼複雜,只是後面又增加了幾個新的支付渠道,而支付寶、微信這種因為開了新的入口(如和微信小程式合作,支付寶第三方合作之類)又申請了下新的微信、支付寶商戶號。

從截止到以上階段的場景上分析,到目前為止都只是在單向的進行收款操作。而隨後的事情可能就有點戲劇性了,因為突然某一天,發生了擠兌的事,系統的退款請求迅速增加,當然,此時大部分的退款請求還都只是走原路進行全額退款的操作,還沒有部分退款等一些複雜的業務退款情況,而此時的退款掉單則有點扯了,因為這導致了大量使用者已經退款,而業務系統邏輯並沒有更新狀態的情況,此時此刻也就為後續財務資料的混亂埋下了相應地伏筆(之前的支付掉單處理得不及時,也是在埋伏筆)。

似乎更為糟糕的是,因為有些使用者太過於忠誠,支付的訂單時間過長,已經超出了第三方渠道允許進行原路退款返回的期限,而此時因為無法通過系統自動進行原路退款,最終沒有辦法客服小姐姐只能人工收集客戶上報的資料(如支付寶賬號),然後通過Excel由哪兩位苦逼的開發去通過手工的方式整理後通過單獨申請的支付寶代付賬號進行轉賬退款操作,似乎這種方式也沒有什麼太大問題,只是比較原始而已。的確是這樣,然而不幸的是,只是這種人工操作偶爾還會失敗,需要重新發起和進行系統訂單狀態的更新(如果真的把錢給別人轉成功了,得用SQL把狀態給改了啊),而這個過程因為人工因素,導致了一些狀態未更新的情況,以及轉賬重複的小失誤,而這也為後續財務資料的混亂埋下了另外一筆伏筆。

看到這裡,也許不少同學都會詫異,這尼瑪為啥不設計相應的機制來解決呢?所以,這個時候開始有人談起了支付系統重構的問題。而此時作者正好加入這家公司,所以心想也算一個機會,於是也提出的自己的重構方案。細節不提了,只說一個基本的支付系統應該是什麼樣,如下圖所示:

支付系統訂單模型該如何設計?

於是作者激情滿滿的找到了領導,提出了自己的想法。然而,令人沒想到的是,還有個Secret專案因為也涉及到一些支付功能的重構,所以需要找人相關人員溝通下,好吧,此時才知道原來支付系統已經在祕密地被重構了,只是正常開發和維護支付系統的人居然不知道這件事。也罷,而讓人更意想不到的事,這是居然還不算完,因為還有另外一個團隊,屬於另外一個VP領導下的團隊也在進行支付系統的重構,只是正常的支付團隊以及祕密重構的專案都還彼此不知道而已。

說到這裡,仔細想想,作者也是很詫異,不過好歹因為作者提出的這個想法並鼓足勇氣和大佬溝通,總算讓大家彼此知道了這件事,也算是一個良好的進步和開端。而與此同時,還有另外一個團隊在開發所謂的財務系統(實際上就是作者圖中所規劃的賬務系統,當然後者因為種種扯淡的因素,在做了兩月之後做黃了,以至於到目前為止仍然缺失這一塊,而收購方希望融合方式則正是所有的業務線接入他們統一收銀臺的同時,還需要接入其賬務系統,這樣資金流、業務流就完成雙向閉環了,這樣業財核對、收入計算就可以通過集團統一而完備的系統進行集中處理了)。

於是乎,好像此時此刻,這件事應該是向著好的方向發展了,支付系統應該是在比較充足的資源配置的情況下,並且經過合理的設計後開始有計劃有步驟地重構了。然而,不幸的事,此時此刻又出現了新的攪局者,新來了一位似乎很有經驗的產品經理,提出要建設一套很牛逼的統一交易系統,而支付系統當然只是其中底層的一個小部分而已。

如此這般,最終經過N輪的扯皮、溝通以及團隊利益的糾結爭鬥,最後就由某某團隊開始進行支付系統的重構了,與此同時作者呢因為剛來,所以就做起了大家都覺得很不起眼的對賬工作了。然而,後續支付系統的重構,並沒有完成徹底的重新塑造,整個系統的訂單模型並沒有進行脫胎換骨的改造和升級,對於歷史資料的處理,也是避重就輕,只是簡單的在新的支付系統的程式碼層面進行了適配,並採用了無敵的雙寫策略,如此至今還是雙寫(客觀地究其原因,因為那個團隊實際參與重構的也只有2~3人,在經驗和資源缺乏的情況下,也很難將這件事做的相對全面而完整)。

以上種種也就為支付系統的先天殘缺,資金資料的混亂以及後續為了適配各種新業務而疲於奔命,從而導致更多的不確定埋下了深深的伏筆。而這其中,又經歷了不同主管Leader的更換,但似乎沒有一個是專業的,於是造就了現如今的種種亂象。

通過上述的坎坷歷程的回顧,這可能並不像是一個技術問題,而更多的像是因為創業公司的技術管理混亂而導致一種扭曲的現象。也許換一個CTO就不一定會是這種狀態,所以這種情況是否屬於共性問題,也就需要大家自己根據自身公司的實際情況進行判斷了。只是在這裡作者將其籠統的歸咎為對支付團隊統一建設的一種忽視吧。

有問題的組織

關於這個問題,不同的公司的情況可能是不一樣的,正如上面所說,早期在業務程式碼中對接個支付寶、微信的介面也許並不是太複雜的事,但是需要說明的是如果考慮到未來業務的擴充套件所導致的複雜性,並且在已經開始重構支付系統的情況下,則是一定要做到“麻雀雖小,五臟俱全”,之所以這麼說,原因在於支付系統是一種對資料一致性要求非常高,但是又很難單純的從某一個小的方面保證資料一致性的系統,它需要一個完整的體系來保證。

而上面提到的複雜性,就有很多種情況了,例如如果涉及系統退款,退款本身就會存在諸多的複雜性,如全額原路退款、部分原路退款、線上轉賬退款、線下轉賬退款等,並且不同的支付渠道所能支援的程度還有差異。

另外,如果涉及多渠道、同一渠道不同的商戶主體,以及銀行卡支付/非銀行卡支付,海外支付多發的ChargeBack等情況,則帶來的複雜性也會相應地增加。因為此時支付系統不僅需要滿足引數配置化、渠道路由化等要求,支付方式、交易方式所產生的資料訂單也需要具備完整的儲存邏輯。

當然,上述邏輯複雜度的增加也不是一開始就是這樣的,而是隨著業務發展逐步遞增的。所以對於支付團隊的配置,也沒有必要一開始就配置一個大的團隊,但是作為團隊的技術Leader,一定要清楚在什麼階段需要什麼樣的人員配備,並且明確的指定一名具有一定專業度的支付團隊技術Leader來帶頭進行有組織、有計劃地重構工作,而不是在這個問題上含糊不清,因為按照個人的經驗,在這個事情上的瞎競爭其實是沒有什麼好處的,最終可能會帶來混亂。

支付訂單模型

在具體討論如何對支付訂單模型進行設計討論之前,和大家一起回顧了一些團隊發展和建設的問題,因為至少在作者目前看來,最本質的問題並不是出在技術本身上,而是因為團隊技術管理混亂,帶來了一系列的惡果。

但很多時候,也許以上種種並不是我們作為普通技術人員本身能夠干預得了的,因為這往往牽扯很多技術以外的因素。那麼如果假設你承擔了這一角色,或者作為一名具體的工程師,在你具體重構或設計支付系統時,如何儘可能地想得長遠一些呢?這裡有作者根據自身經驗設計的一套邏輯模型,供你參考。

支付系統訂單模型該如何設計?


上圖是一張精簡的關於支付系統訂單模型設計的圖,在模型中我們將訂單分為交易&支付兩個層面,之所以要這麼劃分,是在於我們進行支付系統開發時很多時候是需要滿足一部分業務邏輯的,而設定交易訂單的目的則是為了遮蔽這種業務不確定性而帶給支付訂單本身的複雜性。

在這個模型中,交易訂單作為與業務交易對映的一張記錄表,例如業務A通過支付系統發起了一筆充值交易(如10塊錢),那麼就會在交易訂單中插入一條10塊錢的充值交易流水,而這筆充值流水正常情況下可以通過相應地支付渠道進行支付,可以一次性支付10塊錢(插入一條對應的支付訂單流水),也可以支付兩次5塊錢,並且還可以分別使用不同的支付渠道(分別插入兩筆對應的5塊錢的支付訂單流水),所以交易訂單與支付訂單的關係為1:N

之所以允許這樣的情況發生,是因為在實踐中,因為渠道限額,業務允許重複發起支付等原因,所以必須允許進行拆單支付的情況發生。而如果在這種情況下又需要允許交易進行退款的話,為了精簡資料儲存,對於交易訂單可以通過狀態機進行處理(如設定交易退款狀態),而對於支付來說,退款本身也是支付流水,所以不應該直接在支付訂單流水上進行狀態更改,而是應該單獨設計獨立的退款流水錶,只是需要在退款流水錶中設定原始支付的訂單資訊,以及退款的具體方式即可。

而支付退款本身又可以分為原路退款/非原路退款,而這兩種退款方式又分別可以分為全額退款和部分退款兩種情況,所以支付流水與退款流水之間又存在1:N的關係。還是舉上面那個例子,如果使用者充值交易所支付的10塊錢,是一次性通過微信支付的,那麼退款時如果時全額原路退款,則只需要插入一條與支付流水對應的10塊錢的退款流水,並更新交易訂單狀態為“已退款”即可。

如果是因為該使用者的充值部分,使用了5塊,剩下的5塊錢可以退款,那麼此時發起的就是原路部分退款,在退款流水錶中插入一條與支付流水相關的5塊錢的退款流水即可,但是此時需要將對應的交易訂單狀態更新為”部分退款“的狀態。

此外,以上情況如果由於支付訂單時間太久,原支付渠道已無法再進行原路退款,此時只能通過線上或線下轉賬方式/代付方式進行退款的話,則為了完善模型,我們也需要在退款流水錶中記錄一條與原支付訂單關聯的退款流水,只是退款方式需要記錄非原路退款的情況,並且在發起轉賬或代付退款後,需要在退款流水中關聯對應的轉賬或代付流水號,之後根據實際退款的情況更新對應的交易訂單狀態為“已退款/部分退款”。

而轉賬或代付本身因為又是一種單獨的支付方式,所以此時我們需要在支付流水錶中單獨記錄轉賬訂單或代付訂單,但因為此時與交易訂單本身無直接關聯,所以不需要產生新的交易流水。

對於海外支付渠道因為產生了ChargeBack的情況,我們需要將其視為與轉賬類似的非原路退款方式,從而進行退款流水的記錄,以及ChargeBack訂單本身的記錄,這一點對於海外支付渠道的支付邏輯完善以及ChargeBack本身的追溯會比較重要。

按照這種模型進行支付訂單結構的設計,並在一開始就擼清楚這些支付場景的對應的資料儲存邏輯,會對未來系統的拆分擴充套件大有好處,因為至少資料邏輯是非常清晰的了。只是為了確保這套資料邏輯的一致性,我們還需要加強對賬系統關於內部訂單對賬的邏輯,確保不出現異常和不一致的資料問題。

以上就是本次作者關於支付部分想寫的全部內容了,希望能夠對一些正在經歷支付系統構建的朋友們無論好壞有一點參考借鑑的意義。

談一下家國情懷

在這裡上面乾貨部分的內容就說完了,接下來的內容純屬表達下心情,希望見諒!最近因為華為事件,作者也看了很多報導和相關的分析文章,總結一點就是華為的5G太強大,觸動了以美國為主導的西方利益,因為一旦5G網路建設的主導權被中國公司掌握,那麼未來世界的網路格局就要發生翻天覆地的變化了,所以美國開始搞一些下三濫的綁票手段了。

在這裡作者作為一名中國人,對此表示強烈的憤慨,同時也認識到這個世界還是一個弱肉強食的世界,之前很多人都說美國這裡好,哪裡好的,當然我也承認美國的確在很多方面還領先中國,但是正所謂“金窩銀窩不如自己的狗窩”,還是希望大家多多愛自己的祖國,不要時不時的隨波逐流噴我們國家這不好,那不好的了。做好自己的本質工作,不求為國做多大貢獻,但求不給國家添亂就行!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562044/viewspace-2636299/,如需轉載,請註明出處,否則將追究法律責任。

相關文章