Architecture
High-level architecture of Payment Reconciler—components, data flow, and how they interact.
System overview
Payment Reconciler consists of:
| Component | Role |
|---|---|
| NestJS API | REST API for all operations. Handles tenants, expected/incoming transactions, matches, data sources, webhooks, jobs, users. |
| PostgreSQL | Primary data store. Prisma ORM. Separate databases for Payment Reconciler and LedgerMatch. |
| Redis | BullMQ job queues (domain-events, webhooks, etc.) and optional caching for matches/expected transactions. |
| LedgerMatch | External matching service. Takes incoming + expected candidates; returns ranked matches. REST (single-transaction) and gRPC (bulk). |
| Keycloak | Identity and access management. User provisioning, JWT issuance. |
| Ollama (optional) | Local embedding model for LedgerMatch when not using OpenAI. |
Data flow
1. Ingestion
- Expected transactions — Created via
POST /expected-transactions. - Incoming transactions — Created via API (manual), Stripe sync, CSV upload, or EBICS. Field mappings transform raw data for non-manual sources.
2. Matching
- LedgerMatch is invoked (auto-match on new incoming, manual trigger, or scheduled job).
- Payment Reconciler sends incoming + expected candidates to LedgerMatch.
- LedgerMatch returns ranked matches with confidence, embedding similarity, amount score, date score.
- Matches are stored with status PENDING. Auto-accept may run if confidence meets threshold.
3. Resolution
- Accept or reject matches via API.
- Accepting links incoming to expected; both become MATCHED.
- Rejecting leaves incoming available for other candidates or UNMATCHED.
4. Events and webhooks
- Domain events (incoming-transaction.created, match.created, etc.) are published to BullMQ.
- Domain-events processor enqueues webhook deliveries for subscribed webhooks.
- Webhook delivery jobs POST to subscriber URLs with event payloads.
Queues and jobs
| Queue | Purpose |
|---|---|
| domain-events | Domain events (incoming-transaction.created, match.created, etc.). Triggers webhook delivery and auto-match. |
| webhooks | Webhook delivery jobs. Retries on failure. |
| stripe-sync, matching, webhook-retry, cleanup | Scheduled or event-driven jobs. |
Jobs are scoped to tenant and environment. See Jobs for job types and triggers.
Multi-tenancy
All data (expected, incoming, matches, data sources, webhooks, jobs) is isolated per tenant and environment. API requests use X-Tenant-Id and X-Environment headers. Tenant assignment controls access per user.
Related pages
- Infrastructure — Services, ports, protocols
- Reconciliation — Reconciliation flow
- LedgerMatch Integration — REST vs gRPC, scoring