Skip to content

tusharui/payment-gateway

Repository files navigation

Payment Gateway

Production-grade payment processing infrastructure

Bun + TypeScript + PostgreSQL (Neon) + Redis

Tests TypeScript Bun


System Architecture

                        ┌─────────────────────────────────────────────┐
                        │              CLIENT LAYER                  │
                        │     API Key Auth + Rate Limiting (Redis)    │
                        └──────────────────┬──────────────────────────┘
                                           │
                        ┌──────────────────▼──────────────────────────┐
                        │             MIDDLEWARE PIPELINE             │
                        │  Zod Validation → Auth → Rate Limit → PCI  │
                        └──────────────────┬──────────────────────────┘
                                           │
              ┌────────────────────────────┼────────────────────────────┐
              │                            │                            │
    ┌─────────▼──────────┐   ┌─────────────▼──────────────┐   ┌────────▼────────┐
    │   PAYMENT SERVICE  │   │     FRAUD DETECTION        │   │   WEBHOOKS      │
    │                    │   │                            │   │                 │
    │  ┌──────────────┐  │   │  Velocity Check (Redis ZSET)│  │  Outbox Pattern │
    │  │ Idempotency  │  │   │  Amount Threshold           │  │  (PostgreSQL)   │
    │  │ (PostgreSQL) │  │   │  Source Reputation           │  │                 │
    │  └──────┬───────┘  │   │  Customer Blocking (PG)     │  │  Exponential    │
    │         │          │   └────────────────────────────┘   │  Backoff+Jitter │
    │  ┌──────▼───────┐  │                                    │                 │
    │  │ State Machine│  │                                    │  HMAC-SHA256    │
    │  │ (PG Transact)│  │                                    │  Signatures     │
    │  └──────┬───────┘  │                                    └────────┬────────┘
    │         │          │                                             │
    │  ┌──────▼───────┐  │                                    ┌────────▼────────┐
    │  │   Ledger     │  │                                    │   Dispatcher    │
    │  │ (Double-     │  │                                    │   (Background   │
    │  │  Entry, PG)  │  │                                    │    Worker)      │
    │  └──────────────┘  │                                    └─────────────────┘
    └────────────────────┘

    ┌─────────────────────────────────────────────────────────────────────────────┐
    │                           STORAGE LAYER                                     │
    │                                                                             │
    │   ┌─────────────────────────────┐     ┌──────────────────────────────────┐  │
    │   │       PostgreSQL (Neon)     │     │           Redis                  │  │
    │   │                             │     │                                  │  │
    │   │  Payments (ACID)            │     │  Distributed Locks (Lua CAS)     │  │
    │   │  Ledger Entries             │     │  Rate Limit Sliding Window       │  │
    │   │  Idempotency Keys           │     │  Fraud Velocity Tracking (ZSET)  │  │
    │   │  Webhook Outbox             │     │  API Key Cache                   │  │
    │   │  Blocked Customers          │     │  Circuit Breaker State           │  │
    │   └─────────────────────────────┘     └──────────────────────────────────┘  │
    └─────────────────────────────────────────────────────────────────────────────┘

What Each Pattern Solves

Pattern Problem Implementation
Idempotency Keys Duplicate requests on retry PostgreSQL upsert with unique constraint
Atomic State Machine Race conditions on status updates SELECT ... FOR UPDATE in PG transaction
Double-Entry Ledger Financial traceability Atomic CTE: compute balance → insert → return
Distributed Lock Concurrent payment processing Redis SET NX EX + Lua CAS release
Sliding Window Rate Limit API abuse Redis ZSET + ZREMRANGEBYSCORE
Velocity Fraud Detection Stolen card patterns Redis ZSET time-windowed counter
Outbox Pattern Lost webhook events PG transactional write → async dispatch
Exponential Backoff + Jitter Thundering herd on retries min(1000 * 2^attempts, 30s) + jitter
Circuit Breaker Cascading downstream failures Closed → Open → Half-Open state machine
PCI Security Headers Compliance Strict-Transport-Security, X-Content-Type-Options

Database Schema

