小探網(wǎng)頁支付網(wǎng)關(guān)的架構(gòu)設(shè)計與體驗優(yōu)化——以某企業(yè)支付平臺為例

開題

現(xiàn)在網(wǎng)絡(luò)支付方式越來越發(fā)達(dá)而昨,已經(jīng)不可避免地開始與各類 IT 系統(tǒng)集成们何。在財務(wù)制度比較規(guī)范的地方态蒂,這類入賬自然需要統(tǒng)一管理,資金不能隨意流動辽社。如果由各個業(yè)務(wù)系統(tǒng)自己去申請對接網(wǎng)絡(luò)支付接口伟墙,自然是很難實現(xiàn)統(tǒng)一管理的,而且也麻煩滴铅。

因此戳葵,就需要一個統(tǒng)一的企業(yè)級支付平臺作為中間層,來負(fù)責(zé)各業(yè)務(wù)系統(tǒng)與網(wǎng)絡(luò)支付的對接汉匙。這樣拱烁,不僅方便了財務(wù)數(shù)據(jù)的統(tǒng)一提取、賬戶對賬噩翠,也使企業(yè)支付平臺可以代表所有的業(yè)務(wù)系統(tǒng)與網(wǎng)絡(luò)支付接口進(jìn)行交互戏自,業(yè)務(wù)系統(tǒng)不會接觸到企業(yè)的網(wǎng)絡(luò)支付總密鑰,較為安全可控伤锚。

這樣的例子其實我們天天見擅笔。例如 12306 的車票支付教育部考試中心的考試費支付屯援,都采用了中間層猛们,來接入多個網(wǎng)絡(luò)支付平臺。

此時狞洋,企業(yè)級支付平臺的角色可以認(rèn)為是一個代理弯淘,協(xié)助業(yè)務(wù)系統(tǒng)完成支付流,并保存相關(guān)數(shù)據(jù)吉懊。目前這類“代理”的架構(gòu)并沒有標(biāo)準(zhǔn)庐橙,所以實現(xiàn)起來會各有小差別假勿。如何去定義企業(yè)級支付平臺(下稱企業(yè)層)和業(yè)務(wù)系統(tǒng)各自的角色,就會決定架構(gòu)的實現(xiàn)方式态鳖,相應(yīng)就會影響到支付業(yè)務(wù)的實現(xiàn)情況转培。

WePay 的實現(xiàn)思路

下面介紹一款已經(jīng)在運行中的企業(yè)支付平臺 WePay,其目前向上對接了微信企業(yè)號的微信支付接口郁惜,遠(yuǎn)期規(guī)劃可加入其他網(wǎng)絡(luò)支付的支持堡距。

WePay 會給每個業(yè)務(wù)系統(tǒng)分配一個“子商戶”,對應(yīng)會有 ID 和密鑰兆蕉,也就意味著業(yè)務(wù)系統(tǒng)通過 WePay 實現(xiàn)的子商戶進(jìn)行支付請求羽戒,WePay 自己處理網(wǎng)絡(luò)支付接口的密鑰,應(yīng)用系統(tǒng)只能借助 WePay 獲取網(wǎng)絡(luò)支付的結(jié)果信息虎韵。

WePay 當(dāng)前的架構(gòu)和支付流程

上圖的流程目前其實工作得非常好易稠。應(yīng)用系統(tǒng)需要完成的工作很簡單,生成應(yīng)用端的訂單信息并保存訂單號包蓝,然后把訂單信息一股腦前臺 POST 給 WePay驶社,WePay 的網(wǎng)頁會幫應(yīng)用系統(tǒng)實現(xiàn)支付過程,應(yīng)用系統(tǒng)只管收支付結(jié)果就可以了测萎。

在這里亡电,WePay 的角色并不只是“代理”那么簡單了,因為要幫應(yīng)用系統(tǒng)實現(xiàn)支付流程硅瞧,所以中間還得控制支付過程份乒。我就暫且叫它做“富代理”吧。

