Skip to content

C4 Cards Container & Component Diagrams

Field Value
Status Draft
Owner Cards Squad
Last Updated 2026-04-03
Applies To Cards product line

1. Overview

The Cards system processes Visa and Mastercard transactions — authorisation, capture, void and refund. It includes a PCI DSS-compliant tokenisation vault and 3-D Secure (3DS) orchestration service. All card data handling occurs within an isolated Cardholder Data Environment (CDE) boundary with strict network segmentation.

2. Container Diagram

graph TB
    Merchant["🏪 Merchant<br/>(API Client)"]
    Consumer["👤 Cardholder<br/>(3DS challenge)"]

    subgraph "API Gateway"
        KrakenD["KrakenD Gateway<br/>(Auth, throttling, routing)"]
    end

    subgraph "PCI DSS Boundary (CDE)"
        CardsSvc["Cards Service<br/>(Go)<br/>Transaction orchestration"]
        TokenVault["Tokenisation Vault<br/>(Go)<br/>PAN storage, token mapping"]
        ThreeDSSvc["3DS Service<br/>(Go)<br/>3DS2 orchestration"]

        subgraph "CDE Data Store"
            SurrealDB_CDE["SurrealDB (CDE)<br/>Isolated cluster<br/>Encrypted at rest"]
        end
    end

    subgraph "Card Network Adapters"
        VisaAdapter["Visa Adapter<br/>(ISO 8583 + VTS API)"]
        MCAdapter["Mastercard Adapter<br/>(ISO 8583 + MDES)"]
    end

    subgraph "Non-CDE Data Stores"
        SurrealDB["SurrealDB<br/>(Transaction metadata)"]
    end

    subgraph "Messaging"
        NSQ["NSQ<br/>(Event bus)"]
    end

    Merchant -- "HTTPS" --> KrakenD
    Consumer -- "HTTPS (3DS challenge)" --> ThreeDSSvc
    KrakenD -- "gRPC" --> CardsSvc
    CardsSvc -- "gRPC" --> TokenVault
    CardsSvc -- "gRPC" --> ThreeDSSvc
    CardsSvc -- "gRPC" --> VisaAdapter
    CardsSvc -- "gRPC" --> MCAdapter
    TokenVault --> SurrealDB_CDE
    CardsSvc --> SurrealDB
    CardsSvc -- "Publish" --> NSQ

3. Component Diagram — Cards Service Internals

graph TB
    subgraph "Cards Service (Go)"
        API["gRPC API Layer<br/>Request validation"]
        AuthHandler["Auth Handler<br/>Authorisation request builder"]
        CaptureHandler["Capture Handler<br/>Capture after auth"]
        VoidHandler["Void Handler<br/>Reversal before settlement"]
        RefundHandler["Refund Handler<br/>Post-settlement return"]
        NetworkRouter["Network Router<br/>Visa vs Mastercard selection"]
        ThreeDSOrchestrator["3DS Orchestrator<br/>Challenge flow management"]
        TokenResolver["Token Resolver<br/>Detokenise PAN for network call"]
        TxnRepository["Transaction Repository<br/>SurrealDB persistence"]
        EventPublisher["Event Publisher<br/>NSQ domain events"]
    end

    API --> AuthHandler
    API --> CaptureHandler
    API --> VoidHandler
    API --> RefundHandler
    AuthHandler --> ThreeDSOrchestrator
    AuthHandler --> TokenResolver
    AuthHandler --> NetworkRouter
    CaptureHandler --> NetworkRouter
    VoidHandler --> NetworkRouter
    RefundHandler --> NetworkRouter
    NetworkRouter --> VisaAdpt["Visa Adapter"]
    NetworkRouter --> MCAdpt["MC Adapter"]
    TokenResolver --> Vault["Tokenisation Vault"]
    TxnRepository --> DB["SurrealDB"]
    EventPublisher --> Q["NSQ"]

4. Data Flows

4.1 Authorisation with 3DS