-- Payment: core entity with optimistic locking via version column
Payment (id, idempotencyKey UNIQUE, status ENUM, amount, currency,
         customerId, paymentMethod, metadata JSONB, version, timestamps)

-- Ledger: double-entry bookkeeping with computed running balance
LedgerEntry (id, paymentId FK, type ENUM, account, amount,
             currency, balanceAfter, createdAt)

-- Idempotency: request deduplication
IdempotencyKey (key PK, paymentId, status, response JSONB, createdAt)

-- Webhooks: outbox pattern for reliable delivery
WebhookEvent (id, type, payload JSONB, status, attempts,
              createdAt, lastAttemptAt, nextRetryAt)

-- Fraud: blocked customer registry
BlockedCustomer (customerId PK, reason, blockedAt, expiresAt)

Quick Start

# Clone and install
git clone <repo-url> && cd payment-gateway
bun install

# Configure
cp .env.example .env
# Edit .env with your DATABASE_URL and REDIS_URL

# Push schema to PostgreSQL
bun run db:push

# Start server
bun run dev

# Run the full pipeline demo
bun run pipeline

API Reference

All endpoints require Authorization: Bearer sk_test_demo_key_00000000000000000000

# Health check (no auth required)
curl http://localhost:3000/health

# Create a payment
curl -X POST http://localhost:3000/v1/payments \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_test_demo_key_00000000000000000000" \
  -d '{
    "idempotencyKey": "idem_unique_123",
    "amount": 5000,
    "currency": "USD",
    "customerId": "cust_001",
    "paymentMethod": "card"
  }'

# Get payment status
curl http://localhost:3000/v1/payments/{id} \
  -H "Authorization: Bearer sk_test_demo_key_00000000000000000000"

# Refund a payment
curl -X POST http://localhost:3000/v1/payments/{id}/refund \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_test_demo_key_00000000000000000000" \
  -d '{ "amount": 2500 }'

# Prometheus metrics (no auth required)
curl http://localhost:3000/metrics

Demos

bun run pipeline    # 7 pipelines, 16 stages — see the full flow
bun run showcase    # Race conditions, attack simulation, refunds
bun run benchmark   # 1000 concurrent payments throughput test
bun run demo        # 12-step feature walkthrough

Project Structure

src/
├── config/         Environment variables, production guards
├── lib/
│   ├── redis.ts           Redis connection singleton
│   ├── prisma.ts          PostgreSQL client (Neon + Prisma 7)
│   ├── distributed-lock.ts  Redis lock with Lua CAS release
│   ├── circuit-breaker.ts   Failure detection + recovery
│   ├── metrics.ts          Prometheus counters + histograms
│   └── logger.ts           Structured JSON logging (pino)
├── middleware/
│   ├── api-key.ts        Bearer token authentication
│   ├── rate-limit.ts     Sliding window (Redis ZSET)
│   ├── validation.ts     Zod schema validation
│   ├── security.ts       PCI compliance headers
│   └── errors.ts         Typed error codes
├── modules/
│   ├── payment/
│   │   ├── state-machine.ts    Atomic status transitions (PG tx)
│   │   ├── idempotency.ts      Request deduplication
│   │   └── payment-service.ts  Orchestration layer
│   ├── ledger/
│   │   └── ledger.ts           Double-entry with atomic balance
│   ├── fraud/
│   │   └── fraud.ts            Velocity + amount + source checks
│   └── webhook/
│       ├── outbox.ts           PG-backed event queue
│       └── dispatcher.ts       HMAC-signed delivery
├── index.ts          Server entry point
└── worker.ts         Background webhook processor

Tech Stack

Layer Technology Why
Runtime Bun 4x faster startup, native TypeScript, built-in test runner
Language TypeScript (strict) Type safety, better DX, self-documenting
Database PostgreSQL (Neon) ACID transactions, JSONB, ENUM types, foreign keys
ORM Prisma 7 Type-safe queries, migrations, introspection
Cache/Queue Redis Sub-ms latency, Lua scripts, sorted sets
Validation Zod Runtime + compile-time type safety
Logging pino Structured JSON, fast, child loggers
IDs nanoid URL-safe, collision-resistant, 21 chars

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages