Skip to content

Cross-border payment orchestration API — strict state machine, real-time FX conversion, IBAN/SWIFT validation, and OFAC/EU sanctions screening. The framework that became OBELISK.

Notifications You must be signed in to change notification settings

HWyn2020/CrossPay_Engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CrossPay Engine

Cross-border payment orchestration API. Multi-currency processing, real-time FX conversion, OFAC/EU sanctions screening, IBAN/SWIFT validation, and full payment lifecycle management through a strict state machine.

Architecture

                          ┌──────────────────────────────────────┐
                          │           CrossPay Engine            │
                          │                                      │
  Client ──> Fastify API ─┤  ┌─────────────────────────────────┐ │
             (rate limit,  │  │       Payment Engine            │ │
              auth, CORS)  │  │                                 │ │
                          │  │  INITIATED ──> VALIDATED ──> ... │ │
                          │  │       State Machine              │ │
                          │  └────┬──────┬──────┬──────────────┘ │
                          │       │      │      │                │
                          │  ┌────▼──┐ ┌─▼────┐ ┌▼───────────┐  │
                          │  │  FX   │ │Sanc- │ │ IBAN/SWIFT  │  │
                          │  │Service│ │tions │ │ Validator   │  │
                          │  └───┬───┘ └──────┘ └─────────────┘  │
                          │      │                               │
                          │  ┌───▼───────────────────────┐       │
                          │  │  PostgreSQL + Redis        │       │
                          │  │  (payments, audit, cache)  │       │
                          │  └───────────────────────────┘       │
                          └──────────────────────────────────────┘

Payment Lifecycle

Every payment moves through a strict state machine. Invalid transitions are rejected.

INITIATED ──> VALIDATED ──> SCREENED ──> QUOTED ──> CONFIRMED ──> PROCESSING ──> SETTLED ──> COMPLETED
                │              │           │
                ▼              ▼           ▼
            REJECTED         HELD      EXPIRED
                              │
                              ▼
                         REJECTED or SCREENED (after review)

Additional states: CANCELLED (user-initiated), FAILED (processing error, retryable), REFUNDED (post-settlement reversal).

Stack

Component Technology Why
Runtime Node.js 20 Non-blocking I/O for concurrent payment processing
Framework Fastify 5 2x throughput vs Express, schema validation, plugin architecture
Database PostgreSQL 16 JSONB for flexible party data, ACID for financial transactions
Cache Redis 7 FX rate caching, idempotency key dedup
Validation Zod Runtime type checking, schema inference, better errors than Joi
Logging Pino Structured JSON, PII redaction, 5x faster than Winston
Security Helmet, CORS, rate-limit Defense in depth
Containers Docker + Compose Reproducible local dev, production parity
CI/CD GitHub Actions Automated test + security audit + deploy

API Endpoints

Payments

Method Endpoint Description
POST /api/v1/payments Create payment
GET /api/v1/payments/:id Get payment details
POST /api/v1/payments/:id/validate Validate IBAN/SWIFT/amounts
POST /api/v1/payments/:id/screen Run sanctions screening
POST /api/v1/payments/:id/quote Get FX quote (30s TTL)
POST /api/v1/payments/:id/confirm Confirm at quoted rate
POST /api/v1/payments/:id/process Submit to banking network
POST /api/v1/payments/:id/cancel Cancel (from eligible states)

Utilities

Method Endpoint Description
GET /api/v1/fx/:from/:to Live FX rate lookup
GET /api/v1/validate/iban/:iban IBAN validation with checksum
GET /api/v1/validate/swift/:bic SWIFT/BIC format validation

System

Method Endpoint Description
GET /health Liveness probe
GET /ready Readiness probe (checks DB)
GET /metrics System metrics

Create Payment Example

curl -X POST http://localhost:3000/api/v1/payments \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000.00,
    "sendCurrency": "USD",
    "receiveCurrency": "EUR",
    "sender": {
      "name": "Acme Corp",
      "iban": "GB29 NWBK 6016 1331 9268 19",
      "swift": "NWBKGB2L",
      "country": "GB"
    },
    "beneficiary": {
      "name": "Schmidt GmbH",
      "iban": "DE89 3704 0044 0532 0130 00",
      "swift": "DEUTDEFF",
      "country": "DE"
    },
    "purpose": "Invoice #INV-2026-0142",
    "idempotencyKey": "unique-client-key-123"
  }'

IBAN Validation

Full ISO 7064 Mod 97-10 checksum verification with country-specific length enforcement.

Supported: 60+ countries (AL, AD, AT, AZ, BH, BY, BE, BA, BR, BG, ...)
Extracts: Country code, check digits, BBAN, bank identifier

Sanctions Screening

Screens sender and beneficiary against OFAC SDN and EU consolidated lists.

Match types:
  EXACT   (confidence 1.0)   - Direct name match
  FUZZY   (confidence 0.80+) - Levenshtein distance
  PARTIAL (confidence 0.65)  - Word-level overlap
  
Features:
  - Unicode normalization (accents, diacritics)
  - Alias matching
  - Case insensitive
  - Country pre-filtering

Security

  • Fastify Helmet (CSP, HSTS, X-Frame-Options)
  • Rate limiting (100 req / 15 min per IP)
  • API key authentication (SHA-256, timing-safe comparison)
  • Zod input validation on all endpoints
  • Parameterized SQL queries (injection prevention)
  • Structured logging with PII field redaction
  • Non-root Docker container
  • Health checks with dependency verification

Database Schema

6 versioned migrations:

  1. payments - Core payment table with state enum, JSONB party data, partial indexes
  2. payment_audit_log - Every state transition logged with actor and metadata
  3. fx_rates - Cached exchange rates with expiry
  4. idempotency_keys - Request deduplication with TTL
  5. webhook_deliveries - Outbound webhook tracking with retry queue
  6. cleanup_procedures - DB functions for TTL expiry and key cleanup

Testing

npm test                  # Unit + integration tests
npm run test:adversarial  # Security/adversarial tests

The adversarial suite documents every confirmed vulnerability with severity, risk description, and proposed fix. See tests/adversarial.test.js for the full report.

Quick Start

# Local development with Docker
cd docker && docker compose up -d

# Or manual setup
cp .env.example .env     # Edit credentials
npm install
npm run db:migrate
npm start

Known Limitations

Documented in tests/adversarial.test.js:

  • No row-level locking on state transitions (double-spend risk in concurrent scenarios)
  • Sanctions screening uses demo list (production requires OFAC SDN feed integration)
  • No SSRF protection on webhook URLs
  • BBAN structure not validated per-country
  • Math.round instead of banker's rounding for FX conversions
  • No phonetic matching (Soundex/Metaphone) for sanctions name transliterations

License

MIT

Author

Henry Wyndham | henry@ubava.ee

About

Cross-border payment orchestration API — strict state machine, real-time FX conversion, IBAN/SWIFT validation, and OFAC/EU sanctions screening. The framework that became OBELISK.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published