🏗️ Reading: Architecture Descriptions
3 exercises — read a real-style service architecture document for a Payment microservice. Extract component responsibilities, understand design decisions, and reason about system behavior.
How to read architecture documents
- Summary / Overview → what the service does and what it doesn't do (boundaries)
- Components section → the building blocks and their responsibilities
- Key Design Decisions → the "why" — trade-offs the team made consciously
- Look for: who calls whom, what is synchronous vs. async, what data is stored where
- Arrows and dependencies: "A calls B" means A depends on B
0 / 3 completed
1 / 3
Payment Service — Architecture Overview
# Payment Service — Architecture Overview
## Summary
The Payment Service handles all financial transactions for the platform.
It is a standalone microservice responsible for charge processing, refund
management, and payment method storage. It does NOT handle authentication —
all requests must arrive pre-authenticated via the API Gateway.
## Components
### API Layer
Exposes a REST API consumed by the Web App and Mobile App. All endpoints
require a valid JWT token in the Authorization header. Rate-limited to
100 requests per minute per user.
### Business Logic Layer
Coordinates the payment workflow:
1. Validates the request (amount, currency, idempotency key)
2. Calls the External Payment Provider (Stripe) via the Provider Adapter
3. Records the transaction in the Database
4. Publishes a payment.completed or payment.failed event to the Message Queue
### Provider Adapter
Abstracts the External Payment Provider. Currently wraps Stripe's API.
Designed to be swappable — switching providers requires only changing
this adapter without touching the Business Logic Layer.
### Database
PostgreSQL (RDS, Multi-AZ). Stores:
- Transactions (immutable — never updated, only appended)
- Payment methods (tokenized — raw card data is never stored)
- Idempotency keys (TTL: 24 hours)
### Message Queue
Publishes domain events consumed by:
- Order Service (to mark orders as paid)
- Notification Service (to send payment receipts)
- Analytics Service (for revenue reporting)
## Key Design Decisions
- **Idempotency**: Every POST request must include an Idempotency-Key header.
Duplicate requests with the same key return the cached response without
re-processing the payment.
- **Immutable ledger**: Transactions are append-only. To "cancel" a payment,
a separate refund transaction is created rather than updating the original.
- **No raw card data**: PCI DSS compliance — card data is tokenized at the
client before reaching our servers. According to the architecture document, what is the purpose of the Provider Adapter component?
The Provider Adapter abstracts the payment provider — making it swappable:
The document says: "Abstracts the External Payment Provider. Currently wraps Stripe's API. Designed to be swappable — switching providers requires only changing this adapter without touching the Business Logic Layer."
This is the Adapter design pattern:
This is called "loose coupling" — components depend on abstractions, not concrete implementations. It reduces vendor lock-in and makes the system easier to maintain and test.
Architecture document vocabulary:
The document says: "Abstracts the External Payment Provider. Currently wraps Stripe's API. Designed to be swappable — switching providers requires only changing this adapter without touching the Business Logic Layer."
This is the Adapter design pattern:
- The Business Logic Layer calls a consistent internal interface
- The Adapter translates those calls into whatever the external provider (Stripe, PayPal, etc.) requires
- If the company switches from Stripe to Adyen, only the Adapter changes — no other layer is affected
This is called "loose coupling" — components depend on abstractions, not concrete implementations. It reduces vendor lock-in and makes the system easier to maintain and test.
Architecture document vocabulary:
- abstracts → hides implementation details behind an interface
- swappable → can be replaced without affecting surrounding components
- adapter → translates between two incompatible interfaces
- standalone microservice → an independently deployable service with its own database and responsibilities