Ugo ChukwuAI & Financial Systems
← Work

Payments / Finance Operations

Multi-Processor Payment Reconciliation

A reconciliation architecture that normalises transactions, settlements, refunds, fees and payment events from multiple processors into a single auditable ledger — with automated matching, exception handling and a clear path into the accounting system.

StatusReference implementation
DomainPayments & finance ops
RoleArchitecture & build
Core stackPython · FastAPI · Postgres

01 — The problem

Money arrives in four shapes and no two systems agree on what happened.

A company taking payments through several processors ends up with several versions of the truth: a charge in one system, a payout in another, fees deducted somewhere in between, refunds and chargebacks arriving days later, and an accounting ledger that has to reflect all of it.

Finance closes the month by hand. Discrepancies are found late, if at all. Nobody can answer, quickly and defensibly, whether a given settlement is fully accounted for.

Cost of the gap

Manual close cycles that grow with volume rather than with headcount.

Risk

Unmatched settlements and silent fee drift that never reach the ledger.

Blocker

Audit questions that take days to answer because evidence is scattered.

02 — The system

One ledger every processor has to agree with.

Every processor event is pulled into a canonical transaction model — one shape, regardless of origin. Matching runs automatically against settlements and bank credits. Anything that doesn't match cleanly goes to an exception queue with the evidence attached, so a human resolves the case rather than hunting for it.

Multi-processor ingestion

Webhooks and scheduled pulls per processor, normalised on the way in.

Canonical transaction model

Charges, refunds, fees, payouts and adjustments in one vocabulary.

Automated matching

Deterministic rules first, tolerance windows second, human review last.

Fee & settlement reconciliation

Gross-to-net verified per payout, with fee drift surfaced explicitly.

Exception queue

Typed exceptions, ownership, resolution notes and a closing state.

Audit trail & accounting path

Every state change recorded; journal entries exported on a defined schedule.

03 — Architecture

How data moves

StripePayPalBank feedInternal billing
Ingestion layerwebhook verification · idempotency keys · raw event store
Canonical data modelpostgres · immutable event history
Matching & rules engineexact → tolerance → grouped → unmatched
Exception handlingtyped cases · owner · resolution audit
Reconciliation dashboardAccounting exportAlerts
Matching enginematch ratelive
processor events1 exception → reviewsettlements

04 — Engineering decisions

The choices that decide whether it survives contact with production.

Event-driven, not scheduled

Processor webhooks arrive continuously and out of order. Reacting to events keeps the ledger current and makes late-arriving refunds and chargebacks ordinary rather than exceptional. Scheduled sweeps remain as a backstop for missed events.

Postgres as the ledger

Financial reconciliation is relational and needs transactional guarantees, constraints and exact numeric types. Money is stored in minor units as integers; no floats touch a balance.

Idempotency everywhere

Every inbound event carries a processor-scoped key with a uniqueness constraint behind it. Replays are safe by construction rather than by convention — the single most important property in a system that receives money events twice.

Deterministic rules before models

Matching is rule-based and explainable. A probabilistic layer only assists on residual unmatched cases, and never auto-resolves — it ranks candidates for a reviewer.

Human review as a first-class state

The exception queue is part of the design, not an admission of failure. Every exception has a type, an owner, an age and a resolution record.

Append-only history

Corrections are new entries, never overwrites. The ledger can always be reconstructed as of any date — which is what an auditor actually asks for.

05 — Reliability & controls

What the system does when things go wrong.

Failure modeBehaviour
Processor API failureExponential backoff with jitter; circuit breaker after threshold; sync marked degraded, not silently skipped.
Duplicate eventsRejected at the uniqueness constraint and logged as a no-op; never double-counted.
Missing recordsGap detection against processor sequence and settlement totals; backfill job with a bounded window.
Partial failure mid-batchPer-record transactions; a poisoned record moves to the dead-letter table and the batch completes.
Invalid or unexpected dataSchema validation at the boundary; unknown fields preserved in the raw store for replay after a fix.
Nothing matchesException raised with the candidate set attached; alert fires when unmatched value or queue age crosses threshold.

06 — Evidence

Project statusReference implementation

Verified results

None published. This implementation has not been run against a named client's production ledger, and no client figures are claimed here.

Benchmarked results

  • Auto-match rate on the public test datasetmeasurement pending
  • Throughput per ingestion workermeasurement pending
  • Duplicate-event rejectionmeasurement pending

These metrics have not been measured yet. Nothing is claimed for them until a reproducible run exists.

Simulated results

Generated transaction sets with injected duplicates, late refunds, fee drift and missing settlements, used to exercise the matching and exception paths.

Projected business value

Modelled per company from close-cycle hours, unmatched settlement value and fee variance — calculated during the diagnostic, never quoted as an achieved result.

Verified, benchmarked, simulated and projected figures are kept separate on purpose. A benchmarked number is never presented as a verified client result.

07 — Technology

PythonFastAPIPostgreSQLSupabaseDockerGitHub ActionsREST APIs & webhooks

Technology supports the story. The architecture and the controls are the story.

Dealing with a similar problem?

I can help you decide what should be automated, what architecture makes sense, and whether the economics justify building it at all.

Book a Discovery Call