GH GambleHub

Reconcilierea plăților și rapoartelor PSP

TL; DR

Reconcilierea este coaserea zilnică automată a registrului și evenimentelor (auth/capture/rambursare/plată) cu rapoartele PSP/achizitor/bancar. Cheia succesului: un singur model de date, chei de potrivire deterministe, idempotență strictă, toleranțe de sumă/FX/timp, coadă DLQ pentru cazuri controversate și playbook-uri de corecție automată. KPI: Recunoașterea nepotrivirii Rate↓, îmbătrânirea Unreconciled↓, Auto- match%↑.

1) De ce și ce verificăm

Obiective: confirmarea veniturilor și comisioanelor, detectarea duplicatelor/pierderilor, decontarea corectă pe zile și valute, controlul rambursării la sursă, respectarea regulatorului/auditului.

Obiecte de reconciliere:
  • Depozite: 'auth → capture → settle'
  • Restituiri: integral/parțial, statusuri și sume
  • Plăți/retrageri: Metode de plată
  • Taxe și ajustări: comisioane PSP, scheme interbancare, corecții
  • Chargebacks/Dispute: Dincolo de inițiativa dvs
  • FX/Conversii: rate, spread-uri, punct de fixare

2) Surse de date

Evenimente interne: event bus/Kafka, 'payments _ flat', 'ramburss', 'payouts', your Ledger.

Rapoarte PSP (dump SFTP/API/webhook):
  • Tranzacții (declarații operaționale)
  • Așezări/Loturi
  • Taxe/Declarații
  • Chargebacks/Litigii
  • Plăți/OCT/RTP/SEPA registre
  • Extrase de cont: CAMT MT940/CSV/ISO20022, ridicare de credit.
💡 Depozitare: aterizare → prime → normalizate → potrivite. Toate fișierele primite - cu sume de control și versioning.

3) Chei de potrivire

Arbore cheie prioritar (descrescător în precizie):

1. provider_txid ↔ provider_txid (ID unic PSP)

2. idempotency_key/ merchant_reference (dacă este stabil în PSP)

3. (suma, moneda, timestamp_bucket, last4/bin, auth_code)

4. Strat fuzzy: toleranțe ± în funcție de sumă/timp, țara BIN/emitent, familia de statut

Recomandări:
  • Păstrați atât 'payment _ id' cât și' provider _ txid '.
  • Pentru parțială/rambursare, adăugați 'sequence _ index' or 'refund _ line _ id'.
  • Для plăți - 'payout _ batch _ id + line_id'.
  • Pentru FX - ' _ id' (conversie) și sursa ratei.

4) Modelul de date (strat normalizat)

json
{
"source": "INTERNAL    PSP_TX    PSP_SETTLEMENT    BANK",
"provider": "Acquirer_A",
"payment_id": "pay_123",
"provider_txid": "psp_tx_789",
"kind": "AUTH    CAPTURE    REFUND    PAYOUT    FEE    SETTLEMENT    CHARGEBACK",
"sequence": 0,
"amount": 100. 00,
"currency": "EUR",
"fee_amount": 1. 20,
"fx_rate": 1. 0000,
"fx_src": "PSP    ECB    BANK",
"status": "APPROVED    CAPTURED    SUCCESS    FAILED    SETTLED",
"event_ts": "2025-11-03T12:00:00Z",
"settlement_date": "2025-11-05",
"account": "PSP_MERCHANT_CARD_A",
"matching_keys": {
"provider_txid": "psp_tx_789",
"merchant_ref": "mr_456",
"idem_key": "idem_abc"
},
"hash_row": "sha256(...)"
}

5) Procesul de reconciliere (ETL/orchestrare)

1. Ingera: luăm rapoartele PSP (SFTP/API), validăm schema/semnăturile, salvăm la „raw”.
2. Normalizați: mappim al câmpului la formatul unificat (ISO valutar, zecimale, fusul orar UTC).
3. Meci: algoritm pentru potrivirea arborelui cheie cu toleranțe.
4. Post-meci: forma diff (discrepanțe) și intrările în jurnal pentru registru/corecții.
5. Decontare: cusătură 'PSP _ SETTLEMENT ↔ BANK' (creditare în cont), scatter pe zi/lot.
6. Raport: tablou de bord, alerte; controversat în DLQ pentru parsare manuală/auto-reluare.

Idempotence: pentru fiecare fișier/pagină - 'ingest _ id'. Reîncărcarea nu schimbă rezultatul.

6) Toleranțe și reguli

