Payments that never quite agree
Money passes through a payment provider, your application, a ledger somewhere, and finally a spreadsheet in finance. Each system is individually correct and collectively wrong. The symptom is always the same: a number that is off by a small amount and nobody can say which system is the liar.
The part that is actually hard
Webhooks are retried, reordered, and occasionally delivered twice with different payloads. Refunds arrive weeks after the charge. Currency rounding means the sum of the parts is not the total. Any reconciliation built on "process each event once" is wrong the first time the provider retries.
So the event log becomes the source of truth, keyed by the provider's own id, and the ledger is a projection of it. Reconciliation stops being a nightly prayer and becomes a query that either returns zero rows or pages someone.
What you get
- Idempotent webhook handler with a replay path
- Event log + ledger projection schema
- Daily reconciliation job with drift report
- Alerting on unmatched or stuck events
- Runbook for the 3am "numbers don't match" call