支付通pos機(jī)交易明細(xì)查詢,基于有限狀態(tài)機(jī)與消息隊列的三方支付系統(tǒng)補(bǔ)單實(shí)踐

 新聞資訊  |   2023-04-23 12:42  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于支付通pos機(jī)交易明細(xì)查詢,基于有限狀態(tài)機(jī)與消息隊列的三方支付系統(tǒng)補(bǔ)單實(shí)踐的知識,也有很多人為大家解答關(guān)于支付通pos機(jī)交易明細(xì)查詢的問題,今天pos機(jī)之家(m.afbey.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、支付通pos機(jī)交易明細(xì)查詢

支付通pos機(jī)交易明細(xì)查詢

0.引言

在日常生活中,從線下的超市購物到線上的外賣點(diǎn)餐、電商網(wǎng)購等,支付無時無刻不在發(fā)生,不論是通過現(xiàn)金、pos 機(jī)刷卡還是微信支付寶等第三方支付。線上支付有著及時便捷一氣呵成的極致體驗,當(dāng)然也有少數(shù)的時候體驗不夠絲滑,比如早期我們在 PC 版 12306 買火車票,當(dāng)支付完成后,訂單的支付狀態(tài)卻經(jīng)常不能及時更新,會有一段時間的延遲,有時甚至?xí)却荛L時間處在未支付狀態(tài)。

在支付的過程中由于各種各樣的原因(比如外部渠道處理出了問題,異步回調(diào)遲遲不來)導(dǎo)致流程走了一半停了下來,用戶看到訂單依然是未支付狀態(tài),會不知所措,此時就需要一種機(jī)制來推動完成這筆交易。本文就以三方支付系統(tǒng)中的補(bǔ)單機(jī)制為例,來介紹一種較為通用的單據(jù)補(bǔ)償模式。

1.三方支付系統(tǒng)簡介1.1 什么是三方支付

所謂第三方支付,就是和各大銀行簽約,獨(dú)立于商戶和銀行,具備一定實(shí)力和信譽(yù)保障的,為商戶與消費(fèi)者提供支付結(jié)算服務(wù)的第三方獨(dú)立機(jī)構(gòu)。它是處于買方和賣方之間具備公信力的第三方,承擔(dān)擔(dān)保人和資金托管人的角色。三方支付也可以稱為虛擬賬戶支付,由消費(fèi)者在第三方支付機(jī)構(gòu)開設(shè)虛擬賬戶,并用虛擬賬戶中的資金進(jìn)行支付。業(yè)界常見的三方支付有支付寶、微信支付、美團(tuán)支付、京東支付等等。

1.2 三方支付中的交易&支付系統(tǒng)

交易是什么,最直觀的描述就是“一手交錢、一手交貨” ,交易會使買賣雙方形成債權(quán)和債務(wù)關(guān)系。交易的存在是支付發(fā)生的前提,用戶通過使用某種支付方式去完成交易。交易是支付流程的驅(qū)動者,根據(jù)具體場景組合不同的支付指令,來完成交易資金的轉(zhuǎn)移。

支付是交易處理資金流的工具,目的是清償債權(quán)和債務(wù)關(guān)系;支持多種支付方式(如銀行卡支付、余額支付、優(yōu)惠券組合支付、類似花唄的信用支付等),負(fù)責(zé)對接賬務(wù)、會計、計費(fèi)系統(tǒng)等資金處理能力,接收支付指令,驅(qū)動完成資金交換。將實(shí)際的支付行為(實(shí)際資金)與內(nèi)部的記賬(虛擬資金)相結(jié)合,保證虛實(shí)一致。

三方支付整體業(yè)務(wù)架構(gòu)如圖 1 所示,其中交易核心與支付核心在業(yè)務(wù)劃分上處于"收單支付域",具備普通交易的收款、付款、退款及充值、轉(zhuǎn)賬與提現(xiàn)等常見功能,還包括了支撐電商業(yè)務(wù)的合單支付、擔(dān)保與分賬的能力。其中交易與支付核心都有一個異常查補(bǔ)模塊,它囊括了所有業(yè)務(wù)的補(bǔ)償流程,也是本文主要介紹的部分。

圖 1. 三方支付業(yè)務(wù)架構(gòu)

2.什么是補(bǔ)單&為什么需要補(bǔ)單