Timp: „± 15 min” pentru tranzacții, „± 1 zi” pentru decontare.
Suma: '≤ 0. 01 "monedă de bază sau" ≤ 10 bps "pentru diferențe FX/taxă.
FX: permitem discrepanța cu banca dacă sursa cursului de schimb este diferită; fix 'fx _ src'.
Parțial/Multiplu: Suma liniilor parțiale/de rambursare trebuie să fie egală cu soldul intern.

7) Diff taxonomy

Tip diffDescriereAcțiune
MISSING_INTERNALPSP-ul are, noi nuCreați un caz orfan, verificați cărțile web/retraiele
MISSING_PSPAvem, PSP nu aVerificare stare/repetare, contact PSP
AMOUNT_MISMATCHSumele variază> toleranțăAutocorrect/Jurnal, Escalate după cum este necesar
FEE_MISMATCHComisioanele diferăAcceptați PSP ca „adevărat” (politică) sau solicitați notă de credit
STATUS_DRIFTCAPTURĂ cu noi, AUTH cu PSPVerificați cârligele de captare/decontare
DUPLICATLinii duplicateDedup by 'provider _ txid/idempotency _ key'
FX_DRIFTCursuri divergenteSetați sursa oficială, ajustați P&L
REFUND_OVERRambursare> capturatUnitate urgentă, parsare manuală, jurnal de corecție inversă

8) Registru & Contabilitate

Captură: 'DR Accounts Receivable/CR Revenue' и 'DR Cash (la decontare )/CR Accounts Receivable'

Taxa: 'DR Taxe/CR Cash sau Payable'

Rambursare: postări inverse pro rata parțială

Chargeback: conturi separate și rezervă pentru litigii

Reval FX: reevaluarea zilnică a soldului AR/cache la 'fx _ src _ policy'

9) KPI-uri și obiective

Auto-meci% = linii de auto-meci/toate liniile (95% ≥ țintă)

Rata de neconcordanță de recunoaștere = linii diff/toate liniile (≤ 1-2%)

Îmbătrânirea neconciliată: p50/p95 zile în DLQ (p95 ≤ 3 zile)

Timpul de decontare: proporția loturilor cusute cu banca D-day (≥ 99%)

Acuratețea taxei: discrepanțele dintre comisioanele furnizorului (≤ 0. 1% din cifra de afaceri)

Incidente duplicate/orfane: cu scopul 0

10) Felii SQL

10. 1 Potrivire provider_txid de bază

sql
WITH i AS (
SELECT provider, provider_txid, kind, amount, currency, event_ts
FROM internal_norm
),
p AS (
SELECT provider, provider_txid, kind, amount, currency, event_ts
FROM psp_norm
)
SELECT
COALESCE(i. provider_txid, p. provider_txid) AS txid,
COALESCE(i. provider, p. provider) AS provider,
i.kind AS kind_internal, p. kind AS kind_psp,
i.amount AS amount_internal, p. amount AS amount_psp,
i.currency, p. currency,
CASE
WHEN i.provider_txid IS NULL THEN 'MISSING_INTERNAL'
WHEN p. provider_txid IS NULL THEN 'MISSING_PSP'
WHEN ABS(i. amount - p. amount) > 0. 01 THEN 'AMOUNT_MISMATCH'
ELSE 'MATCHED'
END AS recon_status
FROM i
FULL OUTER JOIN p USING (provider, provider_txid);

10. 2 Decontare ↔ Banca

sql
SELECT s. settlement_date, s. batch_id, s. currency,
s. amount_settled, b. amount_bank,
(b. amount_bank - s. amount_settled) AS diff
FROM psp_settlements s
LEFT JOIN bank_statements b
ON b. value_date = s. settlement_date
AND b. currency = s. currency
AND ABS(b. amount_bank - s. amount_settled) <= 0. 5;

10. 3 DLQ îmbătrânire

sql
SELECT diff_type,
COUNT() AS cnt,
PERCENTILE_CONT(0. 5) WITHIN GROUP (ORDER BY AGE(NOW(), created_at)) AS p50_age,
PERCENTILE_CONT(0. 95) WITHIN GROUP (ORDER BY AGE(NOW(), created_at)) AS p95_age
FROM recon_dlq
GROUP BY diff_type
ORDER BY cnt DESC;

11) Caracteristici pe șine/cazuri

