Bölekleýin we doly refandlar
TL; DR
Refand - captured mukdar boýunça ters amaldyr. Doly geleşigi bütinleý ýapýar, bölekleýin bölegi yzyna gaýtarýar (partial seriýasy doly bolup biler). Möhüm: refund-to-source, berk idempotentlik, sebäpleri ýazga almak we webhuklar/retralar bilen orkestr. "Refund Rate", "TtR p95", "Refund Error" -y ölçeýäris we awto-deňeşdirmeler arkaly goşa/gapma-garşylyklary ýok edýäris.
1) Adalgalar we prinsipial tapawutlar
Full Refund - hasaba alnan ähli puluň yzyna gaýtarylmagy ('refund _ amount = capture_amount').
Partial Refund - bölegiň yzyna gaýtarylmagy ('0 <refund_amount <capture_amount'), galan partial jemi' capture _ amount '-e çenli rugsat berýär.
Refund to Source - tölegiň asyl usulyna/relslerine gaýdyp gelmek (kadalaşdyryjy taýdan has gowy/hökmany).
Void - capture (relsler tarapyndan goldanylsa) öň ýatyrylmagy refand hasap edilmeýär.
Reversal/Chargeback - bank/rels mehanikleri siziň inisiatiwaňyzyň daşynda (jedeller, çarjbekler) - refand bilen garyşdyrylmaly däldir.
2) Haçan doly bermeli vs bölekleýin
Doly:- Sargyt/hyzmatyň tutuşlygyna ýatyrylmagy, iki gezek ýazylmagy, ulgamlaýyn ýalňyşlyk.
- Hyzmat edilmedik mahalynda hökmanydyr (sarp edijiniň/düzgünleşdirijiniň düzgünleri boýunça).
- Hyzmatyň bölekleýin ýatyrylmagy, proporsional düzedişler (arzanladyşlar, gijikdirmeleriň öwezini dolmak).
- Relsiň tehniki çäkleri (bir amal üçin iň ýokary mukdar) - partial seriýa.
- Post-faktum komissiýalary saklamak (bu ýerde kadalaşdyryjy taýdan rugsat berilýär) - iGaming-de seýrek bolýar.
3) Syýasatlar we çäkler
Refund-to-source = dogry; kadadan çykmalar - MLRO/complayens-keysler arkaly (logirlenýär).
Kesmek: refandlara capture pursatyndan N gün rugsat berilýär (usul/ýurisdiksiýa boýunça).
Max Partial Count: payment üçin K partial-dan köp bolmaly däldir (adaty K ≤ 5).
Min Partial Amount: rels/PSP-iň tehniki derejesinden pes bolmaly däldir.
- Sapport agenti: partial ≤ X, full ≤ Y.
- Dolandyryjy/maliýe: çäklerden ýokary, kross-metodiki kadadan çykmalar.
- Gaýta-gaýta synanyşmak üçin Cooling-off.
4) Arhitektura we wakalaryň akymy
Komponentler:- "Payment Orchestrator" status hakykatynyň çeşmesi.
- Refund Service - API, idempotentlik, retraý orkestri, žurnallaşdyrma.
- PSP Adapters - usullar boýunça integrasiýa.
- Reconciliation - awto-barlyşyklar, DLQ, düzedişler.
- Ledger/Accounting - simler, deferler, kliringler bilen tekizlemek.
- Töwekgelçilik/Compliance - jedelli ssenariýalarda sanksiýa/SoF barlaglary.
1. `Refund. Create '(API) → tassyklamalar (çäkler, galyndy, policy, KYC/SoF zerur bolsa).
2. Генерация idempotency_key (`hash(payment_id + refund_amount + reason + nonce)`).
3. PSP çagyryşy → 'PENDING' statusy.
4. Webhook/polling → 'SUCCESS '/' FAILED'; wagt-autda - şol bir açar bilen retra.
5. Wakany Kafka → Ledger, BI, alertlerde çap etmek.
6. Awto-deňeşdirme: 'provider _ refund _ id' -ni reýestr bilen deňeşdirmek.
5) Idempotentlik we anti-dubli
Şol bir refand iki gezek ýazylyp bilinmez: ähli logika idempotency storage (KV/Redis + TTL) arkaly.
Açarlar payment_id × amount × reason (we zerur bolsa 'partial _ index').
Retraýlar şol bir açary ulanýarlar.
Parallel partial row-level locks/optimistic version aggregate summalarynda goralýar.
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) Maglumatlaryň modeli (iň az ýeterlik)
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) Töleg relsleri boýunça aýratynlyklar
Kartlar (Visa/Mastercard)
Full/partial; köplenç birnäçe partial; TtR müşderiniň bankyna baglydyr (T + 1... T + 5 b.d.).
Webhuklar üstünlik barada çalt gelýär, ýöne boşadylmak giç bolup biler → sapport şablonlarynda düşündirýäris.
A2A/Open Banking/RTP
Köplenç derrew yzyna gaýtarmak (reversal/credit push); Käbir üpjün edijiler diňe full ýa-da 1 partial.
Başlangyç hasap bilen berk baglanyşyk; refund-to-source hökmany.
Elektron gapjyklar
Adaty full/partial; TtR minutlary; partial mukdar we iň az mukdar boýunça çäklendirmeler.
Talonlar/Prepaid
Adatça refund-to-source elýeterli däl → syýasat: içerki gapjyga ýa-da re-issue talonyna gaýdyp gelmek (eger üpjün ediji edip bilse). Ylalaşyk şertlerini talap edýär.
Kripto
Relsler - üýtgewsiz; refand usuly hökmünde ulanmazlyk has gowudyr. Rugsat berlen halatynda: dokumentleşdirilen kurs we komissiýalar bilen şol adrese/birjasyna gaýtaryp bermek; AML barlagy.
8) Buhgalteriýa, deňeşdirmeler we maliýe
Ledger: capture 'DR Revenue/CR Cash' simleri; refund - ters ýazgylar. Partial proporsional görkezilýär.
Recognition: iGaming-de refand degişli döwrüň GGR-sini azaldar (hasap syýasaty).
Reconciliation: gündelik deňeşdirmeler 'merchant _ refund _ id provider_refund_id', statuslar, pullar, kurslar FX.
FX: kurslaryň logikasyny düzediň (capture pursatynda ýa-da refund pursatynda); spread panjarasyny saklaň.
9) KPI, maksatlar we aladalar (Refund Health)
Refund Rate = 'Refunded _ Tx/ Captured_Tx' (bölmek: sebäplere görä).
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% (bar ýerinde).
Double Refund Incidents = 0.
- 'TtR p95' SLO-dan ýokary → P2 usuly boýunça.
- Bir üpjün edijide "Refund Rate" boýunça Spikes/BIN → P1 (tutmalary/goşlary barlaň).
- Islendik 'Double Refund> 0' → P0 (awto-refandlary derrew doňdurmak).
10) SQL bölekleri
10. 1 Refand profili
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 Partial üçin galyndy gözegçiligi
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 we sapport
Usullar boýunça habar şablonlary: kartoçkalara göçürmede gijä galmagy düşündirýäris, A2A - derrew diýen ýaly.
Kabinetdäki statuslar: "Resmileşdirildi → Gaýtadan işlenildi → Yzyna berildi"; Kabul edilmek üçin garaşylýan senäni görkezmek.
Sebäpler (reason_code) - adam okalýan: "Hasapdan çykarmagyň gaýtalanmagy", "Hyzmatyň ýatyrylmagy", "Bölekleýin öwezini dolmak".
Self-service partial - diňe çäkler we anyk düzgünler bilen howpsuz.
12) Töwekgelçilik we komplayens
Anti-ýuwmak: refand alternatiw kanala çykmaga öwrülmeli däldir; MLRO tassyklamasy bilen kadadan çykmalary ýazga alyň.
Sanksiýalar/RER: "gyzyl" hasaplara/jikme-jikliklere başlanan yzyna gaýtarylanda - hökmany barlag.
DSAR/Retention: Maglumatlary saklamak syýasatynyň çäginde refandlaryň yzlaryny saklaň.
Ýerli düzgünler: yzyna gaýtarmagyň möhletleri we tertibi (mysal üçin, sarp ediş düzgünleri) - policy-da görkezýäris.
13) Ýygy-ýygydan ýalňyşlyklar we olardan nädip gaça durmaly
Idempotentligiň we gaýtalanýan webhuklaryň ýoklugy sebäpli goşa refand → idem-açary/statusy saklamak, balansyny barlamak.
Partial> balans → row-lock/optimistic version we berk barlaglar.
Cross-method refund complayens-rugsatsyz → refund-to-source bozýar.
Hasabatda void we refund garyşyk → KPI ýoýulmasy.
PSP bilen dolandyryjyňyzyň arasynda awtoulag barlagy ýok → "gara deşikler".
14) Pleýbuklar
Üpjün ediji boýunça yzyna gaýdyp gelişleriň köpelmegi → ygtyýarnama şowsuzlyklaryny/goşa capture barlamak, feýloweri açmak, PSP bilen aragatnaşyk.
Köpçülikleýin partial-kompensasiýa (kampaniýa) → partial çäkleri ýokarlandyrmak, toparlaýyn amallary goşmak, barlagy güýçlendirmek.
Webhook hatasy → Pollinge geçmek, TTL-ni köpeltmek, awto-refandlary yza süýşürmek.
Refund-to-source (seýrek) → MLRO-nyň eskalasiýasy, dokumentleşdirilen töleg we 'comp _ approved = true' belligi.
15) Synag haltalary (UAT/Prod)
1. Doly yzyna gaýtarmak bir capture → balansyny dogry ýok edýär.
2. Partial seriýasy (3 ×) → jemi ≤ capture; soňra galyndy üçin full.
3. Idempotentlik: şol bir haýyşyň gaýtalanmagy → 1 netije.
4. Webhuk-drebezg: 3 birmeňzeş bildiriş → bir hasapdan çykarmak/ýazmak.
5. Deňeşdirmeler: emeli mismatch → alert we awto düzediş.
6. Hukuklaryň çäklendirilmegi: agent partial çäkden geçip bilmez.
7. Kesmek: giç refanda synanyşygy → dogry şowsuzlyk we logirleme.
16) Girizmegiň gözegçilik çek-sanawy
- Ýurisdiksiýalar/usullar boýunça full/partial + refund-to-source syýasaty.
- Idempotentlik, retralar, webhuklar we polling, DLQ.
- Yzyna gaýtarmak we reason_code üçin galyndy bilen maglumatlaryň modeli.
- Dolandyryjy we gündelik awto-barlyşyklar.
- KPI/dashboard: Refund Rate, TtR, Error, Double Refund = 0.
- Hukuklar we appruv-matrisa, sapport şablonlary.
- UAT synag ýagdaýlary we prot-derejeli aladalar.
Gysgaça maglumat
Refandlary dolandyrmak prosesleriň berk düzgünidir: refund-to-source, idempotentlik, maglumatlaryň aç-açan modeli, awto-deňeşdirmeler we partial/full syýasatlaryna düşünmek. Şeýle esaslar bilen siz TtR-ny pes saklaýarsyňyz, ýalňyşlyklar - nol, goşa - mümkin däl, laýyklyk we maliýe - işewürlik maksatlary bilen sinhronlaşdyrylýar.