ნაწილობრივი და სრული რეფანდები
TL; DR
Refand არის captured თანხის საპირისპირო ოპერაცია. სრული დახურავს გარიგებას მთლიანად, ნაწილობრივი ნაწილი უბრუნებს ნაწილს (შეიძლება იყოს პარტიული სერია სრულად). კრიტიკულად: refund-to-source, მკაცრი idempotence, მიზეზების ჟურნალები და ორკესტრი ვებჰუკებით/რეტრებით. ჩვენ ვზომავთ Refund Rate, TtR p95, Refund Error და აღმოფხვრის დუბლებს/შეუსაბამობებს მანქანების შერყევის გზით.
1) ტერმინები და ფუნდამენტური განსხვავებები
Full Refund - მთელი ჩაწერილი თანხის დაბრუნება ('refund _ amount = capture _ amount').
Partial Refund - ნაწილის დაბრუნება ('0 <refund _ amount <capture _ amount'), საშუალებას აძლევს დანარჩენ ნაწილებს მთლიანი 'capture _ amount'.
Refund to Source - დაბრუნება გადახდის საწყისი მეთოდით/რელსებზე (მარეგულირებელი სასურველია/აუცილებელი).
Void - გაუქმება capture- ზე (თუ რელსებს უჭერს მხარს), არ განიხილება რეფანდად.
Reversal/Chargeback - საბანკო/სარკინიგზო მექანიკა თქვენი ინიციატივის მიღმა (დავები, ჩარჯბეკი) - არ იყოს დაბნეული რეფანდასთან.
2) როდესაც სრული vs ნაწილობრივი გაცემა
სრული (სრული):- შეკვეთის/მომსახურების მთლიანად გაუქმება, დუბლირების ჩამოწერა, სისტემური შეცდომა.
- სავალდებულოა მომსახურების წარუმატებელი მიწოდებით (მომხმარებლის/რეგულატორის წესების შესაბამისად).
- მომსახურების ნაწილობრივი გაუქმება, პროპორციული კორექტირება (ფასდაკლება, შეფერხებების ანაზღაურება).
- ტექნიკური სარკინიგზო ლიმიტები (მაქს. თანხა ერთი ოპერაციისთვის) - სერია partial.
- პოსტ-ფაქტორი კომისიების შენარჩუნება (სადაც მარეგულირებელი ნებადართულია) ნაკლებად ხშირად iGaming- ში.
3) პოლიტიკოსები და ლიმიტები
Refund-to-source = ნამდვილი ნაგულისხმევი; გამონაკლისები - MLRO/შესაბამისობის შემთხვევების საშუალებით (ლოგიკური).
Cut-off: რეფანდები ნებადართულია N დღიდან capture- დან (მეთოდით/იურისდიქციით).
Max Partial Count: არა უმეტეს K პარტიული პაკეტი (ტიპიური K-5).
Min Partial Amount: არ არის დაბალი, ვიდრე სარკინიგზო/PSP ტექნიკური მინიმუმი.
- საფორტეპიანო აგენტი: წვეულება X, სრული Y.
- მენეჯერი/ფინანსები: უფრო მეტი ლიმიტი, ჯვარედინი გამონაკლისები.
- Cooling-off განმეორებითი მცდელობებისთვის.
4) არქიტექტურა და მოვლენების ნაკადი
კომპონენტები:- Payment Orchestrator არის სტატუსის ჭეშმარიტების წყარო.
- Refund Service - API, idempotence, Retray- ის ორკესტრი, ჟურნალები.
- PSP Adapters - ინტეგრაცია მეთოდების მიხედვით.
- Reconciliation - curves, DLQ, კორექტირება.
- Ledger/Accounting - გაყვანილობა, დეფექტები, გასწორება.
- Risk/Compliance - სანქციების შემოწმება/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. ღონისძიების გამოქვეყნება კაფკა ლედგერში, BI, ალერტაში.
6. მანქანის კრეკი: შედარება „provider _ refund _ id“ რეესტრთან.
5) Idempotence და anti dubles
იგივე რეფანდის ორჯერ ჩარიცხვა შეუძლებელია: მთელი ლოგიკა იდემპოტაციის გზით (KV/Redis + TTL).
გასაღებები payment _ id × amount × reason (და, საჭიროების შემთხვევაში, 'partial _ index').
რეტრაები იყენებენ იმავე კლავიშს.
პარალელური წვეულება დაცულია row-level locks/optimistic ვერსიით gregate თანხით.
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/Mastercard)
მხარს უჭერს სრულ/პარტიულ; ხშირად რამდენიმე პარტიული; TtR დამოკიდებულია კლიენტის ბანკზე (T + 1... T + 5 bd).
ვებჰუკი წარმატების შესახებ სწრაფად მოდის, მაგრამ ამონაწერში ჩარიცხვა შეიძლება დაგვიანდეს და ახსნას საფორტეპიანო შაბლონებში.
A2A/Open Banking/RTP
ხშირად მყისიერი დაბრუნება (reversal/credit push); ზოგიერთი პროვაიდერი მხარს უჭერს მხოლოდ სრულ ან 1 პარტიულ.
მკაცრი კავშირი თავდაპირველ ანგარიშზე; refund to-source სავალდებულოა.
ელექტრონული საფულეები
ჩვეულებრივი სრული/პარტიული; TTR წუთები; შეზღუდვები პარტიული და მინიმალური ოდენობით.
ვაუჩერები/Prepaid
ჩვეულებრივ, refund-to-source არ არის ხელმისაწვდომი, როგორც პოლიტიკა: შიდა საფულეში დაბრუნება ან re-issue ვაუჩერი (თუ პროვაიდერს შეუძლია). მოითხოვს შესაბამისობის დათქმებს.
კრიპტო
რელსები - არასტაბილური; სასურველია არ გამოიყენოთ როგორც რეფანდის მეთოდი. თუ ნებადართულია: იმავე მისამართზე დაბრუნება/გაცვლა დოკუმენტირებული კურსით და კომისიებით; AML სკრინინგი.
8) აღრიცხვა, შერიგება და ფინანსები
Ledger: გაყვანილობა 'DR Revenue/CR Cash' capture- ზე; refund - საპირისპირო ჩანაწერები. წვეულება აისახება პროპორციულად.
ჩანაწერები: iGaming- ში რეფენდი ამცირებს შესაბამისი პერიოდის GGR- ს (ანგარიშვალდებული პოლიტიკა).
რეკონსტრუქცია: ყოველდღიური შერწყმა 'merchant _ refund _ id', provider _ refund _ id ', სტატუსები, თანხები, FX კურსები.
FX: ჩაწერეთ კურსების ლოგიკა (capture- ის დროს ან რეფუნდის დროს), სადაც გამოიყენება; დაიჭირეთ ჭრილობის ცხაური.
9) KPI, მიზნები და ალერტები (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.
- 'TR p95' უფრო მაღალია, ვიდრე SLO, P2 მეთოდით.
- Spikes 'Refund Rate' - ში ერთ პროვაიდერში/BIN-P1 (შეამოწმეთ დატყვევებები/დუბლები).
- ნებისმიერი 'Double Refund> 0' P0 (რეფანდის მანქანების დაუყოვნებლივი გაყინვა).
10) SQL ნაჭრები
10. 1 რეფანდის პროფილი
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 და საფორტი
შეტყობინებების შაბლონები მეთოდების მიხედვით: ბარათები განმარტავს ამონაწერის შესაძლო შეფერხებას, A2A - თითქმის მყისიერად.
სტატუსები ოფისში: 'მორთული'; აჩვენეთ მოსალოდნელი რეგისტრაციის თარიღი.
მიზეზები (reason _ code) - პირადული: „ჩამოწერის დუბლირება“, „მომსახურების გაუქმება“, „ნაწილობრივი ანაზღაურება“.
უსაფრთხო მომსახურება - უსაფრთხოდ მხოლოდ ლიმიტები და მკაფიო წესები.
12) რისკი და შესაბამისობა
ანტი-გათეთრება: რეფენდი არ უნდა იქცეს დასკვნად ალტერნატიულ არხზე; აღრიცხეთ გამონაკლისები MLRO მოწონებით.
სანქციები/REP: „წითელ“ ანგარიშებზე/დეტალებზე წამოწყებული დაბრუნების დროს - სავალდებულო შემოწმება.
DSAR/Retention: შეინახეთ რეფანდის კვალი მონაცემთა შენახვის პოლიტიკის ფარგლებში.
ადგილობრივი წესები: დაბრუნების დრო და პროცედურა (მაგალითად, სამომხმარებლო რეგულაციები) - ჩვენ ასახავს პოლიტიკას.
13) ხშირი შეცდომები და როგორ მოვერიდოთ მათ
ორმაგი რეფენდი, იდემპოტენტურობისა და განმეორებითი ვებჰუკების არარსებობის გამო, შეუძლია შეინახოს idem გასაღები/სტატუსი, შეამოწმოს დარჩენილი.
Partial> დანარჩენი არის row-lock/optimistic ვერსია და მკაცრი შემოწმებები.
Cross-method refund, შესაბამისობის გარეშე, არღვევს refund-to-source.
ანგარიშებში void და refund ნაზავი არის KPI- ს დამახინჯება.
არ არსებობს მანქანების შედუღება - „შავი ხვრელები“ PSP- სა და თქვენს ყინულს შორის.
14) პლეიბუკი
პროვაიდერის დაბრუნების ზრდამ შეიძლება შეამოწმოს ავტორიზაციის გაუმართაობები/დუბლები, ჩართოთ ფეილოვერი, დაუკავშირდით PSP- ს.
მასობრივი პარტიული ანაზღაურება (კამპანია) არის პარტიული ლიმიტის გაზრდა, ჯგუფური ოპერაციების ჩართვა და შერიგების გაძლიერება.
ვებჰუკების შეცდომა - ნახევარზე გადასვლა, TTL idempotence- ის გაზრდა და რეფანდების გადადება.
გამონაკლისი refund-to-source (იშვიათად) არის MLRO ესკალაცია, დოკუმენტირებული გადახდა და აღნიშვნა 'comp _ approved = true'.
15) ტესტის შემთხვევები (UAT/UAT)
1. Full refund ერთი capture- ის შემდეგ სწორად აცილებს დანარჩენებს.
2. Partial სერია (3 ×) - თანხა capture; შემდეგ სრული დარჩენილი.
3. Idempotence: იგივე მოთხოვნის განმეორება - 1 შედეგი.
4. Webhuk-drebezg: 3 იდენტური შეტყობინება - ერთი ჩამოწერა/ჩარიცხვა.
5. კრიპტები: ხელოვნური mismatch ალერტი და ავტოკორექცია.
6. უფლებების შეზღუდვა: აგენტი არ შეიძლება აღემატებოდეს პარტიული ზღვარს.
7. Cut-off: გვიანი რეფანდის მცდელობა - სწორი უარი და ლოგიკა.
16) განხორციელების შემოწმების სია
- სრული/პარტიული + რეფუნდის წყაროების პოლიტიკოსები იურისდიქციების/მეთოდების მიხედვით.
- Idempotence, retrai, webhuk და welling, DLQ.
- მონაცემთა მოდელი დანარჩენი დაბრუნებისთვის და reason _ code.
- ლეგერი და ყოველდღიური მანქანების კრიკეტები.
- KPI/დაშბორდი: Refund Rate, TtR, Error, Double Refund = 0.
- უფლებები და მატრიცა, საფორტეპიანო შაბლონები.
- UAT ტესტის შემთხვევები და პროდ დონის ალერტები.
რეზიუმე
რეფანდის მართვა პროცესების მკაცრი დისციპლინაა: refund-to-source, imempotence, მონაცემთა გამჭვირვალე მოდელი, ავტომობილების კრიკეტები და პარტიული/სრული გასაგები პოლიტიკოსები. ასეთი საფუძვლით, თქვენ TtR- ს დაბალ შეცდომებს ინარჩუნებთ, შეცდომები - ნულოვანი, დუბლები - შეუძლებელია, ხოლო შესაბამისობა და ფინანსები სინქრონიზებულია ბიზნეს მიზნებთან.