Verifica dei pagamenti e dei rapporti PSP
TL; DR
Il comprimario è una combinazione automatizzata giornaliera del tuo programma e degli eventi (auth/capture/refund/payout) con report PSP/Equyer/Banche. La chiave per il successo è un unico modello di dati, chiavi di mappatura determinate, idampotenza rigorosa, tolerance di somma/FX/tempo, coda DLQ per valigette controverse e playbook di correzioni automatiche. KPI: Recon Mismatch Rate↓, Aging of Unreconciled↓, Auto-match%↑.
1) Perché e cosa stiamo controllando
Obiettivi: conferma dei ricavi e delle commissioni, rilevamento delle riprese/perdite, settement corretto per giorni e valute, controllo refund-to-source, conformità a controllo/regolatore.
Oggetti di riconciliazione:- Deposits: `auth → capture → settle`
- Rifunds: full/partial, states e importi
- Payouts/Withdrawals: pagamenti in uscita con metodi
- Fees & Adjustments: commissioni PSP, diagrammi di interscambio, correzioni
- Marcebacks/Disputs: fuori dalla tua iniziativa
- FX/Conversioni: corsi, spread, momento di fissazione
2) Origini dati
Internal Events: bus di eventi/Kafka, 'payments _ flat', 'refunds',' payouts ',' Ledger '.
PSP Reports (SFTP/API/webhook dump):- Transazioni (estratti conto operativo)
- Settlements/Batches (divise delle iscrizioni T + N)
- Fees/Statents (commissioni, regolazioni)
- Chargebacks/Disputes
- Registrazioni Payouts/OCT/RTP/SEPA
- Banca Statents: MT940/CSV/ISO20022 CAMT, lifting delle iscrizioni.
3) Chiavi di mappatura (matching keys)
Struttura chiave prioritaria (decrescente):1. provider _ txid ↔ provider _ txid (ID PSP univoco)
2. idempotency _ key/merchant _ reference (se stabile in PSP)
3. (amount, currency, timestamp_bucket, last4/bin, auth_code)
4. Livello fuzzy: © tolerans per somma/tempo, BIN/issuer country, status family
Raccomandazioni:- Memorizzate entrambi: payment _ id e provider _ txid.
- Per partial/refund - Aggiungi sequence _ index o refund _ line _ id.
- Для payouts — `payout_batch_id + line_id`.
- Per FX - 'exec _ id' (conversione) e l'origine del corso.
4) Modello dati (livello normalizzato)
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) Processo di riconciliazione (ETL/orchestrazione)
1. Ingest - Raccogliamo i report PSP (SFTP/API), valutiamo lo schema/le firme, e salviamo in raw.
2. Normalize: mappim dei campi in formato unificato (currency ISO, decimals, timesone UTC).
3. Match: algoritmo di mappatura dell'albero delle chiavi con tolerance.
4. Post-match - Generiamo differenze (soluzione temporanea) e journal entries per le patch/correzioni.
5. Settle: cuciamo «PSP _ SETTLEMENT» (Accessi al conto), distribuiamo i giorni/battelli.
6. Report: dashboard, alert; Discusso nel DLQ per analisi manuale/autoregolamentazione.
Idempotenza: per ogni file/pagina, 'ingest _ id'. Il nuovo caricamento non modifica il risultato.
6) Tolerance e regole
Tempo: '© 15 min'per le transazioni,' © 1 dn'per il settlement.
Importo: '≤ 0. 01 "valuta di base o" 10 bps "per FX/fee-one.
FX: consentiamo la risoluzione con la banca se l'origine del tasso di cambio è diversa; fissiamo «fx _ src».
Partial/Multiple: l'importo delle linee partial/refund deve essere uguale al saldo interno.
7) Gestione delle soluzioni temporanee (differf tassonomy)
8) Ledger & Accounting (cavi)
Capture: `DR Accounts Receivable / CR Revenue` и `DR Cash (upon settle) / CR Accounts Receivable`
Fee: `DR Fees / CR Cash or Payable`
Rifund: cablaggio inverso proporzionale a partial
Marceback: conti separati e riserva per controversie
FX reval - Rivalutazione giornaliera del residuo AR/cache nel corso dì fx _ src _ policy "
9) KPI e obiettivi
Auto-match% = righe mappate automaticamente/tutte le righe (obiettivo 95%)
Recon Mismatch Rate = righe differenti/tutte le righe (≤ 1-2%)
Aging of Unreconciled: p50/p95 giorni in DLQ (p95-3 giorni)
La percentuale di battaglie cucite con la banca D-day (≥ 99%)
Fee Accuracy - Risoluzione delle commissioni per i provider (≤ 0. 1% del giro d'affari)
Duplicato/Orphan Incidents: cerca 0
10) Tagli SQL
10. 1 Mappatura base provider _ txid
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 Settlement ↔ Bank
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 Aging DLQ
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) Caratteristiche dei binari/valigette
Mappe: differenze tra «auth» e «capture», regolazioni tardive «settlement», interchange/schemi - linee separate.
A2A/Open Banking/RTP: conferme immediate, ma possibili «reversal»; incrociate «payout» e i rimborsi.
Portafogli: spesso perfetti «provider _ txid», veloci «refund»; Tenere traccia delle linee fee.
Voucher: nessun refund simmetrico - Rifletti correttamente in regole e report.
Kripto: è-chain hash-provider _ txid; conferme N; Registrazione delle commissioni di rete e dei possibili rebake corso - al momento della conversione.
12) Playbook operativi
Esplode MISSING _ INTERNAL: controlla la perdita di webhoop/retrai, sovrastampa, attiva il polling API.
AMOUNT _ MISMATCH in un singolo PSP: confronta arrotondamenti/IVA/fee-model e richiedi uno statement di correzione.
Settlement non si allinea con la banca: verifica value date, commissione della banca, ritardi T + N; Scommettere temporaneamente su «Account Suffense».
RIFUND _ OVER di massa: immediata interruzione dei rifandi automatici, controllo dell'idimpotenza, correzione manuale.
FX _ DRIFT - Fissa il policy della sorgente di rotta (ECB/PSP/BANK), ricalca la differenza P&L.
13) Controllo e sicurezza
Idempotence ingestione: 'file _ id + checksum'e registro dei download.
Disponibilità (RBAC) e controllo a 4 occhi per regolazioni manuali/cablaggi di registro.
Controllo-trail: tutte le partite/difas/correzioni sono invariate.
Qualità dei dati: schemi, campi obbligatori, valuta valuta/scale.
14) Dashboard e gli alerti
Widget: Auto-match%, Mismatch Rate, Aging DLQ, Settement Timelover, Fee Accuracy, Top PSP per Difas, mappe di tipo differente.
Alert:- 'Auto-match% <90%' per il provider/giorno di → P1
- "Aging p95> 3 d → P2
- `AMOUNT_MISMATCH spike` → P1
- «Bank≠Settlement» per importo/valuta → P0
15) Valigette di prova (UAT/Prod)
1. Ricaricare lo stesso file con 0 effetti collaterali (idampotenza).
2. Rifandi parziali (3 linee) la somma corrisponde, partita sequence.
3. Conversione FX - La variazione di rotta all'interno del tolerance è un match corretto.
4. Provider _ txid duplicati nel report → e alert.
5. Il Web capture mancante ha chiuso il gap e lo stato è allineato.
6. Il batch Settlement con la linea fee è correttamente suddiviso in Revenue/Fee/Net.
16) Errori frequenti e come evitare
Miscelare le basi di confronto (compare «attempt» vs «capture») mantenendo la stessa granolarità.
L'assenza dì provider _ txid "nella casella di controllo perde la precisione del match.
Ignora il timesone di spostamento in base alle date del settement.
Non ci sono DLQ/retrai per le discrepanze «eterne».
Le modifiche manuali senza registro consentono di non accedere all'udienza.
I tolerance impreziositi sono o una penna o «tutti nel DLQ».
17) Check-list di implementazione
- Un unico schema di normalizzazione e manuali PSP/metodi/account
- Albero chiavi mappatura (txid → merchant _ ref → fuzzy)
- Tolerance per somma/ora/FX, criterio di origine del corso
- Idempotente ingestione, DLQ, retrai, alert
- , Criteri di accesso
- Dashboard KPI, report per la finanza/verifica
- Playbook e SLA di analisi delle valigette differenti
Riepilogo
La combinazione è una disciplina ingegneristica: normalizzazione, chiavi affidabili, tolerance, partite automatiche e regolazioni trasparenti. Con questo tracciato si stabilizzano i ricavi e le commissioni, si minimizzano i buchi neri, si accelera la chiusura del periodo e si esegue un controllo senza dolore.