sequenceDiagram
    participant M as Merchant
    participant K as KrakenD
    participant C as Cards Service
    participant TV as Token Vault
    participant TDS as 3DS Service
    participant CH as Cardholder
    participant VA as Visa Adapter
    participant V as Visa Network
    participant DB as SurrealDB

    M->>K: POST /v1/cards/auth {card_token, amount, currency}
    K->>C: gRPC Authorise
    C->>TV: gRPC Detokenise(card_token)
    TV-->>C: PAN, expiry (encrypted in transit)

    C->>TDS: gRPC Initiate3DS {PAN, amount, merchant}
    TDS->>V: 3DS2 AReq
    V-->>TDS: ARes (challenge required)
    TDS-->>C: Challenge URL
    C-->>K: 200 {status: pending_3ds, challenge_url}
    K-->>M: Redirect cardholder

    CH->>TDS: Complete 3DS challenge
    TDS->>V: 3DS2 RReq
    V-->>TDS: Authentication result (ECI, CAVV)
    TDS-->>C: 3DS Result

    C->>VA: ISO 8583 Auth (with CAVV)
    VA->>V: Authorisation request
    V-->>VA: Approved
    VA-->>C: Auth response
    C->>DB: Insert txn (status: authorised)
    C-->>M: Webhook {txn_id, status: authorised}

4.2 Capture

sequenceDiagram
    participant M as Merchant
    participant C as Cards Service
    participant VA as Visa Adapter
    participant V as Visa Network
    participant DB as SurrealDB

    M->>C: POST /v1/cards/{txn_id}/capture {amount}
    C->>DB: Verify txn status = authorised
    C->>VA: ISO 8583 Capture
    VA->>V: Capture request
    V-->>VA: Captured
    VA-->>C: Capture response
    C->>DB: Update txn (status: captured)
    C-->>M: 200 {status: captured}

4.3 Void

sequenceDiagram
    participant M as Merchant
    participant C as Cards Service
    participant VA as Visa Adapter
    participant DB as SurrealDB

    M->>C: POST /v1/cards/{txn_id}/void
    C->>DB: Verify txn status = authorised (not yet captured)
    C->>VA: ISO 8583 Reversal
    VA-->>C: Reversed
    C->>DB: Update txn (status: voided)
    C-->>M: 200 {status: voided}

4.4 Refund

sequenceDiagram
    participant M as Merchant
    participant C as Cards Service
    participant VA as Visa Adapter
    participant DB as SurrealDB

    M->>C: POST /v1/cards/{txn_id}/refund {amount}
    C->>DB: Verify txn status = captured
    C->>VA: ISO 8583 Refund
    VA-->>C: Refunded
    C->>DB: Insert refund txn, link to original
    C-->>M: 200 {refund_id, status: refunded}

5. PCI DSS Boundary

The CDE is isolated with the following controls:

Control Implementation
Network segmentation Dedicated K8s namespace cards-cde-prod
Encryption at rest SurrealDB CDE cluster with AES-256 encryption
Encryption in transit mTLS between all CDE pods (Caddy sidecar)
Access control No direct DB access; all queries via Token Vault API
Key management HSM-backed keys, rotated quarterly
Audit logging All PAN access logged with requester identity
Vulnerability scanning Weekly ASV scans, quarterly penetration tests
Data retention Truncated PAN only after 90 days

6. Tokenisation Vault

The Token Vault maps merchant-scoped tokens to card PANs. Merchants never handle raw PANs after initial tokenisation.

Operation Description
Tokenise Accept PAN → return card_token (format-preserving)
Detokenise Accept card_token → return PAN (CDE internal only)
Delete Permanently remove PAN and token mapping

Token format: tok_ prefix + 24-character alphanumeric string (e.g. tok_8f3a2b1c9d4e5f6a7b8c9d0e).

7. Non-Functional Requirements

Metric Target
Availability 99.99%
Auth P99 latency < 2 s
3DS challenge timeout 5 minutes
PCI DSS compliance Level 1 (annual ROC)
Token vault RTO < 15 minutes

8. Architectural Decision Records

Changes to Cards architecture require an ADR in /Standards/ADR/.