PowerDotNet個人專案中功能全面而強大的一個系統是支付平臺,我對PowerDotNet的自信很大程度上來自于經過PowerDotNet重寫后的支付、財務、結算、CRM等業務型公共服務系統的穩定運行,
使用PowerDotNet和PowerDotNetCore特別開發的業務邏輯型公共服務既有極大的業務價值,又具有很大的技術挑戰,在我個人看來算是技術和業務緊密結合的典范,可按需二次開發,
個人開發支付平臺的歷史比較久遠,投入時間較多,當然用自己的眼光看,早期的支付系統從基礎組件運用到程式設計和編碼實作,很多都不太令人滿意,所以我一直想用PowerDotNet重寫支付平臺,
現在經過PowerDotNet重寫后的支付平臺已經達到生產級別,是PowerDotNet里最出色的穩定可靠、靈活可擴展、可維護性強且易運維的公共服務之一,
很多人可能會有疑問,PowerDotNet是不是只能開發一些相對簡單的系統?就像前面介紹的基礎資料平臺,只有CRUD?或者像HCRM人員管理平臺,只有略微復雜點的CRUD而已?
其實我認為所有業務系統都可以抽象出CRUD操作,技術為業務服務,有些系統的CRUD門檻還很高,甚至比萬年不變的框架值錢且難寫多了,在很多業務驅動的公司里,CRUD才是真正的核心競爭力,
個人開發生涯至今,碰到過很多業務邏輯復雜,可維護性惡劣的CRUD型業務系統,經常有各種各樣的奇葩問題,讓人產生一種編程是門面向巧合的玄學的感覺,優質的業務系統代碼實在是鳳毛麟角,
對如何寫好CRUD這個問題各種方法論層出不窮,仁者見仁智者見智,至今還有很多爭論,務虛和務實的選擇而已,哪一種讓你更喜歡更有成就感就堅持自己的選擇,
你可能理解總結了很多技術原理,精通軟體開發設計模式和架構,人手一個ORM和(或)代碼生成器,對很多框架和中間件如數家珍娓娓道來,,,可CRUD卻總寫不好,這才是人間真實,
在某廠有兩位高人大仙交接給我一份支付網關和銀聯支付代碼,代碼量不大,但三天兩頭崩可真有你的,看完代碼我又笑了,魔鬼都在CRUD細節中,能讓所有代碼都變成魔鬼確實讓人欽佩,咩哈哈,
萬丈高樓平地起,讓CRUD更快捷更輕松應對變化更容易擴展和維護,這是PowerDotNet出現的一個重要目標,也讓我們多了一個減少出錯的選擇,所謂多一個選擇多一條路,于我心有戚戚焉,
經過PowerDotNet和PowerDotNetCore重構優化后的支付平臺命名規范優雅,分層和系統互動清晰合理,避免抽象能力邏輯能力和代碼組織能力不強的開發人員陷入代碼迷宮的泥潭,
重寫后的支付平臺,模塊間耦合性大大降低,支付方式比早期支持更多樣,單元測驗覆寫率大幅提高,核心邏輯比原有代碼量少了一半左右,關鍵是運行極其穩定,PowerDotNet平臺基礎居功至偉,
遵循PowerDotNet規范開發的CRUD型應用,不但功能強大高度復用,同時代碼的可讀性、可維護性和靈活性也是第一流的,讓開發者更好體會CRUD的樂趣,別問我怎么知道的,我就是知道^_^,
本文介紹的支付平臺可以認為是目前為止PowerDotNet的最佳實踐中的最佳實踐,主要是因為支付平臺相關的應用比較多,不同系統和應用之間互聯互通關系比較復雜,涉及的專業知識面非常廣泛,
支付平臺的最終目標是將公司資金的出入全部集中到平臺進行統一管理,不論線上還是線下,國內還是國際,B2C還是B2B,
目前PowerDotNet實作的支付平臺API介面初步統計有200多個,這還不包括未接入的支付渠道和輔助工具介面、查詢統計類介面、線下業務介面、用戶資訊和公司虛擬貨幣介面,
支付平臺涵蓋了后端、前端和客戶端的很多方面,主要包括多租戶、分布式快取、訊息佇列、回呼通知、定時任務、配置中心、服務治理、多語言、事務、OLTP、OLAP、頁面跳轉、對賬、證書、檔案、憑證、票據、統計、風控、財務、結算、IoC、AOP、ORM、日志、安全、互操作、冪等、二維碼、條碼、監控、報表等,
支付平臺Power.Payment目前支持B2C(線上和線下)和B2B(線上和線下)主流支付方式,和財務、結算、收銀、風控、賬戶、CRM等都有緊密聯系,是對接商戶業務系統的直接而重要的橋梁,
請注意,真正完備的支付平臺通常還包括收銀、風控、賬務、會計、清算、安全等重要子系統,本文介紹的偏重于直接涉及金錢出入的支付前置和網關部分,它們毫無疑問是支付中最重要的平臺子系統,
幾年前在寫某司支付平臺的時候,PowerDotNet還在開發和完善中,服務治理剛有雛形,不能充分利用很多開源組件功能,所以當時寫的支付平臺用的技術堆疊很弱,但是上線后也正常穩定運行,充分證明了抽象和邏輯的重要性,咩哈哈,
很慚愧,在支付系統做了一點微小的作業以后,對日常開發談不上多上心,卻堅定了我深度開發PowerDotNet的決心,人吶確實都不知道,自己多么不可預料,一個人的命運,當然要靠自我奮斗,但也要考慮到歷史的行程,
經過最近幾年的不斷開發優化和完善,PowerDotNet基礎組件和服務已經非常成熟,支付平臺已經是PowerDotNet里涉及技術最全面互聯互通最復雜的公共服務了,
和主流的開發框架相比,PowerDotNet開發最復雜最具挑戰的業務邏輯型應用也是毫不遜色,
有了PowerDotNet,讓我們擼代碼更輕松更高效,
有了PowerDotNet,我們要做到業務邏輯型選手中的天花板,
有了PowerDotNet,CRUD也能兼顧設計的藝術和藝術的設計,
有了PowerDotNet,CRUD我們也是最專業的^_-,
言歸正傳,
支付是一個看上去容易,實際上很難深入,一旦深入又讓人感覺非常簡單的專業領域,
猶記得當年去某司剛接手支付系統的時候,被頁面跳來跳去,界面改來改去,回呼通知來通知去,介面調來調去,對賬對來對去,日志和風控埋點插來插去,各種代碼分支合并來合并去所支配的恐懼,
后來熟悉了之后,也許自視甚高慣了,覺得這系統除了作業量大而且過度設計性能惡劣以及代碼稀爛之外(更專業的吐槽請猛擊這里和這里),真沒多少技術含量,挑戰性不強,咩哈哈哈^_^,
然后跳到下一家公司,本以為再也不會開發支付相關的東西,不到半年,一個玩票demo型的支付系統就到我手上了,看了原始碼后,我真想說你們還是另請高明吧,我實在也不是謙虛,,,,,,
果然天下烏鴉一般黑,沒有最爛只有更爛,最后我就把demo型支付系統推倒重寫了,間接考驗了我的毅力和技術水平,
寫支付應用,并不是拿到支付SDK和檔案,寫寫接入邏輯拼接下報文就搞定的,這種毫不客氣地說,都是demo水平,咩哈哈,
支付接入,需要抽象和提取,然后才能開發出通用高效、面面俱到、功能強大、接入靈活、穩定可追溯的平臺系統,
我個人有相對豐富的支付平臺的開發經驗,積累的越多越能體會到公共服務設計的強大之處,下面就分享些個人經驗之談,不足或疏漏之處請注意甄別,適合自己的就是最好的,
環境準備
1、(必須).Net Framework4.5+
2、(必須)關系型資料庫MySQL或SqlServer或PostgreSQL或MariaDB四選一
3、(必須)PowerDotNet資料庫管理平臺,主要使用DBKey功能
4、(必須)PowerDotNet配置中心Power.ConfigCenter
5、(必須)PowerDotNet注冊中心Power.RegistryCenter
6、(必須)PowerDotNet快取平臺Power.Cache
7、(必須)PowerDotNet訊息平臺Power.Message
8、(必須)PowerDotNet檔案平臺Power.File
9、(必須)PowerDotNet個人用戶管理平臺Power.PCRM(后續詳細介紹)
10、(必須)PowerDotNet人員管理平臺Power.HCRM
11、(必須)PowerDotNet基礎資料平臺Power.BaseData
12、(必須)PowerDotNet定時任務調度平臺Power.TaskSchedule
13、(可選)PowerDotNet資料同步平臺Power.DataX
一、支付應用
1、應用劃分
根據經驗,大概可以分出下面截圖這么多應用,隨著前后端分離的流行,前端還可以分出SPA應用,
業務方客戶端、H5和APP的支付功能主要通過支付網關介面接入,屬于業務系統,不屬于支付系統,
有些支付后端應用會直連銀行介面,這樣會產生一些額外的應用,比如安全守護行程、回呼通知工具、支付憑證工具等,這里也沒有列出來,

