Design a Payment API
Instructions
Objective
Design a complete RESTful Payment Processing API. You will define endpoints, request/response schemas, authentication, idempotency, error handling, and webhook notifications. This exercise mirrors what you'd be asked in a real backend system design interview at companies like Stripe, Square, or Adyen.
Requirements
1. Core Payment Endpoints
Design the following RESTful endpoints:
- Create a payment — initiate a charge against a payment method
- Retrieve a payment — get payment details by ID
- List payments — paginated list with filtering by status, date range, and amount
- Create a refund — full or partial refund against a completed payment
- Retrieve a refund — get refund details by ID
- List refunds for a payment — all refunds associated with a payment
For each endpoint, specify:
- HTTP method and path (following REST conventions)
- Request body (if applicable) with TypeScript interfaces
- Response body with TypeScript interfaces
- Appropriate HTTP status codes for success and error cases
2. TypeScript Interfaces for Request/Response Schemas
Define complete TypeScript interfaces for:
CreatePaymentRequest— amount, currency, payment method, customer ID, metadata, descriptionPaymentResponse— all payment fields including status, timestamps, and refund summaryCreateRefundRequest— payment ID, amount (optional for full refund), reasonRefundResponse— refund details with statusWebhookEvent— event type, payload, timestamp, signatureApiError— error code, message, details array, request ID
Use proper types: amount should be an integer in the smallest currency unit (cents), currency should use ISO 4217 codes, timestamps should be ISO 8601 strings.
3. Authentication Design
Design a two-layer authentication system:
- API Key authentication — for all API requests. Define the header format, key structure (test vs live keys:
sk_test_*andsk_live_*), and how the server validates them. - Webhook signature verification — for webhook delivery. Define how you sign webhook payloads (HMAC-SHA256), what headers are included (
Webhook-Signature,Webhook-Timestamp), and how the receiver verifies authenticity. Include protection against replay attacks.
4. Idempotency Key Implementation
Design the idempotency mechanism for the POST /payments endpoint:
- Define the
Idempotency-Keyheader format (UUID v4) - Explain the server-side deduplication logic
- Define what happens on: first request, duplicate request (same key), expired key
- Specify the TTL for idempotency records (e.g., 24 hours)
- Handle race conditions (concurrent requests with the same key)
5. Rate Limiting Design
Define rate limits for different endpoint categories:
- Payment creation: stricter limits
- Read operations (GET): more permissive
- Webhook retries: separate limits
Specify the response headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) and the error response when rate limited (429).
6. Error Code Taxonomy
Design a structured error system with:
- Error categories:
authentication_error,invalid_request_error,payment_error,rate_limit_error,api_error - Specific error codes within each category (e.g.,
card_declined,insufficient_funds,invalid_currency) - Human-readable messages
- Machine-readable error codes
- Request ID for debugging
7. Webhook Design
Design the webhook notification system for async payment status updates:
- Define the webhook event types:
payment.created,payment.succeeded,payment.failed,refund.created,refund.succeeded - Define the webhook payload structure
- Describe the retry strategy with exponential backoff (1 min, 5 min, 30 min, 2 hr, 24 hr)
- Describe how to handle webhook delivery failures and dead letter queue
Deliverable
Provide a single TypeScript file that contains:
- All TypeScript interfaces and types
- Endpoint documentation as comments (method, path, description, status codes)
- Example request/response JSON for each endpoint (as typed constants)
- Authentication helper function signatures
- Idempotency middleware signature
- Webhook signature generation and verification functions
- Error factory functions
Hints
- Study how Stripe structures their API — it is the gold standard for payment API design
- Use cents (integers) for monetary amounts to avoid floating-point precision issues
- Include
metadatafields (key-value pairs) for extensibility - Payment statuses should form a state machine:
pending->processing->succeeded|failed - Make all responses include a
request_idfor traceability - Use cursor-based pagination for list endpoints
- The webhook signature should include the timestamp to prevent replay attacks
What to Submit
Your submission should contain 1 file section in the editor below: a complete TypeScript file with all 9 sections.