一筆交易在支付過程中由于鏈路中的各種異常而中斷,此時的交易處在一種中間狀態(tài),這種情況俗稱"卡單",即卡在那里不動了,沒有繼續(xù)向下推進(jìn)。還有一種情形,支付核心向渠道發(fā)起了扣款,渠道受理后,銀行卡扣款成功,但由于種種原因沒有向支付核心發(fā)起回調(diào),導(dǎo)致這筆支付沒有完成,用戶沒有享受到相應(yīng)權(quán)益,但銀行卡的錢已經(jīng)扣了,這種情況稱為“掉單”。

不管是卡單還是掉單,都是處在中間態(tài)的訂單。補(bǔ)單就是將處在中間態(tài)的訂單進(jìn)行補(bǔ)償,直到推進(jìn)到終態(tài)(成功或失?。?/strong>。補(bǔ)單一般有兩個關(guān)鍵點(diǎn),一個是補(bǔ)償?shù)挠行?,極端情況下可能補(bǔ)償多次都不成功,不能就此放棄了,需要有兜底的機(jī)制;另一個是補(bǔ)償?shù)募皶r性,因為交易掛起的時間越長,用戶的體驗越差。

交易核心和支付核心的補(bǔ)單相得益彰,具有一定相似程度的設(shè)計與實(shí)現(xiàn),我們就以支付核心的補(bǔ)單為例介紹下異常補(bǔ)單機(jī)制。

3.補(bǔ)單是如何實(shí)現(xiàn)的

本章首先了解一下業(yè)務(wù)流程,說明一下實(shí)現(xiàn)補(bǔ)單需要的前提基礎(chǔ),然后介紹一下補(bǔ)單機(jī)制的演進(jìn)路線,每個版本存在的問題以及在下一個版本是如何解決的。

3.1 有限狀態(tài)機(jī)與冪等性標(biāo)識資金操作的有限狀態(tài)機(jī)

我們首先以用戶發(fā)起一筆余額提現(xiàn)為例,說明下業(yè)務(wù)流程,簡化后如圖 2 所示。

圖 2. 余額提現(xiàn)流程

首先生成支付訂單,然后請求賬務(wù)系統(tǒng),扣減用戶賬戶下的余額,接著向外部渠道發(fā)起付款操作,資金操作完成后統(tǒng)一處理結(jié)果并更新單據(jù)信息,最后還有一些對上下游的異步通知,形式上包括消息和 RPC 回調(diào)。

我們將每個關(guān)鍵資金操作的狀態(tài)記錄落庫,如下表所示。其中出款即錢從哪里來,入款即錢到哪里去,沖正即回滾交易。在提現(xiàn)場景下就是從用戶支付賬戶出錢,到用戶的銀行卡去。其他場景比如充值(銀行卡->用戶支付賬戶),會有不同的資金流向。表中最后兩行加粗的場景還沒有達(dá)到終態(tài),是我們需要去補(bǔ)償?shù)摹?/p>

為了便于理解,我們在這里省略了沖正的相關(guān)操作,一次余額提現(xiàn)流程的狀態(tài)機(jī)轉(zhuǎn)換如圖 3 所示。

圖 3.附帶狀態(tài)機(jī)轉(zhuǎn)換的余額提現(xiàn)流程

可重入與冪等性保證

發(fā)起一次支付會涉及到多個系統(tǒng)間調(diào)用,由于網(wǎng)絡(luò)原因?qū)е碌耐ㄐ懦瑫r是常見的問題。同時上游系統(tǒng)也可能會重新發(fā)起請求,這需要我們的系統(tǒng)保證操作結(jié)果的冪等性。少數(shù)用戶也可能會有多個終端同時操作帶來的并發(fā)請求,需要我們保證接口的可重入性。除了服務(wù)自身,我們的下游依賴同樣也需要保證其接口具有同樣的能力。

先說一說什么是可重入與冪等性。

可重入:在并發(fā)請求下可以保證正確性。冪等性:重復(fù)多次相同的輸入,獲得相同的輸出。冪等性在技術(shù)上其實(shí)也包含了可重入的要求。

具體到業(yè)務(wù)中,冪等性是針對一筆已經(jīng)到達(dá)終態(tài)的支付而言的,對于初次未能拿到最終業(yè)務(wù)結(jié)果的請求,再次發(fā)起調(diào)用的結(jié)果可以是不同的(處理中->處理成功或失?。?。那么我們?nèi)绾伪WC業(yè)務(wù)流程的可重入與冪等性呢?我們分別拆解每一步來看:

生成支付單:首先支付單據(jù)可以將業(yè)務(wù)方傳遞的可保證唯一性的外部訂單號作為唯一索引,插入數(shù)據(jù)庫時若發(fā)生唯一索引沖突,則將查詢已有數(shù)據(jù)進(jìn)行冪等參數(shù)校驗,若與當(dāng)次請求的參數(shù)完全一致說明是重復(fù)請求,可使用 DB 中的支付單繼續(xù)推進(jìn)后續(xù)流程;若不一致則返回錯誤。資金處理流程:賬戶和渠道系統(tǒng)各自保證其接口冪等性。我們也維護(hù)了每個下游操作的狀態(tài),根據(jù)狀態(tài)機(jī)決定是否要繼續(xù)推進(jìn),盡量不向下游輸出重復(fù)流量。比如支付單已經(jīng)完成了所有資金處理,狀態(tài)機(jī)已經(jīng)是終態(tài),那么接口可以直接返回相應(yīng)結(jié)果。更新支付單信息,先將支付單加行級排他鎖,再進(jìn)行更新,保證多個并發(fā)請求只會有一個成功。異步通知,在支付單推進(jìn)到終態(tài)后進(jìn)行。

有了可重入與冪等性保證,我們就可以大量地復(fù)用正向流程來實(shí)現(xiàn)補(bǔ)單接口。

3.2 初始版

一般來說最常見的補(bǔ)單形式是設(shè)置一個定時任務(wù),定時去掃表完成業(yè)務(wù)補(bǔ)償,實(shí)現(xiàn)比較簡單,但是及時性不夠,對于收款轉(zhuǎn)賬類的交易而言用戶體驗不佳。我們采用了通過消息隊列進(jìn)行即時補(bǔ)償?shù)姆绞?,如圖 4 所示。補(bǔ)償消費(fèi)者并沒有去做補(bǔ)償工作,而是解析消息然后通過 RPC 調(diào)用支付核心暴露的補(bǔ)償接口。為什么不在消費(fèi)者中直接補(bǔ)償?這么做主要是考慮將邏輯收斂到一處便于維護(hù)。

圖 4. 余額提現(xiàn)發(fā)生異常時的補(bǔ)單流程

當(dāng)然,補(bǔ)單可能依然失敗,我們可以再次發(fā)送補(bǔ)償消息。但不能一直這樣循環(huán)下去,所以需要設(shè)置一個最大重試次數(shù),超出后不再發(fā)送。當(dāng)補(bǔ)償多次都不成功時,一般是下游系統(tǒng)出了問題,這時我們需要放緩補(bǔ)償?shù)念l次,隨著重試次數(shù)增加,會讓每次補(bǔ)償時間間隔逐漸增大,通過 RocketMQ 的延時消息實(shí)現(xiàn)。

這里有三個很容易想到的問題:

如果異常消息發(fā)送失敗,上游也沒有重試機(jī)制,這筆訂單就可能一直掛在這里不了了之了,如圖 5 所示。補(bǔ)償消費(fèi)者請求支付核心補(bǔ)單時不成功,可能是超時但實(shí)際補(bǔ)償成功了,或者是請求壓根沒有過去,如圖 6 所示。如果重試達(dá)到最大次數(shù)依然沒有成功,這筆單子該怎么處理。

圖 5. 補(bǔ)償消息發(fā)送失敗

圖 6. 補(bǔ)償消息消費(fèi)失敗

3.3 改進(jìn)版

針對問題 1,如果重試依然發(fā)送失敗,我們通過引入一張異常消息表,將發(fā)送失敗的消息落庫來解決。表中記錄了訂單號、當(dāng)前的重試次數(shù)、異常分類、記錄狀態(tài)、消息體等字段。如果圖 6 中的第 4 步消息發(fā)送失敗,就將這筆訂單放入 DB 中的一張異常表中,會設(shè)置一個定時任務(wù)去處理。以目前 RocketMQ 的可用性來說,異常數(shù)據(jù)很少會出現(xiàn)。如圖 7 所示。

圖 7. 針對消息生產(chǎn)/消費(fèi)異常的改進(jìn)版 - 1