按照流行的微服務劃分方法,支付服務如果按照分類進行介面拆分,還可以分出更多應用,尤其直連銀行的情況下還會產生各種補償和查詢工具應用,
上圖里這么多應用,只是變相證明我的微服務“理論”水平很高,其實最新版PowerDotNet將服務合并后真正開發用到的就是前面七八個應用,微服務一到實踐環節就手指跟不上腦子,真的忙不過來了^_^,
在PowerDotNet微服務實踐程序中,我發現自己走了一些彎路,某些系統或應用為了微服務而微服務真的是得不償失,服務拆分粒度非常考驗個人技術水平和研發經驗,
PowerDotNet深受某廠SOA框架影響,潛移默化中就開發出了服務治理中心、配置中心和通用網關,除了沒有直接容器部署,PowerDotNet算是最早微服務的踐行者之一,
部署簡單、自動伸縮、服務編排這些東西并不是Docker等容器技術出現之后才有的,在虛擬機或物體機上也可以做到,所以PowerDotNet目前還沒有將全部服務改造為容器部署的動力,
PowerDotNet的設計初衷并不是為了所謂微服務,在微服務流行之前,PowerDotNet的很多設計和實作就已經存在了,說是微服務不過趕個時髦而已,
Java之父James Gosling(詹姆斯·高斯林)說過:“語言只是實作目標的工具,而不是目標本身,”,把這句話里的語言兩字替換成各種方法論、框架或微服務同樣適用,軟體開發沒有銀彈,實踐出真知,
當然,除了微服務,不論前端還是后端,服務還是頁面,都需要花費大量的精力去設計開發完成,程式的分析設計階段值得我們投入大量時間,所謂磨刀不誤砍柴工是也,
2、應用開發
PowerDotNet和PowerDotNetCore從單體應用到SOA到微服務一路演進而來,保留了成熟開發模式的主要優點,架構清晰穩定,靈活可擴展,可按需選擇合適的架構寫出滿足自己公司現狀的應用代碼,
PowerDotNet支付平臺就是由我“站在巨人的肩膀上”一人獨立設計開發實作的,PowerDotNet提供的平臺開發工具為開發這個業務平臺系統省了很多力氣,比如說集成到服務治理平臺的不帶界面的介面:

又比如說動態可配置的支付收銀臺頁面:

上面收銀臺頁面只是示例參考,對用戶顯示的部分都可以通過后臺動態配置(隨手配置,不要介意圖示重復),甚至樣式模板都可以高度定制化,如有相似設計,英雄所見略同,咩哈哈,
當然還有常見的H5支付收銀臺,APP、Pad、自動售歡訓、一體機等專用的支付網關,這些在PowerDotNet支付平臺下都開發了對應應用予以支持,本文不再贅述,
二、支付基礎
我們設計的是一個支付平臺,而不是只有支付功能,平臺系統的最大特點就是接入的面要非常廣,也就是典型的多商戶或者多租戶系統,
多租戶系統劃分的維度,常見的比如按照國家或區域劃分,如中國,美國等;按照公司劃分,如總公司,分公司等;按照商戶劃分,如內部商戶,合作商戶,外部商戶等,
本文我們以經典的多商戶系統進行分析講解,
1、商戶管理
主要功能是為接入的商戶端分配編碼和秘鑰,安全接入簽名都用到,同時還能按需動態配置顯示支付方式、支付模板等,這些個性化的需求在一個復雜龐大的電商系統里隨處可見,

2、支付分類
主流的支付分類包括第三方支付、微信支付、信用卡支付、儲蓄卡支付、網銀支付、ApplePay、POS刷卡、公司自身的虛擬貨幣(如賬戶和積分)支付等等,
其中,信用卡支付又可以根據支付通道的不同,分為直連信用卡支付、銀聯通道信用卡支付等,也可以根據來源地不同,分為境內信用卡和外卡,支付的時候還需要區分DCC和EDC,
網銀支付目前已經沒落,很少有新的商戶直接接入網銀,而是主要通過支付寶通道實作網銀支付,
對于特殊業務場景要考慮做到通用支持,比如常見的門店現金結算,我們還會抽象出Cash這一特殊支付分類,銀企直連(銀行轉賬),我們還可以定義BankTransfer支付分類,
擔保支付是一種獨特形式的支付,和信用卡預授權類似,不同公司有不同的業務形態,擔保邏輯也可能不同,
3、支付方式
一個支付分類下包含一個或多個具體支付方式,
4、支付方式配置
支付系統的配置是非常多的,我是看過太多人把配置引數都放到組態檔里,或者寫入配置中心,其實有經驗的人都知道這不是最優選擇,demo開發害死人啊,
腐爛的系統一大特征就是組態檔特別多,特別特別多的那種,尤其是還有人哼哧哼哧開發自定義的配置格式檔案,真是奇哉怪也,
元資料設計大法和模板設計大法同時兼顧可維護性和可擴展性,這才是真正的最優解決方案,本文重點介紹支付平臺,不細說這兩種設計方法,
支付方式的配置主要包括實際支付請求的主要協議引數,還有就是回呼通知URL路徑等,支付方式多起來以后,各種支付方式的配置隔離非常重要,

三、支付單
根據個人開發經驗,業務系統中單據處理最大的難點通常有下面幾種:
1、同一種單據,狀態分類特別多,比如支付狀態、退款狀態、取消狀態、回呼通知狀態等
2、同一種單據,相同狀態分類下,狀態型別多變,中間狀態特別多,比如退款,可能有退款等待,退款申請中,退款審核中,退款處理中,退款成功,退款失敗等多種狀態型別
3、單據之間處理相互依賴,你中有我,我中有你,流程冗長復雜,難以保證事務性,補償處理較難
傳統的比較常見的業務訂單系統和支付系統之間,通常都是通過支付請求唯一流水號和訂單關聯,找到支付方式和支付金額,然后將支付結果(如支付狀態改為支付成功)寫入業務系統中去,
這種邏輯看似簡單,實際上隨著系統的邏輯變得復雜,變得不易維護,比如引入退款、混合支付等邏輯,業務系統可能也不得不隨著支付系統而改動,
支付單的設計思想是,將業務系統和支付系統解耦,支付的資料由支付平臺來管理,業務系統通過關聯的支付單號或流水號呼叫查詢介面來查詢支付狀態即可,
這樣業務系統只要保留支付流水號或者支付單號,自動就能獲取支付狀態,不用自己去維護支付邏輯,
按照不同公司的不同支付形態,支付單可以抽象為扣款支付單、退款支付單、擔保支付單,

退款支付單的設計非常重要,非常考驗一個人的設計水平,

除了常見的扣款、退款、凍結、解凍、預授權等指令,支付單介面還可以抽象出很多其他指令,比如代扣、分潤、退分潤、補差、轉賬、預付款等,按照實際業務需要來,支付單保留了創建更多指令的能力,便于按需擴展,
根據我多年的開發經驗,直接接手過大大小小不少于三個支付系統,沒有抽象出支付單的支付系統是短腿的、不完整的,有些甚至嚴重到拖業務后退,這都是抽象失敗的代價,
四、混合支付
不同的公司有不同的虛擬貨幣系統,混合支付是指公司的虛擬貨幣和外部的支付方式一起支付完成支付請求的一種玩法,這里面就涉及到一個很常見很典型的問題:事務性如何保證?
虛擬貨幣賬戶系統我也設計開發過,還是非常考驗人的技術水平的,沒有支付財務結算風控這些常識的,一般都開發不到位,尤其是應對各種財務結算報表業務變化的時候容易捉襟見肘疲于奔命,
至少個人接觸到很多公司,在虛擬貨幣賬戶系統這方面的開發普遍有點吃力,不說了,說多了又要打擊一波人自尊,咩哈哈,
PowerDotNet系列會有一篇文章講講虛擬貨幣系統開發,
五、大額支付
對于常見的電商業務場景而言,尤其是B2C,支付金額通常會有最大額度,比如我們常見的5萬元,
但是不同的公司業務是不同的,買賣的商品金額也有巨大差異,對支付額度就有了不同要求,
以我們熟悉的汽車電商為例,車款通常金額都在5萬元以上,這就對常見的支付方式有了特定的限制,必須有針對性的對接支持大額度的支付方式,
當然,在B2B業務場景下,企業和供應商之間的資金往來大于5萬元再正常不過,也有銀企直連、支票支付等支持大額支付,B2B付款在下面段落中單獨說明,
還有一種場景也支持大額支付,就是最典型的線下POS刷卡,支持5萬元以上額度的轉賬支付,這種支付形態非常適合先扣款,后創建支付單的場景,當然大額退款邏輯也需要開發支持,
六、B2B付款
B2C類的支付平臺,主要面向終端用戶,讓用戶付款給公司,或公司退款給用戶;B2B類的支付平臺,主要面向企業用戶(如供應商等),公司付款給企業用戶或者企業用戶退款給公司,
本文介紹的支付平臺主要是面向B2C形式的公共服務,而B2B形式的支付分類和支付方式遠遠沒有B2C豐富多樣,比如銀企直聯、支票、現金、POS刷卡等在B2B場景下屢見不鮮,
我們完全可以擴展支持B2B需要的支付分類和支付方式,做成B2C和B2B都通用的支付平臺,當然也完全可以獨立部署支持B2B形式的支付平臺服務,
B2B和B2C類的大額銀行轉賬付款單功能在財務平臺系統里很常見,后續有空再介紹財務平臺系統,
下圖是支付平臺開發的銀企直連部分功能截圖,將B2B和B2C、線上業務和線下業務統一抽象到支付平臺,極大地降低了企業對接支付的難度和復雜度,

支付憑證檔案處理需要按照配置模板定時自動生成并上傳,在檔案平臺Power.File和定時任務平臺Power.TaskSchedule的支持下開發難度明顯下降了一個數量級,
銀企直連開發中碰到的同行、跨行轉賬的差異,支付超時等異狀,支付狀態不確定狀態的補償等等問題,支付平臺都有完善的解決方法,編程確實重在執行,需要不斷實戰積累經驗,
某些公司會將相同支付平臺服務獨立部署多份(當然我也這么干過),支持線上和線下業務,也支持B2C和B2B獨立支付,這樣可以最大程度減少開發成本,
七、支付回呼
1、外部支付方式回呼支付平臺
舉例來說,比如用戶使用支付寶支付完成后,支付寶會先回呼通知到支付平臺,支付平臺改變支付單狀態,然后告訴支付寶支付成功了,
從業務完成角度,從外部支付方式回呼支付平臺這里其實只是完成了支付功能的一個部分,因為業務方還沒有拿到支付結果,還不能進行支付成功后的后續業務處理,
退款流程同扣款流程大同小異,
2、支付平臺回呼通知各接入商戶
支付平臺通過定時任務平臺,定時回呼通知各商戶支付單已經支付完成,
退款流程同扣款流程大同小異,
通知佇列需要抽象出來,系統多次回呼不通過,可以人工補償,

支付系統里有大量的回呼和補償操作,定時任務調度平臺Power.TaskSchedule真是功不可沒,
八、信用卡支付
信用卡支付分類和支付方式可以單獨拎出來說一整篇,
每家銀行的信用卡服務介面都會有差異,我們需將最通用的指令抽象設計提取出來,以應對信用卡介面的差異,當然SDK還得一家一家對接,所以直連信用卡服務開發是一項枯燥繁瑣極需耐心的作業,
信用卡預授權在很多業務場景下被廣泛使用,支付平臺開發的信用卡預授權相關的主要功能和通用核心指令包括:
1、預授權(PreAuth)
2、預授權撤銷(PreAuthCancel)
3、預授權完成(PreAuthComplete)
4、預授權完成撤銷(CompleteRevert)
5、退歡訓退(PreAuthRefund)
6、沖正(Reversal)
在支付分類里已經說過,其中信用卡還要區分內卡和外卡、DCC和EDC、直連還是銀聯等,還有部署環境的搭建,比如有無加密狗或U盾、銀行信用卡客戶端SDK對接等等事情需要費力操心,
九、財務對賬
做過支付和財務的開發人員應該都知道,銀行、第三方支付(如支付寶、財付通等)、微信、銀聯等都有完善的商戶管理后臺,業務人員(通常是財務)會定期按天或月將支付結果匯出為Excel來對賬,
對于常見的B2C或者B2B線下支付場景,如POS刷卡支付、支票、現金或者銀企直連等,也需要定期呼叫銀行提供的查詢介面或者直接匯出Excel檔案并決議POS結算資料進行業務和支付資料對賬,
根據個人開發經驗,嚴格來說,對賬應該劃歸到財務系統處理,但PowerDotNet的支付平臺認為支付Excel決議以及銀行、第三方支付、微信、銀聯、POS等的遠程查詢功能都應該由支付平臺來完成,
這樣做的最大好處是外部支付、退款、查詢等功能集中統一,否則財務系統也需要配置各種支付方式的應用Id、密鑰、證書等進行介面呼叫,通俗點講就是讓專業的人干專業的事情,保證系統“純潔性”,
財務對賬的主要目的是找出賬目金額不準、或者缺少入賬收支項、或者單號錯誤等等業務錯誤,通常對賬都由公司財務人員來完成,決議Excel或者直接呼叫查詢介面主要目標也是得到支付結果差異,
支付平臺會定時按照時間范圍或商戶進行支付和退款資料決議和比較,生成差異結果并持久化保存,當然還要開發查詢差異結果介面,供財務系統呼叫,雖然都是體力活,但系統邊界更清晰更易維護,
每到財務月結的時候,通常也是開發人員人心惶惶的時候,完善的支付平臺就應該有全面良好的所見即所得的對賬工具,讓時間寶貴的開發人員告別被大量Excel支配的恐懼,讓財務對賬更順利更輕松,

支付對賬功能能夠很直接迅速的發現業務資料問題,當然也大大減少支付、財務結算等業務人員對各種Excel技巧的依賴,否則天天人工處理Excel,一定會等到哪天系統和人都崩潰吧^_^
十、系統互動
支付平臺除了和銀行、第三方支付平臺、銀聯等外部渠道有直接的互聯互通的互動關系,也和很多內部業務系統保持互通關系,整理下個人開發和對接過的幾種常見互聯系統,
1、訂單系統
訂單系統需要支付平臺提供支付功能,支付平臺回呼支付結果給訂單系統,
支付平臺抽象出來的商戶,基本對應不同業務的訂單系統,訂單系統又可以根據來源終端的不同拆分為多種終端商戶,比如常見的按照PC、H5、APP、Pad等來源進行拆分,
2、風控系統
有支付則必有風控,沒有風控的支付平臺是不完整的,雖然銀行、第三方支付、銀聯等支付通道也有風控,但在自己的系統里提前風控預警更高效安全,
風控系統按照支付平臺的需要,可以按照配置策略動態組合風控到人、到信用卡、到訂單或者到支付金額,也可以按需進行黑白名單同步或異步處理,
風控系統還支持根據特殊業務需要自定義排列組合風控規則,分為扣款前和扣款后風控,或者退款前和退款后風控,或者預授權前和預授權后風控,或者凍結前和凍結后風控等,
但是風控系統在支付系統的角色只能是輔助,主要起到錦上添花的作用,不能喧賓奪主,所以需要風控要有更高的穩定性、準確性和性能,
保證風控的穩定性和準確性,需要收集并做大量的人員資料操作和日志分析,而性能要求通常都是對風控介面設定可控的超時時間,
3、CRM
支付的最終物件說到底是對人,所以支付系統和HCRM、PCRM及ECRM也有千絲萬縷的聯系,
比如用戶下單到支付平臺支付,支付平臺根據用戶Id或用戶名獲取PCRM用戶資訊;或者在HCRM人員管理系統中員工提交報銷申請單,財務系統審核后進行付款,這些都需要和支付平臺互動,
當然支付平臺和CRM的緊密程度,和CRM的設計有直接關系,后面有空介紹PCRM的時候還會說到和支付平臺的關系,
4、財務系統
嚴格來說,支付功能是財務系統的重要組成部分,支付和財務天生緊密聯系在一起,任何資金出入都需要在財務系統里進行記賬和對賬,當然這只是最表面淺顯的功能,
在B2B和B2C業務中,線上和線下交易,轉賬匯款現金支票POS刷卡交易也是應有盡有,支付系統抽象的好能夠讓財務系統記賬功能更加簡單可靠,
PowerDotNet公共服務中也包括財務系統,后續有慷訓寫出來介紹一下,
5、賬戶系統
常見賬戶系統主要管理用戶的虛擬貨幣賬戶或類虛擬貨幣賬戶,虛擬貨幣是簡化用戶支付功能,提升用戶體驗的常見方式,虛擬貨幣最重要的功能包括充值、提現、支付和退款,
對于支付平臺而言,我們完全可以把賬戶系統抽象理解為所在公司創建的支付方式,只不過這種支付方式除了支付和退款外,還有充值、提現等額外附帶的功能,
6、票券系統
票券系統和賬戶系統有相似之處,主要的不同包括票券通常不能直接充值和提現,不支持退款,票券的用途主要針對某些支付特征而設計,比如活動訂單、促銷訂單等等,
票券系統除了常見的優惠券、抵用券、折扣券等非支付可直接抵扣功能,還可以抽象成類虛擬貨幣的介面,提供給支付平臺進行凍結支付扣款,個人見識過某OTA的票券系統,復雜程度讓人嘆為觀止,
7、其他系統
其他如商品、活動等系統也和支付有些聯系,就不一一寫出來了,等我有空了,后續文章將重點圍繞支付平臺,介紹幾種個人深度開發過的和支付緊密聯系的公共服務平臺,
支付平臺可能和這么多的系統進行互動,如果設計實作不全面或者考慮不周到,很容易產生各種各樣的業務邏輯問題,最典型的如冪等性缺失導致的創建重復單據或多次扣減資料等,
對于像支付平臺這種型別的核心業務系統而言,正確性和穩定性是最重要最基礎的需求,無論用什么技術什么語言什么框架實作,架構設計和經驗都是重中之重,
PowerDotNet的支付平臺許多設計和實作已經在生產環境被證明非常穩定可靠正確且性能表現不俗,對各種各樣的業務邊界問題也進行了精密處理,真正做到了Expect the unexpected.
根據經驗和實踐,異步化和串行化通常會降低業務系統間處理的復雜度,對于大中型解耦充分的系統,訊息佇列基本是標配,PowerDotNet的支付平臺實作使用了大量異步化處理,
十一、全鏈路異步化
絕大多數支付場景都要求用戶體驗友好,低延遲高可用最快得到支付結果完成業務需求就是標配,在中小業務規模下這些業務指標并不難實作,很多公司都能做到,
在傳統同步思路下,低延遲的目標能夠較為輕易實作,可是對于高并發場景下,因為支付涉及的鏈路較長,大量的同步處理,伴隨著許多IO和網路消耗,會有明顯的性能問題,
雖然支付平臺主要介面都預留了同步或異步引數以適配特殊的業務場景,但是支付系統全鏈路異步化是一個系統工程,有時候不得不要求業務端配合改造邏輯以支持異步處理,
全鏈路異步化,訊息系統的高可用高性能設計至關重要,根據我的經驗,全鏈路異步化做的好的支付系統,能夠做到異步實作同步的效果,用戶幾乎完全感覺不到延遲,
如果基礎設施扎實穩定,技術儲備深厚,技術管理規范,訊息佇列就是最好的選擇;當然,如果資料量不大,也沒有必要一定用訊息佇列,資料庫加定時任務也能起到訊息佇列的效果,
PowerDotNet支持上述兩種訊息策略處理模式,在配置中心配置下開關即可,任何系統如果加入外部依賴,得到好處的同時也會加大復雜度和運維難度,要按照實際情況進行技術選型,
十二、互操作
支付平臺依賴很多外部SDK用于實作加解密、socket通信等功能,這些SDK的提供者可能包括公司內部的框架部門、公司外部的銀行、第三方支付機構、銀聯等,
對接這些SDK可能經常需要做如下處理:
1、注冊COM組件
regsvr32可以將 DLL檔案注冊為注冊表中的命令組件,通過regsvr32命令列注冊COM組件,可以將注冊后的dll直接添加參考至.NET專案中,這種方式開發和部署都比較直接方便,
語法:regsvr32 [/u] [/s] [/n] [/i[:cmdline]] <Dllname>
2、P/Invoke互操作
另一種是通過P/Invoke(Platform Invoke)實作從托管代碼直接呼叫Win32 API或其他一些非托管代碼,也就是互操作,
使用P/Invoke呼叫非托管代碼的前提和主要作業就是確保托管/非托管代碼之間正確的映射,包括:
(1)為使用的每個方法提供正確的宣告
(2)完成方法引數、回傳值的正確映射,包括基本型別、結構體、指標(函式指標)等
從代碼層面來說互操作性,就是DllImport特性的使用,參考示例:
public class CreditCardSDKEx { private const string DLLName = "CreditCardEx.dll"; [DllImport("kernel32")] public static extern int LoadLibrary(string strDllName); [DllImport("kernel32")] public static extern int GetLastError(); [DllImport(DLLName, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)] public static extern int Encrypt(string plainTxt, IntPtr lpVoid, ref string retStr); [DllImport(DLLName, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)] public static extern int Decrypt(string encryptTxt, IntPtr lpVoid, ref string retStr); }CreditCardEx
使用DllImport完成互操作,務必注意dll檔案路徑問題,尤其是Web應用程式,因為DllImport只能用字符常量,而不能使用Server.MapPath來確認物理絕對路徑,
DllImport查找依賴DLL檔案的順序是:先在程式當前目錄查找,找不到再到System32目錄查找,還找不到就到環境變數Path所設定路徑進行查找,
DllImport對托管DLL和非托管DLL處理還有些區別,整理如下:
(1)托管DLL,可直接添加參考到專案中
(2)托管DLL,通過DllImport間接使用,將托管DLL檔案拷貝至應用程式根目錄下,如果是web應用,拷貝至應用程式bin目錄下
(3)非托管DLL
在Asp.Net環境下,不論是WebForm還是MVC應用程式,非托管DLL 通過DllImport呼叫會有一個經典的路徑處理問題,這也是實踐得出的結果,
a、非Asp.Net應用程式,和托管DLL間接使用一樣,將非托管DLL檔案拷貝至應用程式根目錄下即可正常呼叫,
b、Asp.Net應用程式,不能直接參考到專案中,放到應用bin目錄下也不起作用,運行后會報錯:仍然找不到該dll,這是因為Asp.Net環境下,CLR會把托管檔案拷貝到一個臨時目錄下,然后在那里運行Web,這就是為什么把非托管DLL檔案放到bin目錄下仍然提示找不到該模塊的原因,
解決非托管DLL在web環境下的路徑問題方案有兩種:
(1)[DllImport("完整的絕對路徑")],這種最簡單,但是不推薦,對于多臺節點集群部署的應用來說,很容易埋坑,
(2)在服務器上新建一個目錄,假設是(C:\Payment\WinDLL\),接著在環境變數中給Path變數添加這個目錄,然后把非托管的DLL檔案都拷貝到該目錄下,最后[DllImport("dll名稱")]即可,
注意:上面兩種呼叫dll的方式,共同的缺點是會有兼容問題,發布應用程式的目標平臺可能需要從Any調整為X86和X64平臺,我自己已經不止一次在開發中遇到這種問題,
十三、其他
支付平臺的其他主要功能還包括:
1、支付補償和重試
針對支付寶、微信等的掃描、條碼、聲波等特殊支付方式,需要定時做補償和重試操作,借助定時任務調度平臺,這些都是沒有難度的體力活,寫寫介面配置下補償和重試job即可,
2、支付統計
從商戶或者扣退款支付單維度進行多樣性統計,財務系統對賬可以參考,財務系統有慷訓單獨寫一篇文章講講,

3、支付資料結轉與備份
自從用了DataX資料同步平臺,這一塊幾乎不用寫任何代碼了,咩哈哈,
4、敏感資料脫敏處理
支付資料太敏感,尤其是信用卡CVV2和卡號后四位這些,支付好以后爭取“閱后即焚”及時銷毀,不要讓人接觸到,
在資訊安全和個人資訊保護越來越重視的當今社會,安全性是合格的支付平臺必須要具備的基本特性,
5、銀行卡號處理
包括信用卡、儲蓄卡等卡號規則校驗,卡號黑白名單校驗,銀行卡號通過卡BIN自動獲取銀行名稱等,這些對于安全性和提升用戶體驗有很大幫助,
6、支付監控
根據實際業務和部署情況,抽象出支付業務正常指標,按需動態配置監控和預警引數,可進行短信、郵件、釘釘、微信等方式進行業務告警,
支付監控功能主要基于支付資料報表統計和定時結轉功能,定時任務調度平臺和DataX資料同步平臺真是幫了大忙,這也是我們要辛苦開發平臺基礎公共服務的原因,
7、支付介面安全
支付平臺所有資訊敏感的(尤其是和錢、余額、積分、資金、流水等相關的)介面必須經過嚴格的授權、鑒權、認證(校驗token)、驗簽等操作,當然這些都是服務治理平臺分內的事情,可以在服務治理平臺后臺管理系統點點按鈕輕松搞定,所謂工欲善其事必先利其器,此之謂也,
8、審計日志
支付資料的后臺人工變更必須有審計日志,對于支付財務這樣復雜的系統,因為業務需要,紅沖等后臺操作可能幾乎不可避免,所以必須做充足的審計準備,
作者:Jeff Wong
出處:http://jeffwongishandsome.cnblogs.com/
本文著作權歸作者和博客園共有,歡迎圍觀轉載,轉載時請您務必在文章明顯位置給出原文鏈接,謝謝您的合作,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/540483.html
標籤:其他
上一篇:高并發架構設計經驗總結
下一篇:高并發架構設計經驗總結
