Skip to main content

Platform Architecture

Open Pay is built as a distributed microservices system with 8 backend services, 2 frontend applications, and on-chain smart contracts.

System Overview

                          ┌─────────────────┐
                          │   Merchant       │
                          │   Portal (React) │
                          └────────┬─────────┘

                          ┌────────┴─────────┐
                          │   Admin          │
                          │   Dashboard      │
                          └────────┬─────────┘

                    ┌──────────────┴──────────────┐
                    │       API Gateway (8080)      │
                    │   JWT + HMAC Auth, Rate Limit │
                    └──────────────┬──────────────┘

        ┌──────────┬──────────┬────┴────┬──────────┬──────────┐
        ▼          ▼          ▼         ▼          ▼          ▼
   ┌─────────┐┌─────────┐┌────────┐┌─────────┐┌────────┐┌────────┐
   │Merchant ││Payment  ││Settle- ││Webhook  ││Exchange││Subscr- │
   │ (8082)  ││ (8081)  ││ment    ││ (8084)  ││ (8085) ││iption  │
   │         ││         ││(8083)  ││         ││        ││(8086)  │
   └────┬────┘└────┬────┘└───┬────┘└────┬────┘└───┬────┘└───┬────┘
        │          │         │          │         │         │
        ▼          ▼         ▼          ▼         ▼         ▼
   ┌──────────────────────────────────────────────────────────────┐
   │                    PostgreSQL 16 (per-service DBs)            │
   └──────────────────────────────────────────────────────────────┘
   ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
   │  Redis 7     │  │ NATS         │  │ MinIO        │
   │  (cache/rate)│  │ JetStream    │  │ (file store) │
   └──────────────┘  └──────────────┘  └──────────────┘

Services

Gateway

API gateway handling JWT/HMAC authentication, rate limiting, CORS, and request routing to downstream services. Port 8080.

Payment Service

Payment creation, QR code generation, status tracking, checkout sessions, and crypto provider integrations (Bybit, Binance, KuCoin). Port 8081.

Merchant Service

Merchant registration, KYC management, API key generation, payment links, branch management, and user roles. Port 8082.

Settlement Service

Balance tracking, withdrawal requests, treasury management, and fiat settlement processing. Port 8083.

Webhook Service

ED25519-signed webhook delivery with exponential backoff retries, delivery logs, and signature verification. Port 8084.

Exchange Service

Real-time USDT/LKR exchange rates via CoinGecko. Background fetcher updates every 5 minutes. Port 8085.

Subscription Service

Recurring billing plans, subscriber management, trial periods, and automatic payment scheduling. Port 8086.

Notification Service

Email notifications via SMTP (Resend), with template management and NATS JetStream async processing. Port 8087.

Tech Stack

LayerTechnology
BackendGo 1.24, chi router, pgx/v5, NATS JetStream
FrontendReact, Vite, TanStack (Start, Query, Table), shadcn/ui, Tailwind CSS v4
DatabasePostgreSQL 16 (database-per-service pattern)
CacheRedis 7 (rate limiting, session cache)
MessagingNATS JetStream (event-driven async processing)
File StorageMinIO (S3-compatible object storage)
Smart ContractsSolidity 0.8.24, Hardhat, OpenZeppelin, Chainlink
AuthJWT (merchant/admin), HMAC-SHA256 (SDK), ED25519 (webhooks)
MonitoringPrometheus, Grafana, zerolog, OpenTelemetry
CI/CDGitHub Actions, Vercel (frontends), Docker Compose (backend)

Authentication Layers

Open Pay uses three authentication mechanisms:
1

JWT (Merchant & Admin Portals)

Login with email/password returns an access token (15 min) and refresh token (7 days). Supports 2FA via TOTP.
2

HMAC-SHA256 (SDK / API Keys)

For server-to-server integrations. Each request is signed with HMAC-SHA256(apiSecret, timestamp + method + path + body). Prevents replay attacks with timestamp validation.
3

ED25519 (Webhooks)

Outgoing webhooks are signed with the platform’s ED25519 private key. Merchants verify using the public key from /v1/webhooks/public-key.

Database-per-Service

Each microservice owns its database schema, enforcing data isolation:
ServiceDatabaseKey Tables
Merchantmerchant_dbmerchants, users, api_keys, payment_links, branches
Paymentpayment_dbpayments, payment_statuses
Settlementsettlement_dbbalances, withdrawals
Webhookwebhook_dbwebhook_configs, delivery_logs
Subscriptionsubscription_dbplans, subscriptions
Notificationnotification_dbnotifications, email_templates
Exchangeexchange_dbexchange_rates
Adminadmin_dbadmin_users, roles, audit_logs, settings, legal_documents

Deployment

  • Backend: Docker Compose on DigitalOcean (8 services + infra)
  • Frontends: Vercel with automatic deploys from GitHub
  • Smart Contracts: BSC Testnet (Hardhat deployment)
  • DNS: Custom domains via Cloudflare