Skip to content

GeroJun/payment-reconciliation-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Payment Reconciliation Engine

A Node.js backend project built to understand payment systems, distributed architecture, and AWS services. This system demonstrates core concepts like async processing, idempotency, and double-entry ledgers, which are patterns used in production payment systems.

What I Built

  • RESTful API for transaction processing
  • Double-entry ledger for financial accuracy
  • Redis-based idempotency handling
  • AWS SQS integration for async processing
  • PostgreSQL for persistent storage

What I Learned

  • How distributed systems handle failures
  • Why idempotency matters for financial systems
  • The tradeoffs between sync vs async APIs
  • How to design APIs that handle retries safely

Features

  • Real-Time Reconciliation: Detects and resolves inconsistencies across payment transactions instantly.
  • Idempotency Handling: Ensures repeat operations (e.g., webhook retries) do not create duplicates using Redis cache.
  • Double-Entry Ledger: Follows best practices for accounting and transaction auditing.
  • Discrepancy Detection: Flags missing, mismatched, or erroneous transactions.
  • Asynchronous Processing: AWS SQS integration for distributed, scalable transaction processing.
  • Cloud-Native Design: Built for AWS with monitoring, health checks, and readiness probes.
  • Docker Support: Rapid local deployment and isolation using Docker & Docker Compose.
  • Configurable Schema: Tweak the core accounting and transaction schema to fit enterprise needs.

High-Level Design

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Client    β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚ HTTP Request
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Express API Server (Port 3000)  β”‚
β”‚  - Route handlers                β”‚
β”‚  - Auth middleware               β”‚
β”‚  - Input validation              β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚              β”‚
       β”‚ Cache check  β”‚ Async publish
       β–Ό              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ Redis  β”‚    β”‚ AWS SQS  β”‚
   β”‚ Cache  β”‚    β”‚ (FIFO)   β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                      β”‚
                      β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚ Background Workers   β”‚
            β”‚ (Processing messages)β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
                      β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ PostgreSQL DB    β”‚
              β”‚ - Transactions   β”‚
              β”‚ - Ledger entries β”‚
              β”‚ - Audit trail    β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Components

Component Purpose AWS Service
API Server Handles HTTP requests, validates input, manages auth Application
SQS Queue Async transaction processing, decouples API from workers AWS SQS (FIFO)
Redis Cache Idempotency key storage, fast duplicate detection ElastiCache/local
PostgreSQL Primary database for ledger, transactions, audit logs RDS/local
Background Workers Processes SQS messages, updates database Lambda/EC2
CloudWatch Monitoring, logging, metrics AWS CloudWatch

Key Endpoints

Transaction Processing (Async via SQS)

# 1. Submit transaction (returns immediately with 202)
curl -X POST http://localhost:3000/api/v1/transactions \
  -H "Authorization: Bearer demo-token-for-testing" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction": {
      "source_account_id": "account-123",
      "destination_account_id": "account-456",
      "amount": 100.00
    },
    "idempotencyKey": "unique-key-12345"
  }'

# Response: 202 ACCEPTED
{
  "status": "ACCEPTED",
  "idempotencyKey": "unique-key-12345",
  "messageId": "msg-id-xyz",
  "pollUrl": "/api/v1/transactions/status/unique-key-12345",
  "expiresAt": "2026-01-09T23:13:00.000Z"
}

# 2. Poll for completion
curl http://localhost:3000/api/v1/transactions/status/unique-key-12345 \
  -H "Authorization: Bearer demo-token-for-testing"

# Response: Processing...
{ "status": "PROCESSING", "idempotencyKey": "unique-key-12345" }

# Response: Complete
{
  "status": "COMPLETED",
  "result": {
    "id": 1,
    "source_account_id": "account-123",
    "destination_account_id": "account-456",
    "amount": 100.00,
    "status": "COMPLETED",
    "created_at": "2026-01-09T02:13:00.000Z"
  }
}

Queue Monitoring

# Check SQS queue stats
curl http://localhost:3000/api/v1/queue/stats \
  -H "Authorization: Bearer demo-token-for-testing"

# Response
{
  "queueUrl": "https://sqs.us-east-1.amazonaws.com/account/queue.fifo",
  "messageCount": 5,
  "inFlightCount": 2,
  "visibilityTimeout": 60,
  "isFifo": true,
  "contentDeduplication": true,
  "timestamp": "2026-01-09T02:13:00.000Z"
}

Idempotency & Cache

# Check cache stats
curl http://localhost:3000/api/v1/cache/stats \
  -H "Authorization: Bearer demo-token-for-testing"

# Response
{
  "connected": true,
  "totalKeys": 10,
  "prefix": "idempotency:",
  "defaultTtl": 86400,
  "memoryUsage": "2.5K",
  "timestamp": "2026-01-09T02:13:00.000Z"
}

Health & Readiness Checks

# Liveness probe
curl http://localhost:3000/api/v1/health

# Readiness probe (checks all dependencies)
curl http://localhost:3000/api/v1/ready

# Response
{
  "status": "READY",
  "components": {
    "database": "ready",
    "cache": "ready",
    "queue": "ready"
  }
}

πŸ“Έ Project Showcase

Server Running & Health Check

Health check endpoint confirms server and all dependencies are ready

The /api/v1/ready endpoint verifies database, cache, and SQS queue connectivity

Create Transaction (Async via SQS)

POST /transactions returns 202 ACCEPTED with polling URL

Transaction submitted to SQS queue. API returns immediately with polling URL. Workers process in background.

Idempotency Test

Duplicate request with same idempotencyKey returns cached result

Duplicate request detected via Redis cache. Prevents duplicate charges on webhook retries.

Get Account Balance

GET /accounts/:id/balance returns current balance after processing

Account balance calculated from double-entry ledger after all transactions processed.

Get Ledger History

GET /accounts/:id/ledger returns paginated transaction history

Full audit trail of all account transactions with pagination support.


Usage

Basic Workflow

  1. Submit Transactions:

    curl -X POST http://localhost:3000/api/v1/transactions \
      -H "Authorization: Bearer demo-token-for-testing" \
      -H "Content-Type: application/json" \
      -d '{ "transaction": {...}, "idempotencyKey": "..." }'
  2. Poll for Completion:

    curl http://localhost:3000/api/v1/transactions/status/:idempotencyKey \
      -H "Authorization: Bearer demo-token-for-testing"
  3. Check Account Balance:

    curl http://localhost:3000/api/v1/accounts/:accountId/balance \
      -H "Authorization: Bearer demo-token-for-testing"
  4. Run Reconciliation:

    curl -X POST http://localhost:3000/api/v1/accounts/:accountId/reconcile \
      -H "Authorization: Bearer demo-token-for-testing" \
      -H "Content-Type: application/json" \
      -d '{ "startDate": "2026-01-01", "endDate": "2026-01-31" }'
  5. Monitor System Health:

    curl http://localhost:3000/api/v1/ready \
      -H "Authorization: Bearer demo-token-for-testing"

Project Structure

.
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ controllers/           # Route/controller logic
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ transactionProcessor.js      # Core transaction logic
β”‚   β”‚   β”œβ”€β”€ reconciliationService.js     # Reconciliation engine
β”‚   β”‚   β”œβ”€β”€ ledgerManager.js             # Double-entry ledger
β”‚   β”‚   β”œβ”€β”€ sqsProducer.js               # SQS queue integration
β”‚   β”‚   └── idempotencyCache.js          # Redis cache layer
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   └── routes.js                    # Express route definitions
β”‚   └── utils/
β”‚       β”œβ”€β”€ validation.js     # Input validation
β”‚       β”œβ”€β”€ auth.js           # Auth middleware
β”‚       └── logger.js         # Structured logging
β”œβ”€β”€ init.sql                  # PostgreSQL schema & migrations
β”œβ”€β”€ Dockerfile                # Node.js app container
β”œβ”€β”€ docker-compose.yml        # Orchestrates app + DB + Redis
β”œβ”€β”€ package.json              # Dependencies & scripts
β”œβ”€β”€ .env.example              # Environment variables template
└── README.md                 # This file

About

Real-time payment reconciliation engine built with Node.js & PostgreSQL. Handles idempotency, double-entry ledger, and discrepancy detection for payment systems

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors