Skip to content

C4 Merchant Portal Container & Component Diagrams

Field Value
Status Draft
Owner Frontend Engineering / Platform
Last Updated 2026-04-03
Applies To Merchant Portal

1. Overview

The Merchant Portal is the self-service web application through which merchants manage their Simpaisa integration. It follows the microfrontend architecture (see MICROFRONTENDS-FRAMEWORK.md), with an Astro composition shell, Preact interactive islands, a Go-based Backend for Frontend (BFF), and ControlPlane.com for authentication. The portal is deployed to Cloudflare Pages for edge performance.

2. Container Diagram

graph TB
    Merchant["🏪 Merchant User<br/>(Browser)"]

    subgraph "Cloudflare Edge"
        CF_Pages["Cloudflare Pages<br/>(Static assets, SSR)"]
        CF_WAF["Cloudflare WAF"]
        CF_CDN["Cloudflare CDN"]
    end

    subgraph "Frontend — Astro Shell"
        AstroShell["Astro Composition Shell<br/>(Server-rendered layout)"]
    end

    subgraph "Preact MFEs (Islands)"
        DashboardMFE["Dashboard MFE<br/>Overview metrics"]
        APIKeysMFE["API Keys MFE<br/>Key CRUD, scoping"]
        WebhooksMFE["Webhooks MFE<br/>Endpoint CRUD, logs"]
        TransactionsMFE["Transactions MFE<br/>Search, detail, export"]
        ReportsMFE["Reports MFE<br/>Settlements, recon"]
        TeamMFE["Team MFE<br/>Users, roles, audit"]
    end

    subgraph "Backend for Frontend"
        BFF["BFF Service<br/>(Go)<br/>Aggregation, authorisation"]
    end

    subgraph "Identity"
        ControlPlane["ControlPlane.com<br/>OIDC, RBAC"]
    end

    subgraph "Backend Services"
        MerchantSvc["merchant-svc"]
        PayInSvc["pay-in-svc"]
        PayOutSvc["pay-out-svc"]
        NotificationSvc["notification-svc"]
        Meilisearch["Meilisearch<br/>(Transaction search)"]
    end

    Merchant -- "HTTPS" --> CF_CDN
    CF_CDN --> CF_WAF
    CF_WAF --> CF_Pages
    CF_Pages --> AstroShell

    AstroShell --> DashboardMFE
    AstroShell --> APIKeysMFE
    AstroShell --> WebhooksMFE
    AstroShell --> TransactionsMFE
    AstroShell --> ReportsMFE
    AstroShell --> TeamMFE

    DashboardMFE -- "REST" --> BFF
    APIKeysMFE -- "REST" --> BFF
    WebhooksMFE -- "REST" --> BFF
    TransactionsMFE -- "REST" --> BFF
    ReportsMFE -- "REST" --> BFF
    TeamMFE -- "REST" --> BFF

    BFF -- "OIDC" --> ControlPlane
    BFF -- "gRPC" --> MerchantSvc
    BFF -- "gRPC" --> PayInSvc
    BFF -- "gRPC" --> PayOutSvc
    BFF -- "gRPC" --> NotificationSvc
    BFF --> Meilisearch

3. Component Diagram — BFF Internals

graph TB
    subgraph "BFF Service (Go)"
        Router["HTTP Router<br/>(Chi)"]
        AuthMiddleware["Auth Middleware<br/>JWT validation, RBAC"]
        DashboardHandler["Dashboard Handler<br/>Aggregate metrics"]
        APIKeysHandler["API Keys Handler<br/>CRUD operations"]
        WebhooksHandler["Webhooks Handler<br/>Endpoint management"]
        TxnSearchHandler["Transaction Search Handler<br/>Meilisearch queries"]
        ReportsHandler["Reports Handler<br/>Settlement data, CSV export"]
        TeamHandler["Team Handler<br/>User CRUD, role assignment"]
        MerchantClient["Merchant Service Client<br/>gRPC"]
        PayInClient["Pay-In Service Client<br/>gRPC"]
        PayOutClient["Pay-Out Service Client<br/>gRPC"]
        SearchClient["Search Client<br/>Meilisearch"]
    end

    Router --> AuthMiddleware
    AuthMiddleware --> DashboardHandler
    AuthMiddleware --> APIKeysHandler
    AuthMiddleware --> WebhooksHandler
    AuthMiddleware --> TxnSearchHandler
    AuthMiddleware --> ReportsHandler
    AuthMiddleware --> TeamHandler

    DashboardHandler --> MerchantClient
    DashboardHandler --> PayInClient
    DashboardHandler --> PayOutClient
    APIKeysHandler --> MerchantClient
    WebhooksHandler --> MerchantClient
    TxnSearchHandler --> SearchClient
    ReportsHandler --> PayOutClient
    TeamHandler --> MerchantClient

4. Data Flows

4.1 Authentication Flow

sequenceDiagram
    participant U as Merchant User
    participant Shell as Astro Shell
    participant CP as ControlPlane.com
    participant BFF as BFF (Go)

    U->>Shell: Navigate to portal
    Shell->>CP: OIDC Authorise redirect
    CP->>U: Login page
    U->>CP: Credentials
    CP-->>Shell: Authorisation code
    Shell->>CP: Exchange code for tokens
    CP-->>Shell: ID token + access token
    Shell->>Shell: Store tokens (HttpOnly cookie)

    Note over U,BFF: Subsequent API calls
    U->>BFF: GET /api/dashboard (cookie: JWT)
    BFF->>BFF: Validate JWT signature (JWKS)
    BFF->>BFF: Check RBAC claims
    BFF-->>U: Dashboard data

4.2 API Key CRUD Flow

sequenceDiagram
    participant U as Merchant User
    participant MFE as API Keys MFE
    participant BFF as BFF (Go)
    participant MS as merchant-svc

    U->>MFE: Click "Create API Key"
    MFE->>BFF: POST /api/keys {name, scopes, environment}
    BFF->>BFF: Validate RBAC (admin or developer role)
    BFF->>MS: gRPC CreateAPIKey
    MS-->>BFF: APIKey {id, key, secret}
    BFF-->>MFE: 201 Created {id, key, secret}
    MFE->>U: Display key + secret (show once)

    Note over U,MS: Key rotation
    U->>MFE: Click "Rotate" on existing key
    MFE->>BFF: POST /api/keys/{id}/rotate
    BFF->>MS: gRPC RotateAPIKey
    MS-->>BFF: New APIKey {id, new_key, new_secret}
    BFF-->>MFE: 200 OK
    MFE->>U: Display new credentials

4.3 Transaction Search Flow

sequenceDiagram
    participant U as Merchant User
    participant MFE as Transactions MFE
    participant BFF as BFF (Go)
    participant MS as Meilisearch

    U->>MFE: Enter search query + filters
    MFE->>BFF: GET /api/transactions?q=TXN123&status=completed&from=2026-04-01
    BFF->>BFF: Inject merchant_id from JWT (tenant isolation)
    BFF->>MS: Search(index: transactions, filters)
    MS-->>BFF: Results {hits, total, facets}
    BFF-->>MFE: Paginated results
    MFE->>U: Render transaction table

    U->>MFE: Click transaction row
    MFE->>BFF: GET /api/transactions/{txn_id}
    BFF->>BFF: Verify txn belongs to merchant
    BFF-->>MFE: Transaction detail
    MFE->>U: Render detail view (timeline, channel response)

5. RBAC Model

Role Dashboard API Keys Webhooks Transactions Reports Team Mgmt
admin ✓ (CRUD) ✓ (CRUD)
developer ✓ (CRUD) ✓ (CRUD)
finance ✓ (read)
viewer ✓ (read)

Roles are managed in ControlPlane.com and embedded in JWT claims. The BFF enforces permissions on every request.

6. Portal MFE Details

MFE Key Features
Dashboard MFE Transaction volume chart, success rate, top channels
API Keys MFE Create, rotate, revoke keys; scope to environment
Webhooks MFE Add endpoints, view delivery logs, manual retry
Transactions MFE Full-text search, date/status/channel filters, export
Reports MFE Settlement summaries, reconciliation status, CSV/PDF
Team MFE Invite users, assign roles, view audit log

7. Performance & Caching

Layer Strategy
Cloudflare CDN Cache static assets (JS, CSS, images) 30 d
Cloudflare Workers Edge-side stale-while-revalidate
BFF Redis cache for dashboard aggregates (60 s)
Meilisearch Near-instant search (< 50 ms P99)

8. Non-Functional Requirements

Metric Target
First Contentful Paint < 1.2 s
Search latency P99 < 200 ms
BFF API latency P99 < 500 ms
Availability 99.9%

9. Architectural Decision Records

Changes to the Merchant Portal architecture require an ADR in /Standards/ADR/.