對于第 2 個問題,如果補(bǔ)償消費(fèi)者調(diào)用支付核心失敗,補(bǔ)償消費(fèi)者 HandleMessage 會向上層拋出 error,利用 RocketMQ 的梯度重試機(jī)制,當(dāng)消費(fèi)重試次數(shù)達(dá)到一定上限后會進(jìn)入死信隊列。如圖 8 所示,這種情況一般是服務(wù)或網(wǎng)絡(luò)出了問題,待恢復(fù)之后,可以從死信隊列拉取這些消息再統(tǒng)一處理。

圖 8. 針對消息生產(chǎn)/消費(fèi)異常的改進(jìn)版 - 2

當(dāng)然還有更極端的情況,請求 MQ 和 DB 都失敗了咋辦?以目前 MQ 和 DB 的可用性來說,同時失敗這種基本可以不用考慮,報警人工介入即可。

針對問題 3,如果重試超過最大次數(shù),依然補(bǔ)償不成功,一般是下游依賴出了問題。這種情況我們也將它放進(jìn)異常表中。

對于這兩類漏網(wǎng)之魚,需要支持單條/批量支付單補(bǔ)償?shù)倪\(yùn)營能力以供人工介入;最好有一個在業(yè)務(wù)低峰期運(yùn)行的兜底任務(wù),掃描業(yè)務(wù)單據(jù)表,將一段時間內(nèi)還未完成的訂單進(jìn)行補(bǔ)償。

另外,兜底任務(wù)可能造成消息的短暫堆積,影響線上的實(shí)時補(bǔ)償流程推進(jìn),對此可以使用獨(dú)立的隊列隔離開來。

3.4 最終版

其實(shí)如果只是異步通知類的操作出現(xiàn)了異常,并沒有必要每次都重新走一遍完整業(yè)務(wù)流程,缺啥補(bǔ)啥即可。因此我們將異常劃分為多種類型,將一些異步操作和業(yè)務(wù)處理劃分開來,進(jìn)行精細(xì)化的處理:

通知下游的 MQ 失敗,就將這個消息體重發(fā)一次即可;通知交易的回調(diào) RPC 失敗,可將 RPC 請求序列化到消息體中,補(bǔ)償時通過反序列化消息體中的 RPC 請求,直接再發(fā)起一次 RPC 即可;對于更新 DB 失敗,將更新參數(shù)序列化到消息體中,補(bǔ)單時再次發(fā)起一次更新;如果在業(yè)務(wù)處理時遇到了異常情況,需要再走一遍業(yè)務(wù)補(bǔ)償;

圖 9 以這幾種異常為例,說明了每種補(bǔ)償類型的消息參數(shù)。

圖 9. 分類補(bǔ)償

我們最終的補(bǔ)單體系見圖 10,它既通過即時消息保證了補(bǔ)償?shù)募皶r性,是主動出擊之茅;也利用延時消息重試、落地失敗消息的異常表與兜底任務(wù)保證了補(bǔ)償?shù)挠行?,是萬無一失之盾。不僅可用于支付單據(jù)的補(bǔ)償,通過保證流程的可重入性,也可作為一種通用解決方案,但不適用于無狀態(tài)、不可重入的業(yè)務(wù)形態(tài)。

圖 10. 異常補(bǔ)償體系

4.總結(jié)

本文首先介紹了什么是補(bǔ)單,接著基于三方支付系統(tǒng)的實(shí)現(xiàn)完整闡述了補(bǔ)單機(jī)制的演進(jìn)過程,最終演化為一種相對通用的異常處理模式,即基于消息隊列、有限狀態(tài)機(jī)與多重任務(wù)兜底的業(yè)務(wù)層最終一致性保障機(jī)制,供大家參考指正。

更多分享

UME - 豐富的Flutter調(diào)試工具

一例 Go 編譯器代碼優(yōu)化 bug 定位和修復(fù)解析

字節(jié)跳動破局聯(lián)邦學(xué)習(xí):開源Fedlearner框架,廣告投放增效209%

抖音品質(zhì)建設(shè) - iOS啟動優(yōu)化《原理篇》

歡迎關(guān)注「 字節(jié)跳動技術(shù)團(tuán)隊 」

簡歷投遞聯(lián)系郵箱「 tech@bytedance.com 」

以上就是關(guān)于支付通pos機(jī)交易明細(xì)查詢,基于有限狀態(tài)機(jī)與消息隊列的三方支付系統(tǒng)補(bǔ)單實(shí)踐的知識,后面我們會繼續(xù)為大家整理關(guān)于支付通pos機(jī)交易明細(xì)查詢的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://m.afbey.com/news/28708.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實(shí),本站將立刻刪除。