部分和完整refands
TL;DR
Refand是取回和的逆運算。完全關閉事務整體,部分返回部分(可能是部分到完整系列)。至關重要的是:從源頭到源頭,嚴格的冪等性,原因日誌以及與網絡包/撤退的編排。我們測量Refund Rate,TtR p95,Refund Error,並通過自動對賬消除雙打/不匹配。
1)術語和原則差異
Full Refund-返回所有已記錄的金額('refund_amount=capture_amount')。
Partial Refund-返回部分('0 <refund_amount <capture_amount'),允許其余部分到總計「capture_amount」。
回收來源-退回原始支付方法/軌道(監管優先級/強制性)。
Void-取消捕獲(如果受導軌支撐),不被視為重構。
Reversal/Chargeback-主動性之外的銀行/鐵路機械師(爭議、充電器)-不要與重構混淆。
2)何時發出完整的vs部分
完整(完整):- 取消整個訂單/服務,重復註銷,系統錯誤。
- 在提供服務失敗時具有約束力(根據消費者/監管機構的規則)。
- 部分取消服務,按比例調整(折扣,延遲補償)。
- 導軌技術限制(每次操作的最大金額)是零件系列。
- 事後扣留傭金(在監管上允許)在iGaming中較少見。
3)政策與限制
Refund-to-source=默認為true;例外-通過MLRO/合規案例(已定義)。
切斷:自捕獲以來的N天允許反射(通過方法/管轄權)。
Max Partial Count:在支付上不超過K partial(典型的K ≤ 5)。
Min Partial Amount: 不低於鐵路/PSP的技術最低限度。
Approval Matrix:
劄幌代理:partial ≤ X, full ≤ Y。
經理/財務:超過限額,跨方法例外。
冷靜地進行反復嘗試(反演練)。
4)體系結構和事件流
組件:- Payment Orchestrator是狀態真理的來源。
- Refund Service-API,冪等,Retrais編排,日誌。
- PSP適配器-方法集成。
- Reconciliation-自動對賬,DLQ和校正。
- Ledger/Accounting-接線,代數,清算對齊。
- 風險/合規性-在有爭議的情況下進行制裁/SoF檢查。
1. `Refund.Create '(API) →驗證(限制、殘差、策略、KYC/SoF(如有必要)。
2.Генерация idempotency_key (`hash(payment_id + refund_amount + reason + nonce)`).
3.PSP呼叫→ 「PENDING」狀態。
4.Webhook/polling → 「SUCCESS」/「FAILED」;超時-使用相同鍵的轉發。
5.該活動的發布在Kafka → Ledger,BI,Alerta。
6.自動對賬:將「provider_refund_id」映射到註冊表。
5)相同性和反雙打
相同的重構不能歸功於兩次:所有邏輯都通過idempotency storage (KV/Redis+TTL)。
payment_id × amount × reason上的密鑰(以及必要時的「partial_index」)。
Retrai使用相同的密鑰。
並行分區在總和的aggregate上受到row-level locks/optimistic版本的保護。
python def refund(payment_id, amount, reason, idem_key):
if idem_store. exists(idem_key): return idem_store. get(idem_key)
with tx():
p = db. get_payment(payment_id, for_update=True)
assert p. captured_amount - p. refunded_amount >= amount > 0 r = p. create_refund(amount, reason, status='PENDING', idem_key=idem_key)
resp = psp. refund(p. provider_txid, amount, idem_key)
return finalize(r, resp. status, resp. ext_id)
6)數據模型(最低限度)
json
{
"payment_id": "pay_123",
"captured_amount": 150. 00,
"currency": "EUR",
"refunded_amount": 40. 00,
"refunds": [
{
"refund_id": "rf_001",
"type": "partial full",
"amount": 20. 00,
"reason_code": "PARTIAL_SERVICE",
"idempotency_key": "idem_a1",
"status": "PENDING SUCCESS FAILED",
"provider_refund_id": "psp_rf_9xz",
"created_at": "2025-11-03T12:00:00Z",
"credited_at": "2025-11-03T15:05:00Z",
"notes": "ticket #456"
}
],
"flags": {
"refund_to_source": true,
"jurisdiction": "EEA",
"kyc_tier_required": "tier2"
}
}
7)支付軌道功能
卡(Visa/萬事達卡)
支持full/partial;通常有幾個部分;TtR取決於客戶的銀行(T+1…… T+5 b.d.)。
成功的Webhooks來得很快,但是出院的入學人數可能會滯後→我們在劄幌模板中解釋。
A2A/Open Banking/RTP
通常是即時回報(反向/信用推動);一些提供商僅支持全部或1個部分。
嚴格綁定到源帳戶;refund-to-source是必需的。
電子錢包
普通的全部/部分;TtR分鐘;部分數量和最低金額的限制。
憑證/預付款
通常,背包到源不可用→策略:退回到內部錢包或重置憑證(如果提供者知道如何)。要求遵守條款。
Crypto
鐵軌-波動;優選不用作重新設計方法。如果允許:返回具有記錄的匯率和傭金的同一地址/交易所;AML篩選。
8)會計,對賬和財務
Ledger:捕獲時的「DR Revenue/CR Cash」布線;refund-反向記錄。分區按比例反映。
Recognition:在iGaming中,refand減少了相應周期的GGR(帳戶策略)。
Reconciliation:每日對賬'merchant_refund_id ↔ provider_refund_id'、狀態、金額、FX課程。
FX:在適用的情況下捕獲課程邏輯(捕獲時間或返還時間);保持光柵。
9)KPI,目標和Alerta(Refund Health)
Refund Rate='Refunded_Tx/ Captured_Tx'(分段:出於原因)。
Refund Amount Ratio = `Refunded_Amount / Captured_Amount`.
TtR p95=p95('credited_at-created_at')通過方法。
Refund Error Rate = `Failed / Attempted` (<0.3%).
Refund-to-Source% ≥ 95%(可用)。
Double Refund Incidents = 0.
Alerts:- 「TtR p95」通過→ P2方法高於SLO。
- 在單個提供商/BIN → P1中通過「返還率」進行拼寫(檢查捕獲/雙打)。
- 任何'Double Refund> 0' → P0(立即凍結自動重建)。
10) SQL切片
10.1 Refands配置文件
sql
SELECT
DATE_TRUNC('day', r. created_at) AS d,
method_code, provider,
COUNT() FILTER (WHERE r. status='SUCCESS') AS refunds_ok,
COUNT() FILTER (WHERE r. status='FAILED') AS refunds_fail,
SUM(r. amount) AS refunded_amount,
PERCENTILE_CONT(0. 95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (r. credited_at - r. created_at))) AS ttr_p95_sec
FROM refunds r
JOIN payments p ON p. payment_id = r. payment_id
GROUP BY 1,2,3;
10.2部分余額控制
sql
SELECT p. payment_id,
p. captured_amount,
SUM(r. amount) AS refunded_sum,
(p. captured_amount - SUM(r. amount)) AS refundable_left
FROM payments p
LEFT JOIN refunds r ON r. payment_id = p. payment_id AND r. status IN ('SUCCESS','PENDING')
GROUP BY 1,2
HAVING (p. captured_amount - SUM(r. amount)) < 0;
11) UX和sapport
按方法劃分的消息模板:地圖解釋可能的出院延遲,A2A幾乎瞬間。
內閣狀態:「正式→處理→返回」;顯示預期的入學日期。
原因(reason_code)是人為的:「重復註銷」,「取消服務」,「部分補償」。
自助服務部分-安全只有限制和明確的規則。
12)風險和合規性
反洗錢:反洗錢不應成為替代渠道的結果;使用MLRO批準記錄例外情況。
制裁/RER:在以「紅色」帳戶/詳細信息啟動的退款時-強制性檢查。
DSAR/Retention:作為存儲策略的一部分存儲重構痕跡。
當地規則:退貨的時間和順序(例如消費者法規)-反映在政策中。
13)頻繁的錯誤以及如何避免錯誤
由於缺乏冪等性和重復的webhook而導致的雙重反射,→存儲idem鍵/狀態,檢查殘留物。
Partial>其余部分→ row-lock/optimistic版本和嚴格的檢查。
未經合規許可,跨方法返還→違反返還源。
報告中的void和refund混合→ KPI失真。
PSP和您的主人之間沒有自動焊接→「黑洞」。
14)花花公子
提供商退貨激增→檢查授權故障/捕獲雙打,啟用收件人,與PSP聯系。
大規模的黨派補償(運動)→提高黨派限額,包括團體操作,加強對賬。
Webhook錯誤→切換到polling,增加TTL的等效性,延遲自動重構。
反向來源排除(很少)→ MLRO升級,有記錄的付款和標記「comp_approved=true」。
15)測試案例(UAT/Prod)
1.一次捕獲後完全退款→正確地將剩余部分歸零。
2.Partial系列(3 ×)→捕獲≤總和;然後是剩下的全部。
3.相同性:重復同一請求→ 1個結果。
4.Webhook-drebesg: 3個相同的通知→一個註銷/登記。
5.鉆孔:人工模擬測驗→警報和自動校正。
6.權限限制:代理不能超過分區限制。
7.切斷:嘗試後期重構→正確故障和拼寫。
16)實施控制清單
- 關於司法管轄區/方法的完整/部分+返還源政策。
- DLQ的Idempotity,retrai,webhooks和polling。
- 返回和reason_code余數據模型。
- Ledger和每日汽車對賬。
- KPI/dashbord: Refund Rate, TtR, Error, Double Refund=0.
- 權限和應用矩陣,劄幌模式。
- UAT測試案例和Prod Level Alerta。
總結
Refands管理是嚴格的流程學科:從源到源的再融資,相等性,透明的數據模型,自動對賬和可理解的部分/完整策略。有了這些基本知識,您將TtR保持在較低水平,錯誤-為零,雙打-不可能,合規性和財務-與業務目標同步。