# almousleckdev/zellapay architecture

> Architecture diagram of the GitHub repository almousleckdev/zellapay, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/almousleckdev/zellapay
- Repository: https://github.com/almousleckdev/zellapay

## Overview

ZellaPay is a Gabon-focused payment aggregator: merchants submit collection or payout requests through an authenticated, idempotent REST API; domain services route them to mobile-money operators, update payment state and the double-entry ledger, and publish signed webhook outcomes. The repository also includes merchant/key administration, webhook management, and a sandbox simulator. The sampled composition root shows service and store assembly; README capabilities include reconciliation and refunds, but the tree has no substantive implementation for those yet. Some worker and operator-gateway runtime links are documented but not visible in sampled source.

Main entry points: [`internal/collections/service.go`](https://github.com/almousleckdev/zellapay/blob/main/internal/collections/service.go) (Collections), [`internal/payouts/service.go`](https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/service.go) (Payouts), [`internal/webhooks/service.go`](https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/service.go) (Webhook delivery), [`internal/apiserver/server.go`](https://github.com/almousleckdev/zellapay/blob/main/internal/apiserver/server.go) (API server)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["Merchant API"]
  node_api_server["API server<br/>[server.go]"]
  node_collection_api["Collection routes<br/>[routes.go]"]
  node_payout_api["Payout routes<br/>[routes.go]"]
  node_webhook_api["Webhook routes<br/>[routes.go]"]
  node_merchant_auth["Merchant auth<br/>[middleware.go]"]
  node_idempotency["Idempotency<br/>[middleware.go]"]
end

subgraph group_payments["Payment operations"]
  node_collections["Collections<br/>[service.go]"]
  node_payouts["Payouts<br/>[service.go]"]
  node_ledger["Double-entry ledger<br/>[entry.go]"]
  node_refunds["Refunds"]
end

subgraph group_services["Core services"]
  node_merchants["Merchant services<br/>[service.go]"]
  node_webhooks["Webhook delivery<br/>[service.go]"]
  node_worker["Background worker<br/>[main.go]"]
  node_reconciliation["Reconciliation"]
end

subgraph group_integrations["Storage and integrations"]
  node_collection_store[("Collection store<br/>[query.go]")]
  node_payout_store[("Payout store<br/>[query.go]")]
  node_ledger_store[("Ledger store<br/>[accounts.go]")]
  node_operator_router["Operator router<br/>[router.go]"]
  node_simulator["Sandbox simulator<br/>[simulator.go]"]
  node_callback_dispatch["Operator callbacks<br/>[callbacks.go]"]
  node_webhook_store[("Webhook store<br/>[deliveries.go]")]
end

node_merchant(("Merchant"))
node_merchant_endpoint(("Merchant endpoint"))

node_merchant -->|"submits requests"| node_api_server
node_api_server -->|"mounts routes"| node_collection_api
node_api_server -->|"mounts routes"| node_payout_api
node_api_server -->|"mounts routes"| node_webhook_api
node_collection_api -->|"guards with"| node_merchant_auth
node_payout_api -->|"guards with"| node_merchant_auth
node_webhook_api -->|"guards with"| node_merchant_auth
node_collection_api -->|"guards writes"| node_idempotency
node_payout_api -->|"guards writes"| node_idempotency
node_webhook_api -->|"guards writes"| node_idempotency
node_collection_api -->|"handles requests"| node_collections
node_payout_api -->|"handles requests"| node_payouts
node_webhook_api -->|"handles requests"| node_webhooks
node_collections -.->|"persists state"| node_collection_store
node_payouts -.->|"persists state"| node_payout_store
node_collections -->|"posts entries"| node_ledger
node_payouts -->|"posts entries"| node_ledger
node_collections -.->|"routes payments"| node_operator_router
node_payouts -.->|"routes payouts"| node_operator_router
node_operator_router -->|"dispatches to"| node_simulator
node_callback_dispatch -->|"updates status"| node_collections
node_callback_dispatch -->|"updates status"| node_payouts
node_collections -->|"emits outcomes"| node_webhooks
node_payouts -->|"emits outcomes"| node_webhooks
node_webhooks -.->|"records deliveries"| node_webhook_store
node_webhooks -->|"sends signed events"| node_merchant_endpoint
node_worker -.->|"runs delivery jobs"| node_webhooks
node_merchant -->|"administers keys"| node_merchants
node_refunds -->|"reverses collection"| node_ledger
node_reconciliation -.->|"matches statements"| node_operator_router

click node_api_server "https://github.com/almousleckdev/zellapay/blob/main/internal/apiserver/server.go"
click node_collection_api "https://github.com/almousleckdev/zellapay/blob/main/internal/collections/httpapi/routes.go"
click node_payout_api "https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/httpapi/routes.go"
click node_webhook_api "https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/httpapi/routes.go"
click node_merchant_auth "https://github.com/almousleckdev/zellapay/blob/main/internal/merchants/httpauth/middleware.go"
click node_idempotency "https://github.com/almousleckdev/zellapay/blob/main/internal/platform/idempotency/middleware.go"
click node_collections "https://github.com/almousleckdev/zellapay/blob/main/internal/collections/service.go"
click node_payouts "https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/service.go"
click node_ledger "https://github.com/almousleckdev/zellapay/blob/main/internal/ledger/entry.go"
click node_refunds "https://github.com/almousleckdev/zellapay/tree/main/internal/collections"
click node_merchants "https://github.com/almousleckdev/zellapay/blob/main/internal/merchants/service.go"
click node_webhooks "https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/service.go"
click node_worker "https://github.com/almousleckdev/zellapay/blob/main/cmd/worker/main.go"
click node_reconciliation "https://github.com/almousleckdev/zellapay/tree/main/internal/reconciliation"
click node_collection_store "https://github.com/almousleckdev/zellapay/blob/main/internal/collections/pgstore/query.go"
click node_payout_store "https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/pgstore/query.go"
click node_ledger_store "https://github.com/almousleckdev/zellapay/blob/main/internal/ledger/pgstore/accounts.go"
click node_operator_router "https://github.com/almousleckdev/zellapay/blob/main/internal/operators/router/router.go"
click node_simulator "https://github.com/almousleckdev/zellapay/blob/main/internal/operators/simulator/simulator.go"
click node_callback_dispatch "https://github.com/almousleckdev/zellapay/blob/main/internal/callbacks/callbacks.go"
click node_webhook_store "https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/pgstore/deliveries.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_api_server,node_collection_api,node_payout_api,node_webhook_api,node_merchant_auth,node_idempotency toneBlue
class node_collections,node_payouts,node_ledger,node_refunds toneAmber
class node_merchants,node_webhooks,node_worker,node_reconciliation toneMint
class node_collection_store,node_payout_store,node_ledger_store,node_operator_router,node_simulator,node_callback_dispatch,node_webhook_store toneRose
class node_merchant,node_merchant_endpoint toneIndigo
```

## Components

### Merchant API

- [API server](https://github.com/almousleckdev/zellapay/blob/main/internal/apiserver/server.go): `internal/apiserver/server.go`
- [Collection routes](https://github.com/almousleckdev/zellapay/blob/main/internal/collections/httpapi/routes.go): `internal/collections/httpapi/routes.go`
- [Payout routes](https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/httpapi/routes.go): `internal/payouts/httpapi/routes.go`
- [Webhook routes](https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/httpapi/routes.go): `internal/webhooks/httpapi/routes.go`
- [Merchant auth](https://github.com/almousleckdev/zellapay/blob/main/internal/merchants/httpauth/middleware.go): `internal/merchants/httpauth/middleware.go`
- [Idempotency](https://github.com/almousleckdev/zellapay/blob/main/internal/platform/idempotency/middleware.go): `internal/platform/idempotency/middleware.go`

### Payment operations

- [Collections](https://github.com/almousleckdev/zellapay/blob/main/internal/collections/service.go): `internal/collections/service.go`
- [Payouts](https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/service.go): `internal/payouts/service.go`
- [Double-entry ledger](https://github.com/almousleckdev/zellapay/blob/main/internal/ledger/entry.go): `internal/ledger/entry.go`
- [Refunds](https://github.com/almousleckdev/zellapay/tree/main/internal/collections): `internal/collections`

### Core services

- [Merchant services](https://github.com/almousleckdev/zellapay/blob/main/internal/merchants/service.go): `internal/merchants/service.go`
- [Webhook delivery](https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/service.go): `internal/webhooks/service.go`
- [Background worker](https://github.com/almousleckdev/zellapay/blob/main/cmd/worker/main.go): `cmd/worker/main.go`
- [Reconciliation](https://github.com/almousleckdev/zellapay/tree/main/internal/reconciliation): `internal/reconciliation`

### Storage and integrations

- [Collection store](https://github.com/almousleckdev/zellapay/blob/main/internal/collections/pgstore/query.go): `internal/collections/pgstore/query.go`
- [Payout store](https://github.com/almousleckdev/zellapay/blob/main/internal/payouts/pgstore/query.go): `internal/payouts/pgstore/query.go`
- [Ledger store](https://github.com/almousleckdev/zellapay/blob/main/internal/ledger/pgstore/accounts.go): `internal/ledger/pgstore/accounts.go`
- [Operator router](https://github.com/almousleckdev/zellapay/blob/main/internal/operators/router/router.go): `internal/operators/router/router.go`
- [Sandbox simulator](https://github.com/almousleckdev/zellapay/blob/main/internal/operators/simulator/simulator.go): `internal/operators/simulator/simulator.go`
- [Operator callbacks](https://github.com/almousleckdev/zellapay/blob/main/internal/callbacks/callbacks.go): `internal/callbacks/callbacks.go`
- [Webhook store](https://github.com/almousleckdev/zellapay/blob/main/internal/webhooks/pgstore/deliveries.go): `internal/webhooks/pgstore/deliveries.go`

### Other components

- **Merchant**
- **Merchant endpoint**

## Connections

- Merchant → API server: submits requests (evidence: `README.md`)
- API server → Collection routes: mounts routes (evidence: `internal/apiserver/server.go`)
- API server → Payout routes: mounts routes (evidence: `internal/apiserver/server.go`)
- API server → Webhook routes: mounts routes (evidence: `internal/apiserver/server.go`)
- Collection routes → Merchant auth: guards with (evidence: `internal/collections/httpapi/routes.go`)
- Payout routes → Merchant auth: guards with (evidence: `internal/payouts/httpapi/routes.go`)
- Webhook routes → Merchant auth: guards with (evidence: `internal/webhooks/httpapi/routes.go`)
- Collection routes → Idempotency: guards writes (evidence: `internal/collections/httpapi/routes.go`)
- Payout routes → Idempotency: guards writes (evidence: `internal/payouts/httpapi/routes.go`)
- Webhook routes → Idempotency: guards writes (evidence: `internal/webhooks/httpapi/routes.go`)
- Collection routes → Collections: handles requests
- Payout routes → Payouts: handles requests
- Webhook routes → Webhook delivery: handles requests
- Collections → Collection store: persists state
- Payouts → Payout store: persists state
- Collections → Double-entry ledger: posts entries (evidence: `internal/collections/service.go`)
- Payouts → Double-entry ledger: posts entries (evidence: `internal/payouts/service.go`)
- Collections → Operator router: routes payments
- Payouts → Operator router: routes payouts
- Operator router → Sandbox simulator: dispatches to
- Operator callbacks → Collections: updates status
- Operator callbacks → Payouts: updates status
- Collections → Webhook delivery: emits outcomes
- Payouts → Webhook delivery: emits outcomes
- Webhook delivery → Webhook store: records deliveries
- Webhook delivery → Merchant endpoint: sends signed events (evidence: `README.md`)
- Background worker → Webhook delivery: runs delivery jobs (evidence: `README.md`)
- Merchant → Merchant services: administers keys
- Refunds → Double-entry ledger: reverses collection (evidence: `README.md`)
- Reconciliation → Operator router: matches statements