為了更好地說明純粹的“代理”是個什么情況腕唧,我假設(shè)了新的流程或辖。這里業(yè)務(wù)系統(tǒng)會把 WePay 當(dāng)作是網(wǎng)絡(luò)支付的服務(wù)器,所以業(yè)務(wù)系統(tǒng)傳給 WePay 的 ID 可以是自編號的子商戶枣接,WePay 把請求遞交給網(wǎng)絡(luò)支付的時候再用上網(wǎng)絡(luò)支付統(tǒng)一的密鑰颂暇。

WePay 如果變成一個純粹的代理,會變成這個流程

代理與否但惶,利弊明顯耳鸯。實際上現(xiàn)在基本上都是“富代理”的解決方案。

  • 純代理
    • 業(yè)務(wù)系統(tǒng)需要自己處理支付過程(圖中榆骚,瀏覽器端中間的藍(lán)棧頁面均由應(yīng)用服務(wù)器實現(xiàn))片拍;
    • 不同系統(tǒng)的技術(shù)良莠不齊,支付過程的體驗和安全性會有差別妓肢,不利于企業(yè)對支付過程進(jìn)行標(biāo)準(zhǔn)化;
    • 但如果業(yè)務(wù)系統(tǒng)已經(jīng)做了現(xiàn)有的網(wǎng)絡(luò)支付對接(目前網(wǎng)絡(luò)支付有大量的 SDK)苫纤,技術(shù)上碉钠,純代理模式下業(yè)務(wù)系統(tǒng)會更容易接入企業(yè)層系統(tǒng)纲缓。
  • 富代理
    • 支付過程由 WePay 實現(xiàn)(圖中,瀏覽器端中間的藍(lán)棧頁面均由 WePay 實現(xiàn))喊废;
    • 如果應(yīng)用是從頭開發(fā)的祝高,接入的工作量就會比直接接入網(wǎng)絡(luò)支付少(即便人家有 SDK 了還得自己實現(xiàn)前端呢);
    • 支付過程均由企業(yè)層實現(xiàn)污筷,用戶體驗和安全性可以由企業(yè)層的統(tǒng)一實現(xiàn)來保證工闺。

“富代理”角色可以多做這點判斷

企業(yè)層需要做的事情多了,這樣的角色定位下瓣蛀,每單支付業(yè)務(wù)系統(tǒng)該給企業(yè)層傳多少參數(shù)呢陆蟆?

根據(jù)內(nèi)部公開資料得知,目前業(yè)務(wù)系統(tǒng)在創(chuàng)建支付訂單時惋增,需要傳以下這些參數(shù)給這款 WePay 系統(tǒng)叠殷。我做了下分類:

  • 請求身份和請求校驗
    • spbillCreateIp 發(fā)起訂單的 IP
    • tenant 租戶代碼(由 WePay 分配)
    • timestamp 訂單生成的時間戳
    • sign 所有參數(shù)加上密鑰后的簽名值
  • 訂單內(nèi)容(必須)
    • tradeType 交易類型
    • totalFee 支付金額(單位為分)
    • tenantTradeNumber 租戶訂單號(業(yè)務(wù)系統(tǒng)內(nèi)部唯一)
    • redirectUrl 前端跳轉(zhuǎn)確認(rèn)地址
  • 訂單內(nèi)容(增強)
    • productBody, productDetail 交易內(nèi)容和詳情
    • tenantUserCode, tenantUserName 企業(yè)應(yīng)用中用戶的用戶名、姓名

實際上這一整套接口的參數(shù)內(nèi)容诈皿,多是直接借鑒微信支付的參數(shù)來著的林束,反正就是轉(zhuǎn)發(fā)參數(shù),用現(xiàn)成的參數(shù)名也沒啥問題稽亏。

但注意到 tradeType 這個參數(shù)了嗎壶冒?實際上這個參數(shù)是微信支付用的。微信那邊目前支持的值有 JSAPI(微信內(nèi)瀏覽器)截歉、NATIVE(用戶掃碼付款)胖腾、APP(手機應(yīng)用)、MWEB(微信外手機瀏覽器)怎披、MICROPAY*(商戶條碼付款)胸嘁,而 WePay 實現(xiàn)了 JSAPINATIVE,根據(jù)業(yè)務(wù)系統(tǒng)發(fā)的參數(shù)來返回給瀏覽器不同的界面凉逛。

那么性宏,這個參數(shù)真的要靠業(yè)務(wù)系統(tǒng)來給定嗎?

  • 大多數(shù)情況下状飞,業(yè)務(wù)系統(tǒng)需要根據(jù)客戶端來提供不同的界面來適配毫胜,比如根據(jù) UA 有沒有 micromessenger,判斷提供 PC 版還是微信版诬辈。業(yè)務(wù)系統(tǒng)很多時候似乎知道客戶端屬性了酵使,讓業(yè)務(wù)系統(tǒng)來指定這個類型,下不同的單焙糟,似乎順理成章口渔。
  • 然而,當(dāng)今的網(wǎng)頁技術(shù)早已可以實現(xiàn)一套前端模板穿撮,通吃 PC 移動(Bootstrap 框架 推了很多不會寫響應(yīng)式設(shè)計的人一把)缺脉。因此痪欲,有的業(yè)務(wù)系統(tǒng)根本沒必要去判斷客戶端是不是微信(而提供不同的界面)。這時候讓業(yè)務(wù)系統(tǒng)來下單攻礼,業(yè)務(wù)系統(tǒng)肯定下一個 PC 版的單了业踢,除非非常考究礁扮,才會特意適配一下微信知举。
  • 此外前文提到,企業(yè)層在支付流程中太伊,會協(xié)助應(yīng)用系統(tǒng)實現(xiàn)面向用戶的支付交互流程(前端)雇锡。而顯然,JSAPI倦畅、NATIVE遮糖、MWEB 這三種模式,只是觸發(fā)支付的方式不同叠赐,并不會影響到支付業(yè)務(wù)的核心內(nèi)容和最終結(jié)果欲账。這種情況下,顯然沒有必要讓應(yīng)用去選擇下單模式芭概,而應(yīng)該讓企業(yè)層來統(tǒng)一判斷赛不,從而繼續(xù)降低業(yè)務(wù)系統(tǒng)的集成難度。
    • JSAPI創(chuàng)建訂單的時候需要 OPENID罢洲,可能有的業(yè)務(wù)會靠這個參數(shù)來限制只能某人支付這一訂單踢故。實際上這個需求并非必要,很多時候反而會造成業(yè)務(wù)規(guī)則不統(tǒng)一(支付頁面如果可以分享惹苗,會導(dǎo)致 OPENID 不同而支付失數罱稀;不限制的話桩蓉,雖然可能會有退款退不到賬戶本人的問題淋纲,但很多業(yè)務(wù)直接上 NATIVE 模式,誰掃碼都行院究,完全沒考慮這一點)洽瞬,確實有業(yè)務(wù)需要的話也可以保留,就是 WePay 多判斷一下而已业汰。
  • 更重要的是伙窃,這三種模式是高度與特定的網(wǎng)絡(luò)支付端口耦合的。如果日后需要接入其它的網(wǎng)絡(luò)支付样漆,較好的辦法是業(yè)務(wù)系統(tǒng)不用管網(wǎng)絡(luò)支付端口的具體的支付模式參數(shù)为障,而靠 WePay 去給用戶選擇,否則業(yè)務(wù)系統(tǒng)全得再改一遍,多沒意思产场。

結(jié)論就是鹅髓,這個 tradeType 應(yīng)當(dāng)做一下整合舞竿。鑒于JSAPI京景、NATIVEMWEB 這三種模式本質(zhì)上都是網(wǎng)頁支付骗奖,可以在 WePay 端整合為一個名字(如 HTML)确徙,再由 WePay 進(jìn)行選擇,而不應(yīng)該讓業(yè)務(wù)系統(tǒng)來選执桌。如果業(yè)務(wù)系統(tǒng)還發(fā)了這三個串進(jìn)來鄙皇,就統(tǒng)一定向到新的 HTML 模式就好。至于 APPMICROPAY仰挣,現(xiàn)在這個系統(tǒng)似乎沒有用到伴逸,這些方式就預(yù)留著空位就好。

支付中間層如何判斷支付模式膘壶?

既然提出了這個解決方案错蝴,自然也得考慮,沒有業(yè)務(wù)系統(tǒng)的任何數(shù)據(jù)颓芭,支付層能不能高效率地自行判斷支付模式呢顷锰?當(dāng)然是可以的。

