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/.