payments-core is a ledger-first payments platform demo that models core PSP behaviors with strong correctness guarantees:
- immutable double-entry ledger posting
- idempotent write APIs
- async webhook processing with retries and DLQ
- reconciliation for operational safety
- metrics and a control-plane dashboard for demo and debugging
The project is designed to feel like a compact internal fintech operations system rather than a toy CRUD app.
- Multi-currency account model (USER, MERCHANT, ESCROW)
- Double-entry transactions (
DEPOSIT,TRANSFER,HOLD_CAPTURE) - Balance derivation from ledger state (
posted,held,available) - Idempotency keys for write safety and replay consistency
- Hold authorize/capture/release flow
- Escrow movements tied to hold capture
- State invariants checked by reconciliation
- Webhook ingest endpoint with deduplication
- Asynchronous worker processing via Celery + Redis
- Exponential backoff retries:
1, 2, 4, 8, 16seconds - Dead-letter queue after max retries
- Replay endpoints for failed/DLQ events
- Failure injection for deterministic reliability demos
- On-demand reconciliation run endpoint
- Persisted reconciliation history in
reconcile_runs - Anomaly detection for ledger/holds/webhooks/DLQ consistency
- Prometheus metrics endpoint (
/metrics) - Dashboard control center with live operational KPIs
- React + Vite + TypeScript dashboard
- Unified component system (cards, tables, badges, modals, notices)
- Polling for async-sensitive pages (visibility-aware)
- Page set: Overview, Accounts, Account Detail, Transactions, Holds, Webhooks, DLQ, Reconciliation
Run-time services are composed via Docker:
backend: FastAPI API serverworker: Celery worker for async webhook processingpostgres: relational storageredis: queue/broker for async jobsdashboard: React SPA
High-level flow:
- API write request comes in with idempotency key.
- Backend posts ledger entries atomically.
- Webhook events are ingested and queued.
- Worker processes events with retry + DLQ policy.
- Reconciliation validates consistency and stores report.
- Metrics and dashboard expose operational state.
See ARCHITECTURE.md for additional context.
- Docker + Docker Compose
- Optional: copy
.env.exampleto.envand adjust values. - Run:
make up- Open:
- Dashboard:
http://localhost:5174 - API:
http://localhost:18000 - Health:
http://localhost:18000/health
make upstart all services in detached modemake downstop servicesmake migrateapply Alembic migrations in backend containermake reset-dbdrop Postgres volume and rebuild stackmake seedcall demo reset endpointmake smokerun full end-to-end smoke verification
GET /accountsPOST /accountsGET /accounts/{id}GET /accounts/{id}/statement
POST /transfers(idempotent)GET /transactionsGET /transactions/{id}
POST /holds/authorizePOST /holds/{id}/capturePOST /holds/{id}/releaseGET /holds
POST /webhooks/gatewayGET /webhooks/eventsPOST /webhooks/events/{event_id}/replayGET /dlqPOST /dlq/{event_id}/replayPOST /demo/inject-failure
POST /reconcile/runGET /reconcile/latestGET /demo/statsGET /metrics
See API.md for full contracts and examples.
Each reconciliation run checks:
- debit/credit balance per transaction
- transaction currency vs ledger entry currency
- hold state integrity
- negative available balances for non-system accounts
- webhook state anomalies (including stale processing)
- webhook/DLQ cross-state anomalies
Runs are persisted and latest report is queryable.
Prometheus metrics include webhook lifecycle, DLQ activity, idempotency replay counts, reconciliation runs, and runtime gauges such as active holds and processing webhook count.
Primary scrape endpoint:
GET /metrics
For a scripted walkthrough and expected outputs:
For an automated confidence check:
make smokeSmoke covers reset, transfers, holds, webhooks, DLQ, reconciliation, and metrics validation.
Important env vars (see .env.example):
PAYMENTS_BACKEND_PORTPAYMENTS_DASHBOARD_PORTPAYMENTS_POSTGRES_PORTPAYMENTS_REDIS_PORTPAYMENTS_DEMO_SECRET(used by backend/worker/dashboard in compose)
Demo secret notes:
- Local demo: a shared secret is fine.
- Public deployment: do not rely on browser-exposed shared demo secrets.
- Prefer server-side auth/authorization for privileged demo/admin actions.
backend/FastAPI app, services, models, migrations, testsdashboard/React TypeScript UIinfra/Docker Compose topologyscripts/smoke and helper scriptsAPI.mdendpoint-level documentationARCHITECTURE.mdarchitecture overviewDEMO_SCRIPT.mddemo runbook
- Backend tests under
backend/tests/ - Reconciliation-specific tests included
- Dashboard build checked with
npm run build - Full-stack smoke path available via
make smoke
This project is released under the terms in LICENSE.