Qisman va to’liq refandlar
TL; DR
Refand - bu captured summa bo’yicha teskari operatsiyadir. To’liq tranzaksiyani to’liq yopadi, qisman bir qismini qaytaradi (to’liq partial seriya bo’lishi mumkin). Tanqidiy: refund-to-source, qat’iy idempotentlik, sabablarni jurnallashtirish va vebxuk/retralar bilan orkestr. Biz Refund Rate, TtR p95, Refund Error ni o’lchaymiz va auto-solishtirmalar orqali double/nomuvofiqliklarni bartaraf etamiz.
1) Atamalar va prinsipial farqlar
Full Refund - barcha qayd etilgan summaning qaytarilishi (’refund _ amount = capture_amount').
Partial Refund - qismning qaytarilishi (’0 <refund_amount <capture_amount'), qolgan partial qismning jami’capture _ amount’gacha bo’lishiga yo’l qo’yadi.
Refund to Source - boshlang’ich usulga/to’lov relslariga qaytarish (tartibga solish uchun afzalroq/majburiy).
Void - capture oldidan bekor qilish (agar relslar tomonidan qoʻllab-quvvatlansa) refand hisoblanmaydi.
Reversal/Chargeback - bank/rels mexanikalari sizning tashabbusingizdan tashqarida (nizolar, charjbeklar) - refand bilan adashtirmaslik kerak.
2) Qachon to’liq vs qisman berish
Toʻliq (Full):- Buyurtma/xizmatni butunlay bekor qilish, bir-birini takrorlovchi hisobdan chiqarish, tizim xatosi.
- Xizmat ko’rsatilmaganda majburiy (iste’molchi/tartibga soluvchi qoidalariga ko’ra).
- Xizmatni qisman bekor qilish, mutanosib ravishda tuzatishlar kiritish (chegirmalar, kechikishlar kompensatsiyasi).
- Relsning texnik limitlari (bitta operatsiya uchun maksimal summa) - partial seriya.
- Post-faktum (tartibga solish yo’li bilan ruxsat etilgan) - kamdan-kam hollarda iGaming-da.
3) Siyosat va limitlar
Refund-to-source = true andoza; istisnolar - MLRO/komplayens-keyslar orqali (logirovka qilinadi).
Cut-off: refandlarga capture (usul/yurisdiksiya bo’yicha) vaqtdan boshlab N kun ruxsat etiladi.
Max Partial Count: payment uchun ko’pi bilan K partial (odatda K ≤ 5).
Min Partial Amount: texnik minimal rels/PSP dan past emas.
- Sapport agenti: partial ≤ X, full ≤ Y.
- Menejer/moliya: limitlardan ortiq, kross-uslubiy istisnolar.
- Cooling-off qayta urinishlar (anti-drebezg).
4) Arxitektura va voqealar oqimi
Komponentlar:- Payment Orchestrator - maqom haqiqati manbai.
- Refund Service - API, idempotentlik, retraylarni orkestrlash, jurnallashtirish.
- PSP Adapters - usullar bo’yicha integratsiya.
- Reconciliation - avto-solishtirish, DLQ, tuzatishlar.
- Ledger/Accounting - simlar, deferlar, kliringlar bilan tekislash.
- Risk/Compliance - munozarali stsenariylarda sanksiyalar/SoF tekshiruvi.
1. `Refund. Create’(API) → validatsiyalar (limitlar, qoldiq, policy, KYC/SoF zarurat bo’lganda).
2. Генерация idempotency_key (`hash(payment_id + refund_amount + reason + nonce)`).
3. PSP chaqiruvi →’PENDING’maqomi.
4. Vebxuk/polling →’SUCCESS ’/’ FAILED’; taym-autda - xuddi shu kalitli retralar.
5. Voqeani Kafka → Ledger, BI, alertlarda chop etish.
6. Avto-solishtirish: «provider _ refund _ id» ni reyestr bilan taqqoslash.
5) Idempotentlik va anti-dubli
Bitta refand ikki marta kiritilishi mumkin emas: butun mantiq idempotency storage (KV/Redis + TTL) orqali.
Kalitlar payment_id × amount × reason (va zarurat boʻlganda’partial _ index’).
Retrajlar bir xil kalitdan foydalanadi.
Parallel partial row-level locks/optimistic version aggregate summalarida himoya qilinadi.
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) Ma’lumotlar modeli (eng kam yetarli)
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) To’lov relslari bo’yicha xususiyatlar
Kartalar (Visa/Mastercard)
full/partial; ko’pincha bir nechta partial; TtR mijoz bankiga bog’liq (T + 1... T + 5 b.d.).
Muvaffaqiyat haqida vebxuklar tez keladi, lekin bo’shatish kechikishi mumkin → sapport shablonlarida tushuntiring.
A2A/Open Banking/RTP
Koʻpincha bir lahzada qaytarish (reversal/credit push); ba’zi provayderlar faqat full yoki 1 partial ni qo’llab-quvvatlaydi.
Boshlang’ich hisobvaraqqa qat’iy bog’lanish; refund-to-source majburiydir.
Elektron hamyonlar
Oddiy full/partial; TtR daqiqalar; partial miqdor va eng kam summa bo’yicha cheklashlar.
Vaucherlar/Prepaid
Odatda refund-to-source mavjud emas → siyosat: ichki hamyonga yoki re-issue vaucherga qaytarish (agar provayder buni bilsa). Komplayens-shartlarni talab qiladi.
Kripto
Relslar - o’zgaruvchan; afzalroq refand usuli sifatida ishlatmaslik. Agar ruxsat etilgan bo’lsa: hujjatlashtirilgan kurs va komissiyalar bilan ayni bir manzilga/birjaga qaytarish; AML-skrining.
8) Hisob, solishtirish va moliya
Ledger: capture’da’DR Revenue/CR Cash’simlari; refund bo’lganda - teskari yozuvlar. Partial proporsional tarzda aks ettiriladi.
Recognition: iGaming refandida tegishli davr GGR (hisob siyosati) ni kamaytiradi.
Reconciliation: kundalik solishtirmalar’merchant _ refund _ id provider_refund_id', maqomlar, summalar, FX kurslari.
FX: kurslar mantig’ini (capture yoki refund vaqtida) qo’llash mumkin bo’lgan joyda qayd qiling; panjarani ushlab turing.
9) KPI, maqsadlar va alertlar (Refund Health)
Refund Rate =’Refunded _ Tx/ Captured_Tx' (segmentlash: sabablarga ko’ra).
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% (mavjud).
Double Refund Incidents = 0.
- ’TtR p95’ SLOdan yuqori → P2 usuli bo’yicha.
- Spikes’Refund Rate’bo’yicha bitta provayderda/BIN → P1 (ushlashlarni/dubllarni tekshirish).
- Har qanday’Double Refund> 0’→ P0 (avto-refandlarni darhol muzlatish).
10) SQL-kesmalar
10. 1 Refandlar 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 uchun qoldiqni nazorat qilish
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 va sapport
Xabarlar shablonlarini quyidagi usullar bo’yicha tushuntiramiz: kartalar ko’chirishda kechikish ehtimolini, A2A - deyarli bir zumda.
Kabinetdagi maqomi: «Rasmiylashtirilgan → Qayta ishlangan → Qaytarilgan»; kutilayotgan qabul sanasini koʻrsatish.
Sabablari (reason_code) - odam o’qiydigan: «Hisobdan chiqarishni takrorlash», «Xizmatni bekor qilish», «Qisman kompensatsiya».
Self-service partial - faqat limitlar va aniq qoidalar bilan xavfsiz.
12) Tavakkalchilik va komplayens
Yuvishga qarshi: refand muqobil kanalga aylanmasligi kerak; MLRO roziligi bilan istisnolarni qayd qiling.
Sanksiyalar/TB: «qizil» hisobvaraqlarga tashabbus qilingan qaytarishlarda - majburiy tekshiruv.
DSAR/Retention: maʼlumotlarni saqlash siyosati doirasida refand izlarini saqlang.
Mahalliy qoidalar: qaytarish muddatlari va tartibi (masalan, iste’mol reglamentlari) - policy.
13) Tez - tez xatolar va ulardan qanday qochish mumkin
Idempotentlik va takroriy vebxuklarning yoʻqligi sababli ikkilik refand → idem-kalitni/holatni saqlash, qoldiqni tekshirish.
Partial> qoldiq → row-lock/optimistic version va qattiq tekshiruvlar.
Cross-method refund komplayens-ruxsatsiz → refund-to-source buzadi.
Hisobotlarda void va refund aralashmasi → KPI buzilishi.
PSP va sizning boshqaruvchingiz o’rtasida «qora teshiklar» yo’q.
14) Pleybuklar
Provayder bo’yicha qaytarmalarning ko’payishi → avtorizatsiya muvaffaqiyatsizliklarini tekshirish/dubli capture, feyloverni yoqish, PSP bilan aloqani o’rnatish.
Ommaviy partial kompensatsiyalar (kampaniyalar) → partial limitni oshirish, guruh operatsiyalarini kiritish, solishtirishlarni kuchaytirish.
Vebxuk xatosi → pollingga oʻtish, idempotentlik TTLni oshirish, avto-refandlarni kechiktirish.
Istisno refund-to-source (kamdan-kam hollarda) → MLRO eskalatsiyasi, hujjatlashtirilgan to’lov va’comp _ approved = true’belgisi.
15) Test-keyslar (UAT/Prod)
1. Full refund bitta capture → dan keyin qoldiqni to’g’ri bekor qiladi.
2. Seriya partial (3 ×) → summa ≤ capture; keyin qoldiq uchun full.
3. Idempotentlik: bir xil so’rovni takrorlash → 1 natija.
4. Vebhuk-drebezg: 3 ta bir xil bildirishnoma → bitta hisobdan chiqarish/qabul qilish.
5. Solishtirishlar: sun’iy mismatch → alert va avto tuzatish.
6. Huquqlarni cheklash: agent partial limitdan oshib ketishi mumkin emas.
7. Cut-off: kech refandga urinish → to’g’ri rad etish va loging.
16) Joriy etishning nazorat chek-varaqasi
- Yurisdiksiyalar/usullar bo’yicha full/partial + refund-to-source siyosati.
- Idempotentlik, retrajlar, vebxuklar va polling, DLQ.
- Qaytarish va reason_code qoldig’i bo’lgan ma’lumotlar modeli.
- Ledger va kundalik avto-solishtirishlar.
- KPI/dashbord: Refund Rate, TtR, Error, Double Refund = 0.
- Huquq va appruv matritsasi, sapport shablonlari.
- UAT test-keyslari va pred-darajali alertlar.
Xulosa
Refandalarni boshqarish - refund-to-source, idempotentlik, ma’lumotlarning shaffof modeli, avto-solishtirishlar va tushunarli partial/full siyosati kabi jarayonlarning qat’iy intizomidir. Bunday asoslar bilan siz TtRni past ushlab turasiz, xatolar nolga teng, dubli mumkin emas, komplayens va moliya esa biznes maqsadlari bilan sinxronlashtirilgan.