Hărți: diferențe între ajustările „auth” și „capture”, reglajele „late”, taxa interbancară/circuit - linii separate.
A2A/Open Banking/RTP: confirmări instantanee, dar „inversare” posibilă; check 'plată' și se întoarce.
Portofele: adesea perfect „provider _ txid”, rapid „rambursare”; urmăriți liniile de taxare.
Vouchere: nici o rambursare simetrică - se reflectă corect în politică și rapoarte.
Cripto: hash on-chain ↔ provider_txid; confirmări N; contabilizarea comisioanelor de rețea și eventualele reduceri; cursul de schimb - la momentul conversiei.

12) Playbook-uri operaționale

Supratensiune în MISSING_INTERNAL: verificați pierderea cârligelor/retraielor, rejucați ingestia, activați sondarea API.
AMOUNT_MISMATCH de la un PSP: comparați modelul de rotunjire/TVA/taxă, solicitați o declarație de corecție.
Decontarea nu se leagă de bancă: data valorii de verificare, comisioane bancare, întârzieri T + N; temporar pus în „Contul de suspans”.
REFUND_OVER de masă: auto-refands oprire imediată, audit de idempotență, corecție manuală.
FX_DRIFT: fixați politica sursei cursului de schimb (BCE/PSP/BANK), recalculați diferențele P&L.

13) Control și siguranță

Idempotența ingestiei: 'file _ id + checksum' și istoricul descărcărilor.
Access (RBAC) și 4-eye control: pentru corecții manuale/intrări jurnal.
Traseu de audit: toate meciurile/diffs/corecții - într-un jurnal neschimbabil.
Calitatea datelor: scheme, câmpuri obligatorii, validare valută/scară.

14) Tabloul de bord și alerte

Widget-uri: Auto-meci%, Rata de nepotrivire, Imbatranire DLQ, Decontare timp, Taxa de precizie, top PSP de diff, diff-tip hartă.

Alerte:
  • 'Auto-match% <90%' de către furnizor/zi → P1
  • 'Imbatranire p95> 3 zile' → P2
  • 'CUANTUM _ MISMATCH spike' → P1
  • 'Bank≠Settlement' după sumă/monedă → P0

15) Cazuri de testare (UAT/Prod)

1. Reîncărcarea aceluiași fișier → 0 efecte secundare (idempotență).
2. Refandurile parțiale (3 linii) → suma se potrivește, se potrivesc după secvență.
3. Conversia FX: discrepanța cursului de schimb în toleranța → potrivirea corectă.
4. Duplicați provider_txid în raport → dedup și alertă.
5. Captura lipsă a cârligului web → sondarea au închis decalajul, starea este aliniată.
6. Lot de decontare cu linie de taxare → defalcare corectă pe Venituri/Taxe/Net.

16) Greșeli frecvente și cum să evitați

Comparați „încercare” vs „captură” → păstrați aceeași granularitate.
Absența 'provider _ txid' în jurnalul → pierde acuratețea meciului.
Ignorați fusul orar → compensate de datele de decontare.
Nu există discrepanțe DLQ/retras → „eterne”.
Editări manuale fără un jurnal → neconcordanță cu auditul.
Toleranțele fuzzy → fie o re-meci sau „toate în DLQ”.

17) Lista de verificare a implementării

  • Schema de normalizare unificată și directoarele PSP/metodă/cont
  • Mapping Key Tree (txid → merchant_ref → fuzzy)
  • Suma/Toleranțe de timp/FX, Politica sursei cursului
  • Idempotent ingestie, DLQ, retrai, alerte
  • Reconcilierea Settlement↔Bank, Politica contului de suspans
  • Tablou de bord KPI, raportare financiară/audit
  • Playbooks și SLA defilare cazuri diff

Rezumat

Reconcilierea este o disciplină inginerească: normalizare, chei de încredere, toleranțe, meciuri automate și corecții transparente. Cu un astfel de contur, stabilizați veniturile și comisioanele, minimizați „găurile negre”, accelerați închiderea perioadei și vă auditați fără durere: Auto- match%↑, Mismatch↓, Aging↓.

Contact

Contactați-ne

Scrieți-ne pentru orice întrebare sau solicitare de suport.Suntem mereu gata să ajutăm!

Telegram
@Gamble_GC
Pornește integrarea

Email-ul este obligatoriu. Telegram sau WhatsApp sunt opționale.

Numele dumneavoastră opțional
Email opțional
Subiect opțional
Mesaj opțional
Telegram opțional
@
Dacă indicați Telegram — vă vom răspunde și acolo, pe lângă Email.
WhatsApp opțional
Format: cod de țară și număr (de exemplu, +40XXXXXXXXX).

Apăsând butonul, sunteți de acord cu prelucrarea datelor dumneavoastră.