DocsArchitecture
Back to docs

Architecture Overview

OpenPay is composed of 10+ microservices connected through NATS JetStream event streams. Every component is open source, containerized with Docker, and designed for horizontal scalability.

Architectural Principles

Microservices

Each service has a single responsibility and can be scaled independently.

Event-Driven

Services communicate asynchronously through NATS JetStream — no blocking calls.

Provider-Agnostic

Hyperswitch routes to 100+ processors. Switch providers without code changes.

Self-Healing

Health checks, automatic restarts, and dead-letter queues for fault tolerance.

System Architecture Diagram


                         ┌─────────────────────────────────┐
                         │           Internet              │
                         └────────────┬──────────┬─────────┘
                                      │          │
                               ┌──────▼──────┐   │
                               │   Traefik   │   │ Processor
                               │  (Reverse   │   │ Webhooks
                               │   Proxy)    │   │
                               └──────┬──────┘   │
                                      │          │
          ┌───────────────────────────┼──────────┼──────────┐
          │                           │          │          │
          │                    ┌──────▼──────┐   │          │
          │                    │ Hyperswitch │   │          │
          │                    │(Rust, 8081) │   │          │
          │                    └──────┬──────┘   │          │
          │                           │          │          │
          │                    ┌──────▼──────────────────┐  │
          │                    │    NATS JetStream        │  │
          │                    │   (ports 4222, 8222)     │  │
          │                    │  PAYMENT_EVENTS · DLQ    │  │
          │                    └────┬────┬────┬────┬─────┘  │
          │                         │    │    │    │        │
          │    ┌────────────────────┘    │    │    └─────┐  │
          │    │                  ┌──────┘    └──────┐   │  │
          │    ▼                  ▼                   ▼   │  │
   ┌──────┴────────┐   ┌────────────────┐   ┌────────────┐ │
   │   Kill Bill   │   │  Tazama Rule   │   │  NATS-KB   │ │
   │  (Java, 8082) │   │  Exec (Go,8084)│   │  Bridge    │ │
   │  Subscriptions│   │  Fraud Rules   │   │  (Go)      │ │
   └───────┬───────┘   └───────┬────────┘   └─────┬──────┘ │
           │                   │                   │        │
           ▼                   ▼                   ▼        │
   ┌─────────────────────────────────────────────────────┐  │
   │            PostgreSQL  +  Redis  +  NATS             │  │
   │          (Data Layer — Docker internal only)         │  │
   └─────────────────────────────────────────────────────┘  │

   ┌────────────────────┐   ┌────────────────────┐
   │ Tazama Rule Studio │   │ Case Management   │
   │  (Web UI, 3000)    │   │  (Web UI, 3001)   │
   │  Rule Authoring    │   │  Alert Review     │
   └────────────────────┘   └────────────────────┘
          

All internal services communicate over the Docker bridge network. Only Traefik (ports 80/443) is exposed to the internet.

Payment Event Flow


  CUSTOMER                   HYPERSWITCH                    NATS                     TAZAMA              YOUR APP
    │                            │                         │                         │                    │
    │  POST /payments            │                         │                         │                    │
    ├────────────────────────────►                         │                         │                    │
    │                            │                         │                         │                    │
    │                            ├── payments.pending ────►│                         │                    │
    │                            │                         ├── fraud check ──────────►│                    │
    │                            │                         │                         │                    │
    │                            │◄── risk_score ──────────┤                         │                    │
    │                            │                         │                         │                    │
    │                            │── Connector request ──► (Payment Processor)       │                    │
    │◄── payment response ───────┤                         │                         │                    │
    │                            │                         │                         │                    │
    │                            ├── payments.completed ──►│                         │                    │
    │                            │                         ├── webhook ────────────────────────────────────►│
    │                            │                         │                         │                    │
    │                            │                         ├── invoice request ──► Kill Bill              │
    │                            │                         │                         │                    │
    │  (or)                      │                         │                         │                    │
    │                            ├── payments.failed ─────►│                         │                    │
    │                            │                         ├── webhook ────────────────────────────────────►│
    │                            │                         │                         │                    │
    │  (on error)                │                         │                         │                    │
    │                            │                         ├── dlq.event ───────────► (Investigate)      │
          

Service Communication Matrix

ServiceLanguagePortStoragePub/Sub
TraefikGo80, 443, 8080
HyperswitchRust8081PostgreSQL, RedisNATS (publish)
Kill BillJava8082PostgreSQLNATS (consume)
NATS-KB BridgeGoNATS (both)
Tazama AuthNode8083PostgreSQL, Redis
Tazama Rule ExecGo8084PostgreSQL, RedisNATS (both)
DashboardTypeScript3002REST (client)
PostgreSQL5432Disk
Redis6379RAM
NATSGo4222, 8222Disk

Payment Lifecycle (Step by Step)

1

Customer initiates payment

A customer clicks 'Pay' on your checkout page. The payment request is sent to Hyperswitch via the merchant dashboard, your backend, or the embedded checkout.

Endpoint: POST /payments with amount, currency, and payment details
2

Hyperswitch routes to connector

Hyperswitch evaluates the payment method, currency, and amount. It selects the optimal connector based on your routing rules (cost-based, volume-based, or fallback).

100+ supported connectors including Stripe, Paystack, Adyen, Razorpay
3

Fraud pre-check (Tazama)

Before sending to the connector, Tazama evaluates the transaction against your fraud rules: amount thresholds, velocity checks, BIN country geo-blocking, and custom rules.

Configurable rules in Tazama Rule Studio at port 3000
4

Connector processes payment

Hyperswitch sends the payment to the selected connector. The connector handles 3DS authentication, card tokenization, and bank-side authorization.

Response time: typically 200ms–2s depending on the processor
5

Event published to NATS

Hyperswitch publishes a payment event (succeeded, failed, or processing) to the PAYMENT_EVENTS stream. This triggers all downstream consumers.

Subject: payments.{intent}.{status}
6

Webhook delivery

Your application receives a webhook callback with the final payment status. Webhook retries happen up to 3 times with 30-second acknowledgment windows.

Failed events go to DLQ_EVENTS stream for investigation
7

Invoice & subscription sync

NATS-KB Bridge syncs the completed payment to Kill Bill for invoice generation, subscription billing, and dunning if needed.

Kill Bill handles proration, credits, and usage-based billing

Provider-Agnostic Architecture

One of OpenPay's core design principles is that you should never be locked into a single payment processor. Hyperswitch acts as a universal adapter between your application and 100+ payment processors worldwide.

Switch Processors Without Code Changes

Update routing rules in the Hyperswitch dashboard and payments are instantly rerouted to the new processor. No redeployment, no code changes, no downtime.

Fallback & Smart Routing

Configure primary and fallback processors. If the primary fails, Hyperswitch automatically retries with the fallback. Route by currency, amount, or payment method.

Deep Dives

External Architecture Resources