支付中間層最麻煩的事情亡问,莫過于在開始讓用戶支付前官紫,就得先跟網(wǎng)絡(luò)支付開好訂單。而開訂單的時候州藕,就必須決定具體的支付模式束世。

有種穩(wěn)妥的方法,就是通過前端來檢查微信的 JSAPI 能不能用床玻、有沒有手機(微信)毁涉,再來按需異步開訂單。不過這樣當(dāng)然太麻煩了笨枯,所以靠粗暴的后端 User Agent 檢查薪丁,就可以實現(xiàn)絕大多數(shù)情況下的正確及時判斷了。

所以是:

  • UA 判斷是否包含了 micromessenger馅精,是的話严嗜,默認(rèn)在微信環(huán)境下,開 JSAPI 訂單
    • 調(diào) JSAPI 需要獲取 OPENID洲敢,企業(yè)號的接口無論微信用戶是否有關(guān)注企業(yè)號漫玄,都會返回一個 OPENID,而且鑒于支付是低頻操作,這個時候讓
      WePay 跳一次 OAuth 其實也并不太影響響應(yīng)時間(OAuth 有兩種方案睦优,一種是 WePay 自己跟微信拿數(shù)據(jù)然后 Cookie 緩存渗常,另一種是跟企業(yè)號應(yīng)用主域名拿數(shù)據(jù),由于企業(yè)號域名通常用戶都有登陸汗盘,都帶 Cookie皱碘,可能可以節(jié)省 OAuth 的開銷)
  • 其他情況全部走 NATIVE 訂單;或者隐孽,如果有閑心兼容下 MWEB(手機瀏覽器在這個模式下可以直接拉起微信癌椿,體驗會更好),就再 UA 判斷是否包含 Android 或 iPhone / iPad 串菱阵,有的話就進(jìn) MWEB踢俄,沒有就進(jìn) NATIVE 掃碼去
  • 要做到 100% 靠譜,就得考慮在 WePay 端提供切換模式的功能了晴及,不過一切換模式都办,就得關(guān)閉訂單,還得重新生成訂單號給網(wǎng)絡(luò)支付用虑稼,是挺煩的琳钉,所以沒必要做

EOF

說明:本文資料均來自公網(wǎng)公開資料,圖是自己用這個畫的动雹,并沒有透露什么機密槽卫。終于可以安心學(xué)習(xí)了 = =

本文采用知識共享“署名-非商業(yè)性使用 4.0”許可協(xié)議授權(quán),如需額外授權(quán)請與本人聯(lián)系胰蝠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末歼培,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茸塞,更是在濱河造成了極大的恐慌躲庄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钾虐,死亡現(xiàn)場離奇詭異噪窘,居然都是意外死亡,警方通過查閱死者的電腦和手機效扫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門倔监,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人菌仁,你說我怎么就攤上這事浩习。” “怎么了济丘?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵谱秽,是天一觀的道長洽蛀。 經(jīng)常有香客問我,道長疟赊,這世上最難降的妖魔是什么郊供? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮近哟,結(jié)果婚禮上驮审,老公的妹妹穿的比我還像新娘。我一直安慰自己椅挣,他們只是感情好头岔,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鼠证,像睡著了一般。 火紅的嫁衣襯著肌膚如雪靠抑。 梳的紋絲不亂的頭發(fā)上量九,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音颂碧,去河邊找鬼荠列。 笑死,一個胖子當(dāng)著我的面吹牛载城,可吹牛的內(nèi)容都是我干的肌似。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诉瓦,長吁一口氣:“原來是場噩夢啊……” “哼川队!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睬澡,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤固额,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后煞聪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斗躏,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年昔脯,在試婚紗的時候發(fā)現(xiàn)自己被綠了啄糙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡云稚,死狀恐怖隧饼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碱鳞,我是刑警寧澤桑李,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響贵白,放射性物質(zhì)發(fā)生泄漏率拒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一禁荒、第九天 我趴在偏房一處隱蔽的房頂上張望猬膨。 院中可真熱鬧,春花似錦呛伴、人聲如沸勃痴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沛申。三九已至,卻和暖如春姐军,著一層夾襖步出監(jiān)牢的瞬間铁材,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工奕锌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留著觉,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓惊暴,卻偏偏與公主長得像饼丘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子辽话,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容