Payment success nie oznacza reconciliation success
Płatność może mieć status paid i nadal być operacyjnie niewyjaśniona. Customer mógł zapłacić poprawnie, ale provider fee jest brakujące, settlement opóźniony, refund nie został zaksięgowany albo internal ledger zawiera duplicate credit.
Reconciliation odpowiada na inne pytanie niż payment processing:
Czy wszystkie systemy opisujące ten lifecycle wartości się zgadzają — a jeśli nie, czy potrafimy dokładnie wyjaśnić dlaczego?
Pięć warstw reconciliation
1. Business obligation
Invoice, order, subscription lub payment intent: expected amount, currency, customer i due/expiry context.
2. External execution evidence
Managed: provider order, transaction i provider ledger. Custom: blockchain transaction, token, network, address i confirmation/finality evidence.
3. Internal product ledger
Accepted business credit/debit entries, fees, refunds i adjustments.
4. Settlement lub treasury movement
Managed: provider conversion, payout lub withdrawal. Custom: sweep, treasury transfer, off-ramp lub liquidity movement.
5. Bank/accounting evidence
Przy fiat settlement bank records i accounting exports zamykają operacyjną pętlę.
Correlation identifiers są fundamentem
Każda warstwa potrzebuje deterministycznej referencji. Dobry łańcuch to invoiceId → paymentIntentId → providerOrderId/txHash → ledgerEntryId → settlementBatchId. Brak correlation keys jest jednym z najdroższych błędów, bo finance musi wtedy wnioskować z amounts i timestamps.
Uzgadniaj movements, nie tylko balances
Dwa end-of-day balances mogą być równe, mimo że pojedyncze transakcje są błędne. Najpierw uzgadniaj individual value movements, później totals.
Dla każdej płatności porównuj:
- expected gross amount,
- actual customer payment,
- accepted product credit,
- provider/network fee,
- refundy,
- net settlement lub treasury movement.
Managed provider reconciliation
Przy CoinGate provider order i provider ledger traktuj jako osobne źródła evidence. Ledger transaction API pokazuje credits/debits i pozwala filtrować po dacie, walucie, type i source. To lepsza baza dla scheduled reconciliation niż sama historia webhooków.
Managed reconciliation job może:
- pobrać product payments z okna czasowego,
- pobrać CoinGate orders/ledger transactions,
- matchować po provider order/source reference,
- porównać gross, received, fee, refund i settlement,
- utworzyć exceptions,
- zamknąć reconciliation window dopiero zgodnie z polityką unresolved exceptions.
Custom on-chain reconciliation
Przy direct wallet infrastructure porównuj product ledger z niezależnie obserwowanymi chain transactions. Nie wystarczy current wallet balance. Odtwarzaj zestaw transakcji z block range/checkpoint i weryfikuj token contract, network, receiving address, amount i finality.
Downstream sweeps i treasury movements uzgadniaj osobno. Failed sweep powinien być treasury exception, nie customer-payment mismatch.
Typowe mismatch classes
| Mismatch | Przykład | Owner |
|---|---|---|
| Missing external payment | Ledger credit istnieje, provider/chain evidence brak | Engineering / risk |
| Missing ledger credit | Provider paid, produkt nie credited | Product operations |
| Amount mismatch | Underpayment, overpayment, FX lub fee | Finance / operations |
| Settlement mismatch | Paid orders nie zgadzają się z payout batch | Finance |
| Refund mismatch | Refund completed external, ledger bez adjustment | Operations / finance |
| Duplicate effect | Jeden external event utworzył dwa credits | Engineering |
Zbuduj exception queue
Nie rób z reconciliation boolean report. Stwórz first-class exception entity z type, expected, observed, references, severity, owner, status, notes i resolution history.
To zamienia financial operations w mierzalny workflow zamiast inboxa screenshotów.
Webhook processing i reconciliation muszą być niezależne
Real-time callbacks optymalizują responsiveness. Reconciliation optymalizuje correctness. Jeśli callback failuje i zostanie replayed później, scheduled reconciliation nadal powinno wykryć payment istniejący external, ale brakujący internal.
Przykład daily close
- Zamknij reconciliation window.
- Zaimportuj provider ledger lub przeskanuj chain range.
- Matchuj external movements do payment intents i ledger entries.
- Uzgodnij fee/refunds.
- Match settlement batch lub treasury sweep.
- Match bank payout, jeśli dotyczy.
- Otwórz exceptions.
- Zapisz close summary z counts i totals.
Metryki
- unreconciled payment count,
- unreconciled value,
- oldest open exception,
- duplicate-event prevention count,
- provider/chain ingestion lag,
- settlement variance,
- refund reconciliation lag.
Relacja z internal ledgerem
Reconciliation jest tak dobre, jak ledger, który audytuje. Jeśli produkt nadal opiera się na mutable balances, zacznij od modelu internal ledger.
Reconciliation windows i late events
Zdefiniuj jawne reconciliation windows zamiast zakładać, że midnight-to-midnight zawsze jest poprawne. Provider settlement cut-offs, blockchain finality i bank posting times mogą przekraczać granice dnia. Utrzymuj status okna, np. OPEN, PROCESSING, EXCEPTIONS, CLOSED i REOPENED, żeby obsługiwać late evidence bez nadpisywania historii.
Gross-to-net reconciliation
Przy provider-managed settlement jawnie uzgadniaj równanie: gross accepted value minus provider fees minus refunds plus/minus udokumentowane adjustments = expected net settlement dla batch/period. Przy FX conversion zachowuj conversion evidence i odróżniaj commercial price od settlement value.
Operational ownership
Każdy mismatch class powinien mieć owner i SLA. Engineering odpowiada za missing/duplicated ingestion; operations za payment/customer investigations; finance za settlement i accounting discrepancies; compliance/risk może odpowiadać za invalid lub screened payments. Exception queue powinien routować według tych zasad.
Reconciliation jako regression test
Historyczne reconciliation windows można replayować w staging przeciwko nowemu kodowi. To tworzy wartościowy regression dataset dla provider adapters i chain observers, bo expected financial outcome jest już znany.
Podsumowanie
Celem reconciliation nie jest tylko „liczby się zgadzają”. Celem jest explainability: każda płatność ma mieć traceable story od zobowiązania handlowego, przez execution, product credit, fee/refundy aż po final settlement.