Skip to content

Instantly share code, notes, and snippets.

@bassemZohdy
Created April 11, 2026 12:44
Show Gist options
  • Select an option

  • Save bassemZohdy/96e0fbc78d7947a459e6442f5696c325 to your computer and use it in GitHub Desktop.

Select an option

Save bassemZohdy/96e0fbc78d7947a459e6442f5696c325 to your computer and use it in GitHub Desktop.

E-Commerce Payment Processing Platform

Reference Model & Architecture Specification


Table of Contents

  1. Executive Summary
  2. Problem Statement
  3. User Personas
  4. Feature Prioritization & Roadmap
  5. Core Features & Use Cases
  6. Third-Party Integrations
  7. Critical Technical Patterns
  8. Architectural Patterns
  9. Data Model
  10. Scalability & Capacity Planning
  11. Accessibility & Internationalization
  12. Edge Cases & Error Scenarios
  13. Testing Strategy
  14. Deployment & Infrastructure
  15. Compliance & Security
  16. Success Metrics
  17. Visual Diagrams

1. Executive Summary

  • Purpose: A platform-agnostic reference model for building e-commerce payment processing applications
  • Domain: E-commerce and digital payment infrastructure
  • Scope: Multi-tenant merchant dashboard, transaction management, payment processing, and real-time reporting
  • Target: Web, mobile, and desktop implementations sharing a common architectural foundation

2. Problem Statement

Merchants need unified platforms to manage online payments across multiple channels while maintaining compliance, real-time visibility, and seamless user experiences.

Core Challenges

  • Authentication & Authorization: Multi-role access control with fine-grained permissions
  • Data Consistency: Managing concurrent updates to transactions and balances
  • Real-time Synchronization: Multiple users viewing and updating the same data simultaneously
  • Network Resilience: Offline-first capability with conflict-free sync
  • Complex Forms: Multi-step workflows with validation, error recovery, and async operations
  • Advanced Filtering: Complex queries across large transaction datasets
  • Error Handling: Graceful degradation and retry strategies for external API failures

3. User Personas

Persona Goals & Responsibilities Access Level
Merchant Owner View dashboards, manage payout settings, analyze revenue trends, invite team members, configure webhooks Full Access
Account Manager Process transactions, manage payment methods, handle refunds, update transaction metadata Transaction Management
Finance Officer View reconciliation reports, audit logs, export transaction data, review dispute documentation Financial Reporting
Support Agent View transaction history (read-only), search customers, access logs, no data modification Read-Only

4. Feature Prioritization & Roadmap

Priority Definitions

  • P0 (Critical): Must-have for MVP; blocks core functionality
  • P1 (High): Important for production readiness; enhances core value
  • P2 (Medium): Nice-to-have; improves UX or efficiency
  • P3 (Low): Future enhancements; can be deferred

Feature Matrix

Feature ID Feature Name Priority Domain Dependencies
AUTH-001 User Authentication (OAuth/JWT) P0 Authentication -
AUTH-002 Role-Based Access Control (RBAC) P0 Authentication AUTH-001
AUTH-003 Multi-Factor Authentication (MFA) P1 Authentication AUTH-001
TXN-001 Transaction List & Filtering P0 Transaction Management AUTH-002
TXN-002 Transaction Detail View P0 Transaction Management TXN-001
TXN-003 Real-time Transaction Updates P1 Transaction Management TXN-001
TXN-004 Transaction Search P1 Transaction Management TXN-001
TXN-005 Refund Initiation P1 Transaction Management TXN-002, PM-001
PM-001 Payment Method Management P0 Payment Methods AUTH-002
PM-002 Payment Gateway Integration P0 Payment Methods PM-001
PO-001 Payout Request Creation P1 Payouts AUTH-002
PO-002 Payout Approval Workflow P1 Payouts PO-001
SYNC-001 WebSocket Real-time Updates P1 Synchronization -
SYNC-002 Conflict Resolution P1 Synchronization SYNC-001
OFFLINE-001 Offline Data Caching P2 Offline-First TXN-001, PM-001
OFFLINE-002 Sync Queue Management P2 Offline-First OFFLINE-001
FORM-001 Multi-step Forms P1 Forms & Validation -
FORM-002 Field Validation P0 Forms & Validation FORM-001
FORM-003 Async Validation P1 Forms & Validation FORM-002
ERROR-001 Error Detection & User Feedback P0 Error Handling -
ERROR-002 Automatic Retry with Backoff P1 Error Handling ERROR-001
ERROR-003 Circuit Breaker Pattern P1 Error Handling ERROR-001
REPORT-001 Transaction Export (CSV) P1 Reporting TXN-001
REPORT-002 PDF Report Generation P2 Reporting TXN-001
REPORT-003 Scheduled Reports P2 Reporting REPORT-002
FILE-001 File Upload & Management P1 File Management -
NAV-001 Deep Linking & URL State P1 Navigation -
NOTIF-001 In-app Notifications P1 Notifications -
NOTIF-002 Email Notifications P2 Notifications NOTIF-001
NOTIF-003 Webhook Integration P1 Notifications -

5. Core Features & Use Cases

5.1 Authentication & Authorization

Features

  • OAuth 2.0 / JWT-based login
  • Multi-factor authentication (MFA)
  • Role-based access control (RBAC): Owner, Manager, Finance, Support
  • Row-level security (RLS): Users see only their merchant data
  • Token refresh and automatic re-authentication
  • Session timeout and forced logout
  • Password reset flow

Use Cases & Acceptance Criteria

UC-AUTH-001: User Login

  • Given: A registered user with valid credentials
  • When: User submits login form with email and password
  • Then: System validates credentials, returns JWT token with 24h expiry
  • And: User is redirected to dashboard
  • And: Session is stored securely (httpOnly cookie or secure storage)

UC-AUTH-002: Token Refresh

  • Given: User has an active session with expired access token
  • When: API returns 401 Unauthorized
  • Then: Client automatically uses refresh token to obtain new access token
  • And: Original request is retried transparently
  • And: If refresh token is expired, user is redirected to login

UC-AUTH-003: Role-Based Access Control

  • Given: User has "Finance Officer" role
  • When: User attempts to access "Payout Approval" endpoint
  • Then: Request is allowed based on role permissions
  • And: User with "Support Agent" role receives 403 Forbidden for same endpoint

UC-AUTH-004: Row-Level Security

  • Given: User belongs to Merchant A (ID: merchant-001)
  • When: User queries transactions
  • Then: System automatically filters to return only transactions where merchant_id = merchant-001
  • And: No transactions from Merchant B are returned

UC-AUTH-005: MFA Setup

  • Given: User is required to enable MFA (policy setting)
  • When: User accesses MFA setup flow
  • Then: System generates QR code for TOTP app
  • And: User enters code to verify setup
  • And: Backup codes are generated for account recovery

5.2 Transaction Management

Features

  • Transaction list with status (pending, completed, failed, disputed)
  • Advanced filtering: by date range, amount, status, customer, payment method
  • Search across transaction IDs, customer names, order references
  • Pagination and sorting (default: 50 items per page, max: 200)
  • Real-time transaction status updates via WebSocket
  • Transaction detail view with full audit trail
  • Refund initiation (with validation and approval workflow)
  • Export to CSV/PDF
  • Bulk actions (bulk refund, bulk export)

Use Cases & Acceptance Criteria

UC-TXN-001: Load Transaction List

  • Given: User is logged in with appropriate permissions
  • When: User navigates to Transactions page
  • Then: System returns first 50 transactions sorted by created_at DESC
  • And: Response includes pagination metadata (total, page, per_page, total_pages)
  • And: Loading state is shown while fetching data
  • Performance: Initial load completes within 2 seconds

UC-TXN-002: Apply Filters

  • Given: User is on Transactions page with 500 total transactions
  • When: User filters by date range (last 30 days) and status = "completed"
  • Then: System returns filtered results
  • And: Filter state is preserved in URL for sharing
  • And: Zero-state message shown if no matches found

UC-TXN-003: Search Transactions

  • Given: User has 10,000+ transactions
  • When: User searches for "john@example.com" in customer email field
  • Then: System returns all transactions matching the email across all time periods
  • And: Search is case-insensitive
  • And: Results highlight matched term
  • Performance: Search completes within 500ms for up to 100,000 transactions

UC-TXN-004: Real-time Update

  • Given: Two managers (User A and User B) have transaction list open
  • When: User A initiates a refund on transaction TX-12345
  • Then: User B's list updates within 1 second to show new status
  • And: Visual indicator (toast or highlight) shows which transaction changed
  • And: WebSocket connection auto-reconnects if dropped

UC-TXN-005: View Transaction Details

  • Given: User clicks on transaction TX-12345 from list
  • When: Transaction detail page loads
  • Then: All transaction fields are displayed (amount, currency, status, customer, metadata)
  • And: Complete audit trail is visible (created_at, updated_at, completed_at, settled_at, who changed what)
  • And: Related transactions (refunds, chargebacks) are linked
  • And: Payment method details are shown (masked card number, expiry)
  • And: If transaction has refunds, "Refund History" section is displayed

UC-TXN-005.1: View Refund History

  • Given: Transaction TX-12345 has multiple partial refunds
  • When: User views transaction detail page
  • Then: "Refund History" section lists all refunds in chronological order
  • And: Each refund shows:
    • Refund ID (clickable for details)
    • Refund amount (formatted with currency)
    • Refund date (completed_at timestamp)
    • Refund status (pending, processing, completed, failed)
    • Requested by (user name)
    • Reason (if provided)
  • And: Summary section shows:
    • Original transaction amount: $100.00
    • Total refunded: $75.00 (3 refunds)
    • Remaining refundable: $25.00
  • And: Visual progress bar shows refund percentage (75% refunded)
  • And: If fully refunded, transaction status shows "refunded" with link to refund history

UC-TXN-006: Initiate Refund

  • Given: User views a completed transaction with refundable amount
  • When: User clicks "Refund" and confirms amount
  • Then: System validates:
    • Refund amount ≤ remaining refundable amount
    • Transaction is in refundable state (completed, not already fully refunded)
    • User has refund permissions
  • And: If validation passes, refund is created in "pending" status
  • And: Approval workflow is triggered if configured
  • And: User receives confirmation with refund ID

UC-TXN-007: Export Transactions

  • Given: User has filtered transactions (last 30 days, status: completed)
  • When: User clicks "Export to CSV"
  • Then: System generates CSV with columns: id, amount, currency, status, customer_email, created_at, payment_method
  • And: File is downloaded to user's device
  • And: For large exports (>10,000 rows), system queues job and sends email with download link

5.3 Payment Method Management

Features

  • Add new payment method (card, bank account, wallet)
  • Edit payment method details (nickname, expiry)
  • Set default payment method
  • Delete / archive payment method
  • Tokenization via payment gateway
  • Validation (card expiry, BIN checks, Luhn algorithm)
  • 3D Secure authentication support

Use Cases & Acceptance Criteria

UC-PM-001: Add Card Payment Method

  • Given: User is on Payment Methods page
  • When: User clicks "Add Card" and enters card details (number, expiry, cvv, name)
  • Then: Client-side validation checks:
    • Card number passes Luhn algorithm
    • Expiry date is in future
    • CVV is 3-4 digits
  • And: Card number is sent to payment gateway for tokenization
  • And: System stores only the token, never raw card data
  • And: Token is linked to merchant account
  • Success: Payment method appears in list with masked number (**** 4242)

UC-PM-002: Validation Errors

  • Given: User enters card details
  • When: Card number is invalid (fails Luhn check)
  • Then: Inline error shown: "Please enter a valid card number"
  • And: Submit button remains disabled
  • And: Field is highlighted in red

UC-PM-003: Gateway Failure

  • Given: User submits valid card details
  • When: Payment gateway is temporarily unavailable
  • Then: User-friendly error shown: "Unable to process card. Please try again."
  • And: Retry button is displayed
  • And: Error is logged with correlation ID
  • And: Circuit breaker tracks failure count

UC-PM-004: Set Default Payment Method

  • Given: User has multiple payment methods
  • When: User clicks "Set Default" on card ending in 4242
  • Then: Card ending in 4242 is marked as is_default = true
  • And: All other payment methods have is_default = false
  • And: Future transactions use this method by default

UC-PM-005: Delete Payment Method

  • Given: User wants to remove a payment method
  • When: User clicks "Delete" on non-default method
  • Then: Confirmation dialog shown: "Are you sure? This cannot be undone."
  • And: If confirmed, method is soft-deleted (deleted_at timestamp set)
  • And: If method is default, user must first set another as default

5.4 Payout Management

Features

  • Request payout (single or batch)
  • Payout workflow: draft → submitted → approved → processing → completed / failed
  • Approval by authorized users (configurable)
  • Retry failed payouts
  • Payout history and reconciliation
  • Settlement fee calculation
  • Multi-currency payout support

Use Cases & Acceptance Criteria

UC-PO-001: Create Payout Request

  • Given: User has available balance > $0
  • When: User clicks "Request Payout"
  • Then: Form requires:
    • Payout amount (≤ available balance)
    • Bank account or payment method
    • Payout date (today or future)
  • And: System validates:
    • Minimum payout amount ($10)
    • Bank account belongs to merchant
  • And: User can save as draft or submit immediately

UC-PO-002: Draft Payout

  • Given: User creates payout request
  • When: User saves as draft
  • Then: Payout status = "draft"
  • And: User can edit draft later
  • And: Draft is visible in "My Drafts" section
  • And: Drafts older than 30 days are auto-deleted

UC-PO-003: Submit for Approval

  • Given: User has drafted payout request
  • When: User clicks "Submit"
  • Then: Payout status changes to "pending_approval"
  • And: Notification is sent to authorized approvers
  • And: Request becomes read-only for submitter

UC-PO-004: Approve Payout

  • Given: User is authorized approver
  • When: User views pending payout and clicks "Approve"
  • Then: System checks:
    • User has approval permission
    • Payout is in "pending_approval" status
  • And: If approved, status changes to "processing"
  • And: Bank transfer is initiated via payment gateway
  • And: Audit log records approval (user_id, timestamp, action)

UC-PO-005: Payout Failure & Retry

  • Given: Payout is in "processing" status
  • When: Bank transfer fails (insufficient funds, invalid account)
  • Then: Status changes to "failed"
  • And: Failure reason is stored (e.g., "Invalid account number")
  • And: Notification sent to payout requester
  • And: User can update bank details and click "Retry"

UC-PO-006: Batch Payout

  • Given: User has multiple pending balances
  • When: User selects multiple payouts and clicks "Batch Process"
  • Then: All selected payouts move to "pending_approval"
  • And: Single approval request covers all selected payouts
  • And: Individual payouts can still fail independently

5.5 Real-time Updates & Synchronization

Features

  • WebSocket subscriptions for transaction updates
  • Real-time balance updates across all connected clients
  • Conflict resolution for concurrent edits (last-write-wins or operational transforms)
  • Change logs and audit trails
  • Graceful fallback to polling when WebSocket unavailable
  • Connection status indicator

Use Cases & Acceptance Criteria

UC-SYNC-001: WebSocket Subscription

  • Given: User opens transaction list
  • When: Page loads, WebSocket connection is established
  • Then: Client subscribes to merchant's transaction channel
  • And: Connection status shown as "Connected" (green dot)
  • And: Connection auto-reconnects if dropped

UC-SYNC-002: Receive Update

  • Given: User A and User B have transaction list open
  • When: Transaction TX-12345 status changes on server
  • Then: Both clients receive update within 1 second
  • And: Transaction row is updated in UI
  • And: Visual highlight (flash or border) draws attention
  • And: Toast notification: "Transaction TX-12345 updated"

UC-SYNC-003: Conflict Resolution

  • Given: User A and User B edit transaction metadata simultaneously
  • When: Both submit changes
  • Then: Last-write-wins strategy applies (server timestamp comparison)
  • And: User whose change was overridden receives notification
  • And: Audit log records both changes with timestamps

UC-SYNC-004: Fallback to Polling

  • Given: WebSocket connection fails (network issue)
  • When: Reconnection attempts fail after 3 retries
  • Then: Client switches to polling mode (every 30 seconds)
  • And: Status indicator changes to "Polling" (yellow dot)
  • And: System attempts WebSocket reconnection every 60 seconds
  • And: Returns to WebSocket when connection restored

5.6 Offline-First Capability

Features

  • Local storage of critical data (transactions, balances, user profile)
  • Sync queue for pending operations
  • Offline indicator in UI
  • Conflict-free sync when reconnected
  • Limited functionality when offline (read-only mode or queued writes)
  • IndexedDB for large datasets

Use Cases & Acceptance Criteria

UC-OFFLINE-001: Detect Offline State

  • Given: User is viewing transaction list
  • When: Network connection is lost
  • Then: UI shows offline indicator (banner or icon)
  • And: Current data remains visible (cached)
  • And: User can navigate previously loaded pages
  • And: New data fetches fail gracefully with "Offline - showing cached data"

UC-OFFLINE-002: View Cached Data

  • Given: User is offline
  • When: User navigates to previously viewed transaction list
  • Then: Cached data is displayed
  • And: "Cached - last updated: 5 minutes ago" indicator shown
  • And: User can view transaction details for cached items

UC-OFFLINE-003: Queue Operation

  • Given: User is offline
  • When: User initiates refund on cached transaction
  • Then: Operation is added to sync queue
  • And: UI shows "Queued for sync" status
  • And: User can view queue status
  • And: Operation executes when connection restored

UC-OFFLINE-004: Sync on Reconnect

  • Given: User has 3 queued operations while offline
  • When: Network connection is restored
  • Then: Sync queue processes operations in order
  • And: Each operation shows progress (uploading, success, failed)
  • And: Failed operations can be retried manually
  • And: Conflicts are flagged for user resolution

UC-OFFLINE-005: Conflict Resolution

  • Given: User edited transaction metadata offline
  • When: User reconnects and server shows different data
  • Then: System detects conflict (server version differs from local)
  • And: User is presented with both versions
  • And: User chooses which version to keep
  • And: Conflict is resolved and sync continues

5.7 Forms & Validation

Features

  • Multi-step forms (e.g., payment method addition: type → details → verification)
  • Real-time field-level validation
  • Async validation (check email uniqueness, verify card with gateway)
  • Form state management (pristine, touched, dirty, submitted)
  • Error messaging with inline and summary-level feedback
  • Submit button disabled until valid
  • Draft save (save-as-you-go)
  • Undo / reset form

Use Cases & Acceptance Criteria

UC-FORM-001: Field Validation

  • Given: User is filling payout form
  • When: User enters invalid email format in email field
  • Then: On blur, field shows inline error: "Please enter a valid email"
  • And: Field is highlighted in red
  • And: Submit button remains disabled

UC-FORM-002: Async Validation

  • Given: User enters email in "Invite Team Member" form
  • When: User stops typing for 500ms (debounce)
  • Then: API call checks if email already exists
  • And: If duplicate, shows error: "This email is already registered"
  • And: Loading spinner shown while checking
  • And: Field is not validated again unless user changes value

UC-FORM-003: Multi-step Form

  • Given: User is adding new payment method
  • When: User completes Step 1 (select type: Card)
  • Then: User is navigated to Step 2 (enter card details)
  • And: Progress indicator shows "Step 2 of 3"
  • And: User can click "Back" to return to Step 1
  • And: User can click "Next" only when current step is valid

UC-FORM-004: Form Submission

  • Given: User has completed all form fields with valid data
  • When: User clicks "Submit"
  • Then: Submit button shows loading state
  • And: Form data is sent to server
  • If successful: Success message shown, form resets, user redirected
  • If failed: Error message shown, form retains user input, submit button re-enabled

UC-FORM-005: Draft Auto-save

  • Given: User is filling complex form (5+ fields)
  • When: User types in any field
  • Then: After 2 seconds of inactivity, form is auto-saved to local storage
  • And: "Draft saved" indicator shown
  • And: If user refreshes page, draft is restored
  • And: Draft is cleared after successful submission

5.8 Error Handling & Resilience

Features

  • Network error detection and user feedback
  • Automatic retry with exponential backoff
  • Circuit breaker pattern for external APIs
  • User-friendly error messages (no stack traces)
  • Graceful degradation (show cached data, disable features)
  • Detailed error logs for debugging
  • Recovery recommendations in UI

Use Cases & Acceptance Criteria

UC-ERROR-001: Network Timeout

  • Given: User is loading transaction list
  • When: API request times out after 30 seconds
  • Then: User sees error: "Unable to load data. Please check your connection."
  • And: Retry button is displayed
  • And: If cached data exists, it's shown with "Last updated: 10 minutes ago"
  • And: Error is logged with correlation ID

UC-ERROR-002: Automatic Retry

  • Given: User submits refund request
  • When: Server returns 503 Service Unavailable
  • Then: Client automatically retries with exponential backoff (1s, 2s, 4s, 8s)
  • And: If all retries fail, user sees error message
  • And: User can manually retry
  • And: Request is idempotent (duplicate requests don't cause double refund)

UC-ERROR-003: Circuit Breaker

  • Given: Payment gateway has 5 consecutive failures
  • When: 6th request is made to gateway
  • Then: Circuit breaker is "open" - request fails immediately
  • And: No actual API call is made to gateway
  • After 60 seconds: Circuit breaker enters "half-open" state
  • And: Test request is sent - if successful, breaker closes; if failed, re-opens

UC-ERROR-004: Validation Error

  • Given: User submits form with invalid data
  • When: Server returns 400 Bad Request with validation errors
  • Then: Errors are displayed inline on each affected field
  • And: Error summary is shown at top of form: "Please fix 2 errors"
  • And: Form scrolls to first error field
  • And: Submit button remains enabled for retry

UC-ERROR-005: Authentication Error

  • Given: User has active session
  • When: API returns 401 Unauthorized
  • Then: Client attempts to refresh token automatically
  • And: If refresh succeeds, original request is retried
  • If refresh fails: User is logged out and redirected to login
  • And: User message: "Your session has expired. Please log in again."

5.9 Data Export & Reporting

Features

  • Export transaction list to CSV
  • Generate PDF reports (daily/weekly/monthly summaries)
  • Schedule recurring reports
  • Reconciliation reports
  • Custom date ranges
  • Audit logs
  • Report templates and customization

Use Cases & Acceptance Criteria

UC-REPORT-001: CSV Export

  • Given: User has filtered transactions (last 30 days, 500 results)
  • When: User clicks "Export to CSV"
  • Then: CSV file is generated with columns:
    • Transaction ID, Date, Amount, Currency, Status, Customer Email, Payment Method
  • And: File is downloaded with filename: transactions_2024-04-10.csv
  • And: Date format: ISO 8601 (2024-04-10T14:30:00Z)
  • And: Amount format: 2 decimal places, no currency symbol (123.45)

UC-REPORT-002: Large Export Queue

  • Given: User requests export of 1,000,000 transactions
  • When: User clicks "Export"
  • Then: User sees message: "Your export is being prepared. We'll email you when ready."
  • And: Export job is queued in background
  • And: CSV is generated and uploaded to temporary storage
  • And: User receives email with download link (valid for 24 hours)
  • And: Download link expires after 24 hours

UC-REPORT-003: PDF Report

  • Given: User generates monthly revenue report
  • When: Report is generated
  • Then: PDF includes:
    • Merchant name and logo
    • Report period (e.g., "March 2024")
    • Summary table (total transactions, total revenue, average order value)
    • Chart showing revenue trend
    • Breakdown by payment method
    • Footer with generated timestamp
  • And: PDF is formatted for A4 paper

UC-REPORT-004: Scheduled Report

  • Given: User wants weekly summary every Monday
  • When: User configures scheduled report
  • Then: User specifies:
    • Report type (e.g., "Weekly Revenue Summary")
    • Recurrence (weekly)
    • Day of week (Monday)
    • Time (9:00 AM)
    • Recipients (email addresses)
  • And: System sends PDF to all recipients at scheduled time
  • And: User can pause, modify, or cancel schedule

UC-REPORT-005: Reconciliation Report

  • Given: Finance officer needs to verify settlement
  • When: User generates reconciliation report for date range
  • Then: Report includes:
    • Total transactions per status
    • Total amount settled vs. expected
    • Discrepancies with explanations
    • Payout details (amount, bank account, status)
    • Fees and adjustments
  • And: Report can be exported to CSV for accounting system

5.10 File Management

Features

  • Upload dispute documents (receipts, screenshots)
  • File upload progress tracking
  • File validation (format, size)
  • Download/preview uploaded files
  • Delete files with audit log
  • Virus scanning
  • Secure storage (encrypted at rest)

Use Cases & Acceptance Criteria

UC-FILE-001: Upload Document

  • Given: User is managing a dispute
  • When: User clicks "Upload Evidence" and selects PDF file
  • Then: Client validates:
    • File type (allowed: PDF, JPG, PNG, maximum 10MB)
    • File size (≤ 10MB)
  • And: Progress bar shows upload percentage
  • And: File is scanned for viruses
  • And: If clean, file is stored securely
  • And: File is linked to dispute record

UC-FILE-002: Upload Failure

  • Given: User is uploading file
  • When: Network connection fails during upload
  • Then: Upload pauses and shows "Upload paused"
  • And: User can click "Resume" when connection restored
  • And: If resume not supported, user can retry upload
  • And: Partial uploads are cleaned up after 24 hours

UC-FILE-003: Preview File

  • Given: User has uploaded image file (JPG, PNG)
  • When: User clicks "Preview"
  • Then: File opens in modal/preview window
  • And: User can zoom and pan image
  • And: Download button is available
  • And: For PDF files, first page is shown as thumbnail

UC-FILE-004: Delete File

  • Given: User wants to remove uploaded document
  • When: User clicks "Delete"
  • Then: Confirmation dialog: "This will permanently delete the file. Continue?"
  • If confirmed: File is soft-deleted (marked for deletion)
  • And: File is permanently deleted after 30-day retention period
  • And: Audit log records deletion (user_id, file_id, timestamp)

5.11 Navigation & Deep Linking

Features

  • URL-based navigation (deep links shareable)
  • Preserve state in URL (filters, pagination, tabs)
  • Back/forward browser support
  • Breadcrumb navigation
  • Mobile bottom tab navigation
  • Navigation guards (unsaved changes warning)

Use Cases & Acceptance Criteria

UC-NAV-001: Shareable Filtered List

  • Given: User has filtered transactions (status: completed, date: last 7 days)
  • When: User copies URL and sends to colleague
  • Then: Colleague opens URL and sees identical filters applied
  • And: URL encodes all filter parameters: /transactions?status=completed&date_from=2024-04-03&date_to=2024-04-10
  • And: Filters can be cleared with "Clear All" button

UC-NAV-002: Browser Navigation

  • Given: User navigates: Dashboard → Transactions → Transaction Detail
  • When: User clicks browser back button
  • Then: User returns to Transactions page
  • And: Previous filter state is preserved
  • And: User can click forward to return to Transaction Detail
  • And: Navigation history is accurate for browser history API

UC-NAV-003: Breadcrumb Navigation

  • Given: User is viewing transaction detail page
  • When: Breadcrumb is displayed at top of page
  • Then: Breadcrumb shows: Home > Transactions > TX-12345
  • And: Each breadcrumb segment is clickable
  • And: Current page is not clickable
  • And: Breadcrumb updates on navigation

UC-NAV-004: Unsaved Changes Warning

  • Given: User has edited form but not submitted
  • When: User attempts to navigate away (click link, back button)
  • Then: Browser dialog: "You have unsaved changes. Leave this page?"
  • And: If user clicks "Stay", navigation is cancelled
  • **If user clicks "Leave", navigation continues and changes are lost

5.12 Notifications

Features

  • In-app toast notifications
  • Push notifications (mobile)
  • Email notifications for critical events
  • Webhook for external integrations
  • Notification preferences per user
  • Notification history and read status

Use Cases & Acceptance Criteria

UC-NOTIF-001: In-App Toast

  • Given: User is viewing dashboard
  • When: Transaction status changes (e.g., refund completed)
  • Then: Toast notification appears in corner:
    • Title: "Refund Completed"
    • Message: "Refund for $50.00 has been processed"
    • Action button: "View Transaction"
  • And: Toast auto-dismisses after 5 seconds
  • And: User can manually dismiss
  • And: Toast queue shows multiple notifications

UC-NOTIF-002: Push Notification

  • Given: User has mobile app installed and notifications enabled
  • When: Large dispute is filed (> $1,000)
  • Then: Push notification sent to user's device
  • And: Notification shows:
    • Title: "High-Value Dispute Filed"
    • Message: "Dispute for $1,500.00 requires attention"
  • And: Tapping notification opens app to dispute detail
  • And: Notification is logged in notification history

UC-NOTIF-003: Email Notification

  • Given: User has enabled email notifications for payout approvals
  • When: Payout requires approval
  • Then: Email is sent to approver:
    • Subject: "Payout Approval Required: $5,000.00"
    • Body: Includes payout details, approve/reject buttons
    • Buttons link directly to approval page
  • And: Email is sent in user's preferred language
  • And: Unsubscribe link is included

UC-NOTIF-004: Webhook

  • Given: Merchant has configured webhook URL
  • When: Transaction is completed
  • Then: POST request is sent to webhook URL
  • And: Payload includes:
    • event: "transaction.completed"
    • data: transaction object (id, amount, status, etc.)
    • timestamp
    • signature (HMAC-SHA256)
  • And: If webhook fails, system retries with exponential backoff
  • And: After 5 failures, webhook is disabled and user is notified

UC-NOTIF-005: Notification Preferences

  • Given: User wants to manage notification settings
  • When: User accesses notification preferences
  • Then: User can configure per notification type:
    • In-app toast (on/off)
    • Push notification (on/off)
    • Email (immediate, daily digest, weekly digest, off)
    • Webhook (enabled/disabled)
  • And: User can set quiet hours (e.g., no notifications 10 PM - 8 AM)

6. Third-Party Integrations

6.1 Payment Gateways

Supported Gateways

  • Stripe (Primary)
    • Features: Cards, Apple Pay, Google Pay, SEPA
    • APIs: Payment Intents, Charges, Refunds, Payouts
    • Webhooks: Payment success/failure, dispute creation
  • Adyen (Secondary)
    • Features: Global payment methods, 3D Secure, recurring payments
    • APIs: Payments, Modifications, Payouts
  • PayPal (Optional)
    • Features: PayPal balance, cards, bank accounts
    • APIs: Orders, Payments, Refunds

Integration Requirements

  • Tokenization - never store raw card data
  • 3D Secure authentication for card payments
  • Webhook signature verification
  • Idempotency for all API calls
  • Fallback between gateways (if primary fails)

6.2 Notification Services

Email

  • SendGrid (Primary)
    • Transactional emails, templates, analytics
    • Rate limit: 300 emails/minute
  • AWS SES (Backup)
    • High volume, cost-effective
    • SPF/DKIM/DMARC authentication

Push Notifications

  • Firebase Cloud Messaging (Android)
  • Apple Push Notification Service (iOS)
  • OneSignal (Cross-platform alternative)

SMS (Optional)

  • Twilio
    • Critical alerts (e.g., large disputes)
    • Verification codes for MFA

6.3 Storage & CDN

File Storage

  • AWS S3 (Primary)
    • Encrypted at rest (AES-256)
    • Lifecycle policies for old files
    • Multi-region replication
  • Cloudflare R2 (Alternative)
    • No egress fees
    • S3-compatible API

CDN

  • Cloudflare
    • Global edge caching
    • DDoS protection
    • Image optimization
  • AWS CloudFront (Alternative)

6.4 Analytics & Monitoring

Application Monitoring

  • Datadog (Primary)
    • APM, log management, error tracking
    • Real-time metrics and alerts
  • Sentry (Error Tracking)
    • JavaScript errors, stack traces
    • User context and breadcrumbs

Business Analytics

  • Google Analytics 4
    • User behavior, conversion funnels
  • Mixpanel or Amplitude
    • Event tracking, user cohorts

6.5 Search & Analytics

Transaction Search

  • Elasticsearch
    • Full-text search across transactions
    • Faceted filtering (date ranges, amounts, status)
    • Aggregations and analytics queries

Alternative: Opensearch (AWS-compatible)

6.6 Communication & Support

Live Chat

  • Intercom or Zendesk
    • In-app chat widget
    • Ticket management

Help Center

  • Zendesk Guide or GitBook
    • Documentation, FAQs
    • Searchable knowledge base

7. Critical Technical Patterns

7.1 Idempotency Strategy

Overview Idempotency is critical in payment systems to prevent double-charging, double-refunds, or duplicate operations during network retries and client retries. An idempotent request can be called multiple times with the same result without causing side effects.

Implementation Requirements

Client Responsibilities

  • Generate Idempotency Key: Client MUST generate a unique UUID v4 for each state-changing operation
  • Include in Headers: Every POST/PUT/PATCH request that mutates state MUST include X-Idempotency-Key header
  • Key Reuse: If a request fails, client MUST retry with the same idempotency key
  • Key Expiration: Client should NOT reuse idempotency keys after 48 hours

Server Responsibilities

  • Store Keys: Server MUST store idempotency keys with associated responses for 48 hours
  • Check Before Processing: For each request, check if idempotency key exists in cache (Redis)
  • Return Cached Response: If key exists, return the stored response without re-processing
  • Key Storage Format: Store as idempotency:{key}{response, status_code, headers, timestamp}

Idempotency Key Lifecycle

sequenceDiagram
    participant Client
    participant Server
    participant Redis
    participant Gateway

    Client->>Server: POST /refunds<br/>X-Idempotency-Key: uuid-123
    Server->>Redis: GET idempotency:uuid-123
    Redis-->>Server: null (not found)
    Server->>Gateway: Process refund
    Gateway-->>Server: Success response
    Server->>Redis: SET idempotency:uuid-123<br/>{response, timestamp}
    Server-->>Client: 200 OK + response

    Note over Client,Redis: Client retries due to timeout

    Client->>Server: POST /refunds<br/>X-Idempotency-Key: uuid-123
    Server->>Redis: GET idempotency:uuid-123
    Redis-->>Server: Cached response found
    Server-->>Client: 200 OK + Cached response<br/>(No duplicate refund processed)
Loading

Required Endpoints

The following endpoints MUST require idempotency keys:

Endpoint Method Reason
/transactions POST Create new transaction
/transactions/:id/refund POST Create refund
/payouts POST Create payout request
/payment-methods POST Add payment method
/disputes/:id/evidence POST Submit dispute evidence

TTL and Cleanup

  • TTL: 48 hours (172,800 seconds)
  • Cleanup: Redis automatically expires keys after TTL
  • Storage Backend: Redis recommended for performance
  • Backup: Consider periodic backup to persistent storage for audit

Error Handling

  • Invalid Key Format: Return 400 Bad Request with message "Invalid idempotency key format"
  • Key Already Used with Different Request: Return 409 Conflict with message "Idempotency key already used for different request body"
  • Key Expired: Treat as new request, generate new response

7.2 Transaction State Machine

Overview Transactions progress through well-defined states. Invalid state transitions must be prevented at the application level.

Transaction States

State Type Description
pending Transient Transaction created, awaiting processing
processing Transient Being processed by payment gateway
completed Transient Successfully captured, not yet settled
settled Transient Funds settled by gateway (available for payout)
failed Final Transaction could not be processed
refunded Final Full or partial refund processed
disputed Transient Chargeback or dispute filed
dispute_won Final Dispute resolved in merchant's favor
dispute_lost Final Dispute resolved against merchant
cancelled Final Transaction cancelled before processing

State Transition Diagram

stateDiagram-v2
    [*] --> pending: Create Transaction
    pending --> processing: Submit to Gateway
    processing --> completed: Capture Success
    processing --> failed: Capture Failed
    processing --> disputed: Chargeback Filed
    completed --> settled: Settlement Complete
    completed --> processing: Re-process (retry)
    completed --> refunded: Refund Initiated
    completed --> disputed: Chargeback Filed
    settled --> refunded: Refund Initiated
    settled --> disputed: Chargeback Filed
    refunded --> [*]
    failed --> [*]
    failed --> processing: Retry (optional)
    disputed --> dispute_won: Resolution: Won
    disputed --> dispute_lost: Resolution: Lost
    dispute_won --> settled: Settlement Reinstated
    dispute_lost --> refunded: Funds Reversed
    cancelled --> [*]
    pending --> cancelled: Cancel Before Submit
Loading

Valid Transitions Table

From State To State Pre-conditions
pending processing Valid payment method, amount > 0
pending cancelled Before gateway submission
processing completed Gateway capture successful
processing failed Gateway capture failed
processing disputed Chargeback received during processing
completed settled Gateway settlement webhook received
completed refunded Refund processed successfully
completed disputed Chargeback received
completed processing Manual retry by authorized user
settled refunded Refund processed successfully
settled disputed Chargeback received
disputed dispute_won Evidence accepted, dispute resolved
disputed dispute_lost Evidence rejected, funds reversed
dispute_won settled Settlement reinstated by gateway
dispute_lost refunded Funds automatically reversed

Invalid Transitions (Must Be Prevented)

Attempted Transition Reason
failedcompleted Failed transactions cannot auto-complete
failedrefunded Cannot refund failed transactions
pendingsettled Must complete before settlement
pendingrefunded Cannot refund unprocessed transactions
disputedsettled Must resolve dispute first
dispute_lostdispute_won Cannot reverse dispute outcome
refundedcompleted Cannot un-refund

State Transition Implementation

Database Constraints

-- Ensure state transition is valid using trigger or application logic
CREATE TRIGGER validate_transaction_state_transition
BEFORE UPDATE ON transactions
FOR EACH ROW
EXECUTE FUNCTION check_valid_state_transition(OLD.status, NEW.status);

Application-Level Validation

const VALID_TRANSITIONS = {
  pending: ['processing', 'cancelled'],
  processing: ['completed', 'failed', 'disputed'],
  completed: ['settled', 'refunded', 'disputed', 'processing'],
  settled: ['refunded', 'disputed'],
  failed: ['processing'], // Optional retry
  disputed: ['dispute_won', 'dispute_lost'],
  dispute_won: ['settled'],
  dispute_lost: ['refunded'],
  refunded: [], // Final state
  cancelled: [] // Final state
};

function canTransition(from: string, to: string): boolean {
  return VALID_TRANSITIONS[from]?.includes(to) ?? false;
}

Business Rules

Settlement Timing

  • Settlement typically occurs 1-3 business days after completed
  • settled_at timestamp marks when funds are available for payout
  • completed_at marks when capture was successful
  • Finance officers use settled_at for reconciliation

Dispute Timing

  • Disputes can only be filed on completed or settled transactions
  • Dispute response deadline is typically 7-14 days from filing
  • Loss of dispute triggers automatic refund

Refund Rules

  • Can only refund completed or settled transactions
  • Partial refunds supported (amount < original transaction)
  • Multiple partial refunds allowed until fully refunded
  • refunded_amount tracks total refunded
  • refundable_amount = amount - refunded_amount

7.3 Financial Precision

Problem Statement JavaScript/TypeScript number type uses 64-bit floating-point representation, which can lead to precision errors in financial calculations:

// Example of floating-point errors
0.1 + 0.2 !== 0.3  // true: 0.30000000000000004
0.3 - 0.1 !== 0.2  // true: 0.19999999999999998

In payment systems, even minor precision errors can cause:

  • Balance discrepancies
  • Reconciliation failures
  • Regulatory compliance issues

Solution: String-Based Representation

API Contract

All monetary values MUST use string type in API requests and responses:

// ❌ BAD: Using number type
interface Transaction {
  amount: number;  // Prone to precision errors
  fee: number;
}

// ✅ GOOD: Using string type
interface Transaction {
  amount: string;  // Always represents cents as string
  fee: string;
}

Format Specification

  • Currency: ISO 4217 code (e.g., "USD", "EUR")
  • Amount Format: Integer string representing the smallest currency unit (cents)
    • USD: "100" = $1.00, "1050" = $10.50
    • JPY: "100" = ¥100 (no decimal places)
    • BHD: "100" = 100 fils (3 decimal places for some currencies)

Client-Side Display

Use locale-aware formatting for display:

function formatCurrency(amount: string, currency: string): string {
  const cents = BigInt(amount);
  const dollars = Number(cents) / getCurrencyDivisor(currency);
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: currency
  }).format(dollars);
}

function getCurrencyDivisor(currency: string): number {
  const decimalPlaces = {
    'USD': 2, 'EUR': 2, 'GBP': 2,
    'JPY': 0, 'KRW': 0,
    'BHD': 3, 'KWD': 3, 'OMR': 3
  };
  return Math.pow(10, decimalPlaces[currency] || 2);
}

Server-Side Calculations

Use decimal math libraries for calculations:

Recommended Libraries

  • Node.js: decimal.js, big.js, bignumber.js
  • Database: Use DECIMAL/NUMERIC types with sufficient precision
import Decimal from 'decimal.js';

class FinancialCalculator {
  static calculateSubtotal(items: {price: string, quantity: number}[]): string {
    return items.reduce((sum, item) => {
      const price = new Decimal(item.price);
      const qty = new Decimal(item.quantity);
      return sum.plus(price.times(qty));
    }, new Decimal(0)).toString();
  }

  static calculateFee(amount: string, feeRate: string): string {
    const amountDec = new Decimal(amount);
    const rateDec = new Decimal(feeRate);
    return amountDec.times(rateDec).toString();
  }

  static calculateNetAmount(amount: string, fee: string): string {
    return new Decimal(amount).minus(new Decimal(fee)).toString();
  }
}

// Example usage
const amount = "10000"; // $100.00
const feeRate = "0.029"; // 2.9%
const fee = FinancialCalculator.calculateFee(amount, feeRate); // "290"
const net = FinancialCalculator.calculateNetAmount(amount, fee); // "9710"

Database Schema

-- ✅ GOOD: Using DECIMAL type
CREATE TABLE transactions (
  id UUID PRIMARY KEY,
  amount DECIMAL(19, 4) NOT NULL,  -- 19 digits total, 4 decimal places
  currency VARCHAR(3) NOT NULL,
  fee_amount DECIMAL(19, 4) NOT NULL,
  net_amount DECIMAL(19, 4) NOT NULL,
  -- ...
);

-- ❌ BAD: Using FLOAT or DOUBLE
CREATE TABLE transactions (
  amount FLOAT NOT NULL,  -- Prone to precision errors
  -- ...
);

Calculation Precision Rules

Operation Rule Example
Addition Decimal(A) + Decimal(B) "100" + "50" = "150"
Subtraction Decimal(A) - Decimal(B) "100" - "30" = "70"
Multiplication Decimal(A) × Decimal(B) "100" × "0.029" = "2.9"
Division Decimal(A) ÷ Decimal(B) "100" ÷ "3" = "33.33..." (round to 2 decimals)
Rounding Always round half-up 2.345 → 2.35, 2.344 → 2.34
Comparison Exact string comparison "100" === "100"

Currency-Specific Precision

Currency Code Decimal Places Example (100)
US Dollar USD 2 $1.00
Euro EUR 2 €1.00
Japanese Yen JPY 0 ¥100
Bahraini Dinar BHD 3 BD 0.100
Kuwaiti Dinar KWD 3 KWD 0.100
Omani Rial OMR 3 RO 0.100

Validation Rules

function validateMonetaryAmount(amount: string, currency: string): boolean {
  // Must be numeric string
  if (!/^\d+$/.test(amount)) {
    return false;
  }

  // Must be non-negative
  if (parseInt(amount, 10) < 0) {
    return false;
  }

  // Check precision based on currency
  const divisor = getCurrencyDivisor(currency);
  const amountNum = BigInt(amount);

  // For currencies with decimals, ensure valid precision
  if (divisor > 1) {
    // Amount should be divisible by the smallest unit
    // This check depends on your specific requirements
  }

  return true;
}

Summary Checklist

  • All API monetary fields use string type
  • Database uses DECIMAL/NUMERIC types
  • Server-side calculations use decimal.js or equivalent
  • Client-side display uses Intl.NumberFormat
  • Currency decimal places configured correctly
  • Rounding rules documented and consistent
  • All monetary calculations use Big/Decimal types

7.4 Multi-Tenancy Strategy

Overview The platform uses a multi-tenant architecture where multiple merchants share the same infrastructure while maintaining complete data isolation.

Multi-Tenancy Model: Shared Schema with Merchant Partitioning

Architecture Decision

┌─────────────────────────────────────────────────────────────┐
│                    Single Database Instance                  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │         Shared Schema (public schema)                  │  │
│  │  ┌─────────────┬─────────────┬─────────────┬────────┐ │  │
│  │  │ merchants   │ users       │ transactions│ payouts │ │  │
│  │  └─────────────┴─────────────┴─────────────┴────────┘ │  │
│  │         All tables include merchant_id column          │  │
│  └───────────────────────────────────────────────────────┘  │
│                                                             │
│  Row-Level Security (RLS) Policies enforce isolation        │
└─────────────────────────────────────────────────────────────┘

Why This Model?

Advantages

  • Cost Efficiency: Shared infrastructure reduces operational costs
  • Rapid Onboarding: New merchants provisioned instantly
  • Resource Utilization: Better resource pooling and utilization
  • Maintenance: Single schema to upgrade and maintain
  • Scalability Path: Can migrate high-volume merchants to isolated schema later

Trade-offs

  • Performance Impact: Requires merchant_id indexing on all queries
  • Noisy Neighbor: One merchant's load can affect others (mitigated with rate limiting)
  • Security Complexity: RLS policies must be thoroughly tested

Implementation Details

Database Schema Pattern

-- All tenant tables follow this pattern
CREATE TABLE transactions (
  id UUID PRIMARY KEY,
  merchant_id UUID NOT NULL,
  -- ... other columns
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  -- Composite index for efficient tenant queries
  INDEX idx_transactions_merchant_created (merchant_id, created_at)
);

-- Foreign keys enforce referential integrity
ALTER TABLE transactions
ADD CONSTRAINT fk_transactions_merchant
FOREIGN KEY (merchant_id) REFERENCES merchants(id);

Row-Level Security (RLS) Policies

-- Enable RLS on all tenant tables
ALTER TABLE transactions ENABLE ROW LEVEL SECURITY;

-- Policy: Users can only see their own merchant's data
CREATE POLICY tenant_isolation_transactions ON transactions
  FOR ALL
  USING (merchant_id = current_setting('app.current_merchant_id')::UUID);

-- Similar policies for all tables
ALTER TABLE payouts ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_payouts ON payouts
  FOR ALL
  USING (merchant_id = current_setting('app.current_merchant_id')::UUID);

Application Context

// Middleware to set merchant context
async function setMerchantContext(req: Request, res: Response, next: NextFunction) {
  const user = await getUserFromToken(req.headers.authorization);
  const merchantId = user.merchant_id;

  // Set merchant context for database session
  await db.query('SET app.current_merchant_id = $1', [merchantId]);

  req.merchantId = merchantId;
  next();
}

Tenant Isolation Guarantees

Guarantee Implementation Verification
Data Isolation RLS policies on all tables Test: User A cannot query User B's data
Session Isolation Merchant context per request Test: Concurrent requests don't leak context
Resource Isolation Rate limiting per merchant Test: One merchant cannot exhaust resources
Backup Isolation Backup/restore by merchant_id Test: Can restore single merchant's data

Scalability: Migration Path to Isolated Schema

For high-volume merchants (>1M transactions/month):

Migration Strategy

graph LR
    A[Shared Schema] -->|Volume Threshold Reached| B{Assess Migration}
    B -->|Complex Queries| C[Create Dedicated Schema]
    B -->|Simple Queries| D[Add Read Replica]
    C --> E[Replicate Data]
    E --> F[Update Routing Logic]
    F --> G[Point-of-Switch]
    G --> H[Isolated Schema Active]
Loading

Migration Steps

  1. Assessment: Evaluate query complexity and performance
  2. Provision: Create isolated schema/database for merchant
  3. Replicate: Copy data from shared to isolated schema
  4. Route: Update application routing based on merchant_id
  5. Cutover: Perform zero-downtime cutover
  6. Cleanup: Remove data from shared schema after verification

Routing Logic

function getDatabaseConnection(merchantId: string): Database {
  const isolatedMerchants = new Set(['high-volume-merchant-1', 'high-volume-merchant-2']);

  if (isolatedMerchants.has(merchantId)) {
    return isolatedDatabases[merchantId];
  }

  return sharedDatabase;
}

Partitioning Strategy

For large shared tables, use partitioning by merchant_id:

-- Partition transactions by merchant_id range
CREATE TABLE transactions (
  id UUID,
  merchant_id UUID,
  -- ... other columns
) PARTITION BY HASH (merchant_id);

-- Create partitions
CREATE TABLE transactions_p0 PARTITION OF transactions
  FOR VALUES WITH (MODULUS 4, REMAINDER 0);

CREATE TABLE transactions_p1 PARTITION OF transactions
  FOR VALUES WITH (MODULUS 4, REMAINDER 1);

CREATE TABLE transactions_p2 PARTITION OF transactions
  FOR VALUES WITH (MODULUS 4, REMAINDER 2);

CREATE TABLE transactions_p3 PARTITION OF transactions
  FOR VALUES WITH (MODULUS 4, REMAINDER 3);

Security Considerations

Tenant Enumeration Prevention

// Prevent brute-force enumeration of merchant IDs
app.use(rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit requests per IP
  keyGenerator: (req) => req.ip
}));

Data Exfiltration Prevention

  • Audit logs track all queries with merchant_id
  • Alert on unusual query patterns
  • Limit bulk export operations

Monitoring

Per-Merchant Metrics

  • Query latency
  • Storage usage
  • API request rate
  • Error rate

Alerting

  • High query latency for specific merchant
  • Unusual storage growth
  • Rate limit violations

7.5 Webhook Security & Secret Rotation

Overview Webhooks enable real-time notifications to external systems. Given their critical role in payment processing, robust security and seamless secret rotation are essential.

Webhook Security Architecture

sequenceDiagram
    participant Platform as Payment Platform
    participant Redis as Key Store
    participant Merchant as Merchant Webhook Endpoint
    participant DB as Database

    Note over Platform,DB: Webhook Configuration

    Platform->>DB: Store webhook URL + secrets
    Platform->>Redis: Cache active secrets

    Note over Platform,Merchant: Webhook Delivery

    Platform->>Platform: Generate signature<br/>HMAC-SHA256(secret, payload)
    Platform->>Merchant: POST webhook<br/>+ X-Webhook-Signature-256
    Merchant->>Merchant: Verify signature<br/>HMAC-SHA256(secret, payload)

    alt Signature Valid
        Merchant-->>Platform: 200 OK
    else Signature Invalid
        Merchant-->>Platform: 401 Unauthorized
        Platform->>Platform: Log security event
    end
Loading

Secret Rotation Strategy

Rolling Secrets Approach

To avoid webhook downtime during secret rotation, support two active secrets simultaneously:

stateDiagram-v2
    [*] --> Active_v1: Initial Secret
    Active_v1 --> Transition: Rotation Initiated
    Transition --> Active_v1_v2: Add New Secret
    Active_v1_v2 --> Active_v2: Remove Old Secret
    Active_v2 --> Transition: Next Rotation
Loading

Secret Rotation Workflow

  1. Generate New Secret: Create new UUID or cryptographically random string
  2. Add to Active Secrets: Add new secret alongside existing secret
  3. Notify Merchant: Send alert about secret rotation
  4. Update Merchant Systems: Merchant updates their verification logic
  5. Verification Period: Wait for configured period (default: 24 hours)
  6. Remove Old Secret: Remove old secret from active secrets
  7. Audit Log: Log rotation event

Implementation Details

Database Schema

CREATE TABLE webhook_configs (
  id UUID PRIMARY KEY,
  merchant_id UUID NOT NULL,
  url VARCHAR(2048) NOT NULL,
  secret_current VARCHAR(255) NOT NULL,
  secret_previous VARCHAR(255),  -- During rotation
  secret_rotation_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT fk_webhook_merchant
    FOREIGN KEY (merchant_id) REFERENCES merchants(id)
);

-- Index for lookups
CREATE INDEX idx_webhook_merchant
  ON webhook_configs(merchant_id);

Webhook Delivery with Signature Verification

interface WebhookPayload {
  event: string;
  data: any;
  timestamp: string;
}

class WebhookService {
  private secrets: Map<string, {current: string, previous?: string}> = new Map();

  async loadSecrets(merchantId: string): Promise<void> {
    const config = await db.query(
      'SELECT secret_current, secret_previous FROM webhook_configs WHERE merchant_id = $1',
      [merchantId]
    );
    this.secrets.set(merchantId, {
      current: config.secret_current,
      previous: config.secret_previous
    });
  }

  async sendWebhook(merchantId: string, payload: WebhookPayload): Promise<boolean> {
    const secrets = this.secrets.get(merchantId);
    if (!secrets) throw new Error('Webhook not configured');

    const config = await db.query('SELECT url FROM webhook_configs WHERE merchant_id = $1', [merchantId]);
    const url = config.url;

    // Try with current secret first
    const signature = this.generateSignature(secrets.current, payload);
    const success = await this.deliver(url, payload, signature);

    if (!success && secrets.previous) {
      // Fallback to previous secret (during rotation)
      const oldSignature = this.generateSignature(secrets.previous, payload);
      return await this.deliver(url, payload, oldSignature);
    }

    return success;
  }

  private generateSignature(secret: string, payload: WebhookPayload): string {
    const payloadString = JSON.stringify(payload);
    return crypto
      .createHmac('sha256', secret)
      .update(payloadString)
      .digest('hex');
  }

  private async deliver(url: string, payload: WebhookPayload, signature: string): Promise<boolean> {
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Webhook-Signature-256': signature,
          'X-Webhook-Timestamp': payload.timestamp,
          'X-Webhook-Id': crypto.randomUUID()
        },
        body: JSON.stringify(payload)
      });

      return response.ok;
    } catch (error) {
      // Log and return false for retry
      logger.error('Webhook delivery failed', { url, error });
      return false;
    }
  }
}

Merchant-Side Verification (Example)

// Merchant's webhook handler
function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  // Use constant-time comparison to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Handle both secrets during rotation
app.post('/webhook', (req, res) => {
  const payload = JSON.stringify(req.body);
  const signature = req.headers['x-webhook-signature-256'];

  // Try current secret first
  if (verifyWebhookSignature(payload, signature, CURRENT_SECRET)) {
    // Process webhook
    return res.status(200).send('OK');
  }

  // Try previous secret (during rotation)
  if (PREVIOUS_SECRET && verifyWebhookSignature(payload, signature, PREVIOUS_SECRET)) {
    // Process webhook
    return res.status(200).send('OK');
  }

  // Invalid signature
  return res.status(401).send('Invalid signature');
});

Secret Rotation API

Initiate Rotation

POST /api/v1/webhooks/rotate-secret
Authorization: Bearer {token}
Content-Type: application/json

{
  "webhook_id": "webhook_123",
  "rotation_delay_hours": 24
}

Response

{
  "webhook_id": "webhook_123",
  "new_secret": "whsec_abc123...",
  "previous_secret": "whsec_xyz789...",
  "rotation_complete_at": "2024-04-11T14:30:00Z",
  "message": "New secret generated. Update your verification code before rotation completes."
}

Check Rotation Status

GET /api/v1/webhooks/{webhook_id}/rotation-status
Authorization: Bearer {token}

Response

{
  "webhook_id": "webhook_123",
  "status": "in_progress",
  "secrets": {
    "current": "whsec_abc123...",
    "previous": "whsec_xyz789..."
  },
  "rotation_started_at": "2024-04-10T14:30:00Z",
  "rotation_complete_at": "2024-04-11T14:30:00Z",
  "message": "Old secret will be removed in 12 hours"
}

Security Best Practices

Secret Generation

function generateWebhookSecret(): string {
  // Generate 32-byte cryptographically secure random string
  const bytes = crypto.randomBytes(32);
  return `whsec_${bytes.toString('hex')}`;
}

Secret Storage

  • Store secrets hashed in database (bcrypt/scrypt) if needed for audit
  • Store secrets encrypted at rest (AWS KMS, vault)
  • Never log secrets or include in error messages

Timestamp Protection

// Prevent replay attacks
function validateTimestamp(timestamp: string): boolean {
  const webhookTime = new Date(timestamp).getTime();
  const currentTime = Date.now();
  const maxAge = 5 * 60 * 1000; // 5 minutes

  return Math.abs(currentTime - webhookTime) < maxAge;
}

Rate Limiting

// Prevent webhook abuse
const webhookRateLimit = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 100, // 100 webhooks per minute per merchant
  keyGenerator: (req) => req.merchantId
});

Monitoring & Alerting

Metrics to Track

  • Webhook delivery success rate
  • Signature verification failures
  • Rotation completion rate
  • Secret age (alert if > 90 days)

Alerts

  • 5% signature failure rate → Possible secret compromise

  • Failed webhook delivery → Retry or manual intervention
  • Secret not rotated in 90 days → Security advisory

9. Architectural Patterns

9.1 State Management

Global State

  • Authentication state (user, token, permissions)
  • Tenant context (merchant_id, settings)
  • Application settings (theme, language, notifications)

Local State

  • Form data (pristine, touched, dirty, submitted)
  • UI flags (loading, errors, modals open)
  • Pagination and sort state

Cache State

  • Transaction lists (keyed by filters)
  • Payment methods (refreshed on mutation)
  • Balances (stale-while-revalidate)

Sync State

  • Pending operations queue
  • Connection status (online/offline/syncing)
  • Conflict flags

9.2 Data Flow

Unidirectional Flow

User Action → Dispatch Action → Reducer → New State → UI Re-render

Optimistic Updates

  1. User initiates action
  2. UI updates immediately (assumes success)
  3. API call made in background
  4. If success: confirmation shown
  5. If failure: rollback state, show error

Rollback Strategy

  • Store previous state before optimistic update
  • On server error, restore previous state
  • Show error message with retry option

Time-Travel Debugging

  • All state changes logged with action type and payload
  • DevTools allows stepping through state history
  • Useful for debugging complex state transitions

9.3 API Contract

RESTful Endpoints

  • Standard HTTP methods (GET, POST, PUT, DELETE)
  • Resource-based URLs (e.g., /transactions, /transactions/:id)
  • Consistent error response format:
    {
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "Invalid email address",
        "details": { "field": "email", "value": "invalid" }
      },
      "request_id": "req_abc123"
    }

Versioning Strategy

  • URL-based versioning: /api/v1/transactions
  • Breaking changes increment version
  • Non-breaking changes don't require version bump

Rate Limiting

  • Per-user rate limits (e.g., 100 requests/minute)
  • Per-endpoint limits (e.g., 10 exports/hour)
  • Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset

Pagination

  • Offset-based: ?page=1&per_page=50
  • Cursor-based for large datasets: ?cursor=abc123&limit=50
  • Response includes pagination metadata:
    {
      "data": [...],
      "meta": {
        "total": 500,
        "page": 1,
        "per_page": 50,
        "total_pages": 10,
        "cursor": "next_cursor_value"
      }
    }

WebSocket

  • Endpoint: wss://api.example.com/ws
  • Authentication via query param: ?token=jwt_token
  • Message format:
    {
      "event": "transaction.updated",
      "data": { "id": "tx_123", "status": "completed" },
      "timestamp": "2024-04-10T14:30:00Z"
    }

9.4 Persistence & Caching

Cache-First Strategy

  1. Check cache for data
  2. If cache hit, return cached data
  3. Fetch from server in background
  4. Update cache with fresh data
  5. Re-render if data changed

Stale-While-Revalidate

  1. Return cached data immediately (even if stale)
  2. Fetch fresh data in background
  3. Update cache when fresh data arrives
  4. Re-render with fresh data

Cache Invalidation

  • Time-based: Invalidate after X minutes
  • Event-based: Invalidate on mutation (e.g., create/update/delete)
  • Tag-based: Cache tagged by entity, invalidate by tag

Local Storage

  • User preferences (theme, language)
  • Form drafts (auto-save)
  • Offline queue (pending operations)
  • Browser localStorage for small data (<5MB)
  • IndexedDB for large datasets

9.5 Error & Exception Handling

Typed Error Hierarchy

class AppError extends Error {
  code: string;
  statusCode: number;
  isRetryable: boolean;
}

class NetworkError extends AppError { /* ... */ }
class ValidationError extends AppError { /* ... */ }
class AuthenticationError extends AppError { /* ... */ }
class AuthorizationError extends AppError { /* ... */ }
class NotFoundError extends AppError { /* ... */ }

Result Pattern (Either Monad)

type Result<T, E> = { success: true; data: T } | { success: false; error: E };

async function processPayment(amount: number): Promise<Result<Payment, Error>> {
  try {
    const payment = await createPayment(amount);
    return { success: true, data: payment };
  } catch (error) {
    return { success: false, error };
  }
}

Structured Logging

  • Log all errors with context:
    {
      "level": "error",
      "message": "Payment gateway timeout",
      "error": {
        "code": "GATEWAY_TIMEOUT",
        "stack": "..."
      },
      "context": {
        "user_id": "user_123",
        "transaction_id": "tx_456",
        "request_id": "req_abc123"
      },
      "timestamp": "2024-04-10T14:30:00Z"
    }

Error Boundaries

  • UI components catch errors and show fallback
  • Prevent entire app from crashing
  • Allow user to report error

10. Data Model

10.1 Entity Relationships

Merchant (1) ----< (N) User
Merchant (1) ----< (N) Transaction
Merchant (1) ----< (N) PaymentMethod
Merchant (1) ----< (N) Payout
Merchant (1) ----< (N) AuditLog
Merchant (1) ----< (N) File
User (1) ----< (N) AuditLog
Transaction (1) ----< (N) Refund
Transaction (1) ----< (N) Dispute
Dispute (1) ----< (N) File
Payout (1) ----< (1) PaymentMethod

10.2 Core Entities

Merchant

interface Merchant {
  id: string;                    // UUID
  name: string;                  // Business name
  slug: string;                  // URL-friendly identifier
  email: string;                 // Primary contact email
  phone?: string;                // Contact phone
  status: 'active' | 'suspended' | 'pending';
  kyc_status: 'verified' | 'pending' | 'rejected';
  default_currency: string;      // ISO 4217 (e.g., 'USD')
  timezone: string;              // IANA timezone (e.g., 'America/New_York')
  settings: MerchantSettings;    // JSON object
  metadata: Record<string, any>; // Flexible key-value store
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  deleted_at?: ISO8601Timestamp; // Soft delete
}

interface MerchantSettings {
  require_mfa: boolean;
  payout_approval_required: boolean;
  minimum_payout_amount: string;  // String representing cents (e.g., "1000" = $10.00)
  payout_currency: string;
  notification_preferences: NotificationPreferences;
}

User

interface User {
  id: string;                    // UUID
  merchant_id: string;           // FK to Merchant
  email: string;                 // Unique
  name: string;                  // Full name
  role: 'owner' | 'manager' | 'finance' | 'support';
  status: 'active' | 'inactive' | 'pending';
  mfa_enabled: boolean;
  last_login_at?: ISO8601Timestamp;
  preferences: UserPreferences;
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  deleted_at?: ISO8601Timestamp;
}

interface UserPreferences {
  language: string;              // 'en', 'es', 'fr', etc.
  timezone: string;
  theme: 'light' | 'dark' | 'system';
  notifications: NotificationPreferences;
}

Transaction

interface Transaction {
  id: string;                    // UUID
  merchant_id: string;           // FK to Merchant
  amount: string;                // String representing cents (e.g., "10000" = $100.00)
  currency: string;              // ISO 4217
  status: 'pending' | 'processing' | 'completed' | 'settled' | 'failed' | 'refunded' | 'disputed' | 'dispute_won' | 'dispute_lost' | 'cancelled';
  payment_method_id: string;     // FK to PaymentMethod
  customer_email: string;
  customer_name?: string;
  description?: string;
  order_reference?: string;      // Merchant's order ID
  metadata: Record<string, any>; // Merchant custom data
  gateway_transaction_id?: string; // External gateway ID
  gateway_response?: any;        // Full gateway response
  refundable_amount: string;     // Calculated field: amount - refunded_amount
  refunded_amount: string;       // Calculated field: total of all refunds
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  completed_at?: ISO8601Timestamp; // When transaction was captured
  settled_at?: ISO8601Timestamp;   // When funds settled (available for payout)
  deleted_at?: ISO8601Timestamp;
}

PaymentMethod

interface PaymentMethod {
  id: string;                    // UUID
  merchant_id: string;           // FK to Merchant
  type: 'card' | 'bank_account' | 'wallet';
  token: string;                 // Gateway token (never store raw data)
  display_name?: string;         // User-friendly name
  is_default: boolean;
  details: PaymentMethodDetails;
  status: 'active' | 'expired' | 'failed';
  last_used_at?: ISO8601Timestamp;
  expires_at?: ISO8601Timestamp; // For cards
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  deleted_at?: ISO8601Timestamp;
}

interface PaymentMethodDetails {
  card?: {
    brand: 'visa' | 'mastercard' | 'amex' | 'discover';
    last4: string;               // "4242"
    expiry_month: number;
    expiry_year: number;
  };
  bank_account?: {
    bank_name: string;
    last4: string;
    account_type: 'checking' | 'savings';
  };
  wallet?: {
    provider: 'paypal' | 'apple_pay' | 'google_pay';
    email: string;
  };
}

Payout

interface Payout {
  id: string;                    // UUID
  merchant_id: string;           // FK to Merchant
  payment_method_id: string;     // FK to PaymentMethod
  amount: string;                // String representing cents (e.g., "10000" = $100.00)
  currency: string;              // ISO 4217
  status: 'draft' | 'pending_approval' | 'approved' | 'processing' | 'completed' | 'failed' | 'cancelled';
  requested_by: string;          // FK to User
  approved_by?: string;          // FK to User
  approved_at?: ISO8601Timestamp;
  scheduled_for?: ISO8601Timestamp;
  processed_at?: ISO8601Timestamp;
  fee_amount: string;            // String representing processing fee (e.g., "290" = $2.90)
  net_amount: string;            // amount - fee_amount (e.g., "9710" = $97.10)
  failure_reason?: string;
  gateway_payout_id?: string;    // External gateway ID
  metadata: Record<string, any>;
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  deleted_at?: ISO8601Timestamp;
}

Refund

interface Refund {
  id: string;                    // UUID
  transaction_id: string;        // FK to Transaction
  amount: string;                // String representing cents (e.g., "5000" = $50.00)
  currency: string;              // ISO 4217
  status: 'pending' | 'processing' | 'completed' | 'failed';
  reason?: string;
  requested_by: string;          // FK to User
  gateway_refund_id?: string;    // External gateway ID
  failure_reason?: string;
  is_partial: boolean;          // True if amount < original transaction amount
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  completed_at?: ISO8601Timestamp;
}

Dispute

interface Dispute {
  id: string;                    // UUID
  transaction_id: string;        // FK to Transaction
  amount: string;                // String representing cents (e.g., "15000" = $150.00)
  currency: string;              // ISO 4217
  status: 'open' | 'under_review' | 'won' | 'lost' | 'cancelled';
  reason: string;                // Chargeback reason code
  deadline: ISO8601Timestamp;    // Response deadline
  evidence_submitted: boolean;
  evidence_deadline: ISO8601Timestamp;
  outcome?: 'won' | 'lost';
  loss_reason?: string;
  created_at: ISO8601Timestamp;
  updated_at: ISO8601Timestamp;
  resolved_at?: ISO8601Timestamp;
}

File

interface File {
  id: string;                    // UUID
  merchant_id: string;           // FK to Merchant
  entity_type: 'transaction' | 'dispute' | 'user' | 'payout';
  entity_id: string;             // ID of associated entity
  filename: string;
  mime_type: string;
  size_bytes: number;
  storage_path: string;          // S3 key or CDN URL
  uploaded_by: string;           // FK to User
  virus_scan_status: 'pending' | 'clean' | 'infected';
  created_at: ISO8601Timestamp;
  deleted_at?: ISO8601Timestamp;
}

AuditLog

interface AuditLog {
  id: string;                    // UUID
  merchant_id: string;           // FK to Merchant
  user_id: string;               // FK to User (or 'system')
  action: string;                // 'create', 'update', 'delete', 'approve', etc.
  entity_type: string;           // 'transaction', 'payout', etc.
  entity_id: string;             // ID of affected entity
  changes: {
    before?: Record<string, any>;
    after?: Record<string, any>;
  };
  ip_address?: string;
  user_agent?: string;
  created_at: ISO8601Timestamp;
}

10.3 Indexes & Optimization

Critical Indexes

-- Transactions
CREATE INDEX idx_transactions_merchant_status ON transactions(merchant_id, status);
CREATE INDEX idx_transactions_created_at ON transactions(created_at DESC);
CREATE INDEX idx_transactions_customer_email ON transactions(customer_email);

-- Users
CREATE UNIQUE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_merchant_role ON users(merchant_id, role);

-- Payouts
CREATE INDEX idx_payouts_merchant_status ON payouts(merchant_id, status);
CREATE INDEX idx_payouts_scheduled_for ON payouts(scheduled_for) WHERE status = 'approved';

-- Audit Logs
CREATE INDEX idx_audit_logs_merchant ON audit_logs(merchant_id, created_at DESC);
CREATE INDEX idx_audit_logs_entity ON audit_logs(entity_type, entity_id);

Data Retention

  • Transactions: 7 years (compliance)
  • Audit logs: 7 years (compliance)
  • Files: 3 years after associated entity deletion
  • Export jobs: 30 days
  • Notification history: 90 days

11. Scalability & Capacity Planning

11.1 Expected Volumes

Transaction Volume

  • Small merchants: 1,000 - 10,000 transactions/month
  • Medium merchants: 10,000 - 100,000 transactions/month
  • Large merchants: 100,000 - 1,000,000+ transactions/month
  • Peak traffic: 10x normal volume during sale events

User Volume

  • Average merchant: 5 - 20 users
  • Large merchants: 50 - 200 users
  • Concurrent users: 20% of total users

Data Growth

  • Transaction: ~1 KB per record
  • Audit log: ~500 bytes per record
  • With 1M transactions/month: ~1 GB/month for transactions + audit logs

11.2 Performance Targets

API Response Times

  • Transaction list (50 items): < 500ms (p95)
  • Transaction detail: < 200ms (p95)
  • Search query: < 1s (p95)
  • Export generation: < 30s for 10K rows
  • WebSocket message delivery: < 100ms (p99)

Page Load Times

  • Initial load: < 2s (p95)
  • Route transition: < 500ms (p95)
  • First Contentful Paint (FCP): < 1.5s
  • Time to Interactive (TTI): < 3.5s

Database Queries

  • Simple lookups (by ID): < 10ms
  • Filtered queries (with indexes): < 100ms
  • Complex aggregations: < 500ms
  • Full-text search: < 1s

11.3 Scaling Strategies

Horizontal Scaling

  • Stateless API servers behind load balancer
  • Database read replicas for read-heavy workloads
  • Connection pooling (e.g., PgBouncer for PostgreSQL)
  • Microservices architecture for future growth

Vertical Scaling

  • Database server with sufficient RAM for cache
  • SSD storage for fast I/O
  • CPU optimization for encryption/decryption

Caching Strategy

  • Redis cache for:
    • Session data
    • Frequent query results
    • Rate limit counters
  • CDN for static assets
  • Browser caching headers (1 hour for API responses)

Database Partitioning

  • Partition transactions by date (monthly)
  • Partition audit logs by date
  • Archive old partitions to cold storage

12. Accessibility & Internationalization

12.1 Accessibility (WCAG 2.1 AA)

Keyboard Navigation

  • All interactive elements keyboard-accessible
  • Visible focus indicators (2px solid outline, high contrast)
  • Skip navigation link
  • Logical tab order

Screen Reader Support

  • ARIA labels for icons and buttons without text
  • Semantic HTML (nav, main, article, etc.)
  • Alt text for all images
  • Live regions for dynamic content updates

Color & Contrast

  • Minimum contrast ratio 4.5:1 for normal text
  • Minimum contrast ratio 3:1 for large text (18pt+)
  • Color not only way to convey information (icons, patterns)
  • Support for high contrast mode

Form Accessibility

  • Labels associated with inputs (for/id attributes)
  • Error messages announced to screen readers
  • Instructions provided before form
  • Required fields clearly marked

Responsive Design

  • Works with screen magnification (up to 400%)
  • Touch targets minimum 44x44 pixels
  • Content reflows without horizontal scrolling at 400% zoom
  • Orientation changes handled gracefully

12.2 Internationalization (i18n)

Language Support

  • Default: English (en)
  • Supported languages: Spanish (es), French (fr), German (de), Portuguese (pt), Japanese (ja)
  • Language selection in user preferences
  • Browser language detection for new users

Number & Currency Formatting

  • Locale-specific number formatting (e.g., 1,234.56 vs 1.234,56)
  • Currency symbols and placement ($1,000 vs 1.000$)
  • Decimal precision based on currency (JPY: 0 decimals, USD: 2)

Date & Time Formatting

  • Locale-specific date formats (MM/DD/YYYY vs DD/MM/YYYY)
  • Timezone-aware display (user's local timezone)
  • Relative time (2 hours ago, yesterday)

Text Direction

  • LTR (Left-to-Right) for most languages
  • RTL (Right-to-Left) for Arabic, Hebrew, etc.
  • CSS logical properties (margin-inline-start vs margin-left)

Character Encoding

  • UTF-8 for all data
  • Support for Unicode characters (emojis, special characters)

Pluralization

  • Language-specific plural rules (English: 1 item, 2 items; Arabic has 6 plural forms)

13. Edge Cases & Error Scenarios

13.1 Network Scenarios

Slow Connection

  • Action: Show loading indicators
  • Timeout: 30 seconds for API calls
  • Fallback: Show cached data if available
  • UX: Progressive loading (skeleton screens)

Intermittent Connection

  • Action: Queue requests, retry with backoff
  • Detection: Navigator.onLine API, failed pings
  • UX: Show "Offline - queued" status
  • Sync: Process queue when reconnected

Complete Outage

  • Action: Show friendly offline page
  • Fallback: Serve cached critical pages (service worker)
  • UX: Clear message with estimated recovery time
  • Recovery: Auto-refresh when connection returns

13.2 Concurrency Scenarios

Simultaneous Updates

  • Scenario: Two users edit same transaction
  • Resolution: Last-write-wins with timestamp comparison
  • UX: Notify user whose change was overridden
  • Audit: Log both changes with timestamps

Duplicate Requests

  • Scenario: User double-clicks submit button
  • Prevention: Disable submit button on first click
  • Server: Idempotency keys to prevent duplicates
  • UX: Clear feedback when request is processing

Race Conditions

  • Scenario: Refund initiated while transaction status changing
  • Prevention: Database row locking or optimistic concurrency
  • Resolution: Return conflict error, retry logic
  • UX: Inform user to try again

13.3 Data Integrity Scenarios

Partial Failures

  • Scenario: Batch payout - some succeed, some fail
  • Handling: Mark each payout individually (completed/failed)
  • UX: Show which succeeded, which failed, why
  • Retry: Allow retry of failed items only

Orphaned Records

  • Scenario: Transaction without merchant (merchant deleted)
  • Prevention: Soft deletes, cascade checks
  • Handling: Flag orphaned records for review
  • Cleanup: Job to resolve or archive orphaned data

Data Corruption

  • Scenario: Invalid data in database
  • Prevention: Strict validation on writes
  • Detection: Data integrity checks (checksums)
  • Recovery: Restore from backup, fix corrupted records

13.4 Security Scenarios

Token Theft

  • Scenario: JWT token stolen via XSS
  • Prevention: httpOnly cookies, short-lived tokens
  • Detection: Anomaly detection (unusual IP, location)
  • Response: Revoke token, force re-authentication

Rate Limit Bypass

  • Scenario: Attacker uses multiple IPs to bypass rate limits
  • Prevention: Rate limit by user_id, not just IP
  • Detection: Suspicious pattern recognition
  • Response: CAPTCHA, temporary account lock

SQL Injection

  • Scenario: Malicious input in search field
  • Prevention: Parameterized queries, input sanitization
  • Detection: SQL query analysis
  • Response: Block request, alert security team

13.5 Payment Gateway Scenarios

Gateway Timeout

  • Scenario: Payment gateway doesn't respond within 30 seconds
  • Action: Mark transaction as "pending"
  • Retry: Check status via webhook or periodic polling
  • UX: Show "Processing - check back later" message

Gateway Downtime

  • Scenario: Payment gateway completely unavailable
  • Action: Circuit breaker opens
  • Fallback: Use secondary gateway if configured
  • UX: Show "Payment processing temporarily unavailable"

Webhook Failure

  • Scenario: Webhook notification not delivered
  • Retry: Exponential backoff (5 min, 15 min, 1 hour, 4 hours)
  • Max retries: 5 attempts
  • Fallback: Manual retry option in admin panel

Double Payment

  • Scenario: Gateway processes payment twice
  • Prevention: Idempotency keys
  • Detection: Duplicate transaction_id check
  • Resolution: Refund duplicate, alert merchant

13.6 File Upload Scenarios

Virus Detection

  • Scenario: Uploaded file contains malware
  • Action: Quarantine file, mark as "infected"
  • UX: Show "File blocked: security threat"
  • Notification: Alert security team

Storage Quota Exceeded

  • Scenario: Merchant exceeds file storage limit
  • Prevention: Show storage usage meter
  • UX: Block uploads, prompt to delete old files
  • Resolution: Upgrade plan or archive old files

Corrupted Upload

  • Scenario: File upload completes but file is corrupted
  • Detection: Checksum validation after upload
  • Action: Delete corrupted file, show error
  • UX: Prompt user to re-upload

13.7 Data Sync Scenarios

Sync Conflict

  • Scenario: Offline changes conflict with server changes
  • Detection: Version/timestamp comparison
  • UX: Show both versions, let user choose
  • Resolution: Manual merge or override

Lost Sync

  • Scenario: Sync queue data lost (device failure)
  • Prevention: Persist queue to durable storage
  • Detection: Queue完整性检查
  • Recovery: Re-sync from server, flag lost changes

Clock Skew

  • Scenario: Client clock differs from server
  • Impact: Timestamps, expirations, sorting
  • Prevention: Use server time for critical operations
  • Detection: NTP sync, timestamp validation

13.8 External Service Failures

Email Service Down

  • Scenario: Transactional email provider unavailable
  • Fallback: Queue emails, retry when service returns
  • Max queue: 10,000 emails
  • Alert: Notify admin if queue grows > 5,000

Push Notification Fail

  • Scenario: FCM/APNS tokens invalid
  • Detection: Unregistration feedback
  • Action: Remove invalid tokens, prompt user to re-enable
  • Fallback: In-app notification

CDN Failure

  • Scenario: Static assets not loading from CDN
  • Fallback: Serve from origin server
  • Detection: Health checks every 30 seconds
  • Alert: Notify admin of CDN issues

14. Testing Strategy

14.1 Test Categories

Unit Tests

  • Coverage Goal: 80%+ code coverage
  • What to Test:
    • State reducers and actions
    • Form validators
    • Utility functions (formatters, parsers)
    • Business logic (calculations, validations)
  • Tools: Vitest, Jest, Mocha

Integration Tests

  • Coverage Goal: All critical user flows
  • What to Test:
    • API calls with mocked responses
    • Form submission flow
    • Authentication flow
    • Cache invalidation
    • Error handling
  • Tools: Supertest, Playwright API, MSW (Mock Service Worker)

End-to-End (E2E) Tests

  • Coverage Goal: Core user journeys
  • What to Test:
    • Login → Dashboard → Transaction List → Transaction Detail → Logout
    • Create Refund → Verify Status → View in History
    • Upload File → Verify Upload → Delete File
    • Apply Filters → Verify Results → Export CSV
  • Tools: Playwright, Cypress, Puppeteer
  • Environments: Staging environment (not production)

Performance Tests

  • What to Test:
    • API response times under load
    • Database query performance
    • Frontend rendering performance
    • WebSocket connection handling
    • Concurrent user simulation (100, 500, 1000 users)
  • Tools: k6, Locust, JMeter, Lighthouse

Offline/Sync Tests

  • What to Test:
    • Offline mode detection
    • Data caching
    • Sync queue management
    • Conflict resolution
    • Reconnection handling
  • Tools: Chrome DevTools Network throttling, Playwright offline mode

Security Tests

  • What to Test:
    • Authentication/authorization (RBAC, RLS)
    • Input validation (SQL injection, XSS)
    • CSRF protection
    • Rate limiting
    • Token expiration/refresh
    • File upload security
  • Tools: OWASP ZAP, Burp Suite, custom security tests

Accessibility Tests

  • What to Test:
    • Keyboard navigation
    • Screen reader compatibility
    • Color contrast
    • ARIA labels
    • Form accessibility
  • Tools: axe DevTools, WAVE, Lighthouse

14.2 Test Data Management

Test Data Strategy

  • Use fixtures for consistent test data
  • Generate random data for uniqueness tests
  • Mock external dependencies (gateways, email services)
  • Clean up test data after each test run

Environments

  • Local: Unit tests, integration tests with mocks
  • Dev: Integration tests with real services
  • Staging: E2E tests, performance tests
  • Production: Smoke tests (read-only, non-destructive)

14.3 Test Automation

CI/CD Integration

  • Run tests on every pull request
  • Block merge if tests fail
  • Parallel test execution for speed
  • Generate coverage reports
  • Notify team of failures

Test Reporting

  • Test results dashboard (e.g., GitHub Actions, CircleCI)
  • Coverage trends over time
  • Flaky test detection
  • Performance regression alerts

15. Deployment & Infrastructure

15.1 Architecture Overview

Frontend

  • Framework: React, Vue, or Angular (implementation choice)
  • Hosting: Static hosting on CDN (Cloudflare, AWS CloudFront, Vercel)
  • Build process: TypeScript → JavaScript (ES2022), minification, code splitting
  • Deployment: Git push triggers automatic build and deploy

Backend

  • Framework: Node.js (Express, Fastify) or Encore.ts
  • Containerization: Docker containers
  • Orchestration: Kubernetes, AWS ECS, or equivalent
  • API Gateway: NGINX, AWS API Gateway, or Kong
  • Scaling: Horizontal scaling with auto-scaling policies

Database

  • Primary: PostgreSQL (recommended) or MySQL
  • Replication: Read replicas for read-heavy workloads
  • Backup: Daily full backups + continuous WAL archiving
  • High Availability: Multi-region replication
  • Connection Pooling: PgBouncer (PostgreSQL) or ProxySQL (MySQL)

Cache

  • Redis or Memcached
  • Use cases: Session storage, query cache, rate limiting
  • Persistence: RDB snapshots every 5 minutes
  • High Availability: Redis Cluster or AWS ElastiCache

Message Queue

  • RabbitMQ, AWS SQS, or Kafka
  • Use cases: Async tasks (payouts, reports, notifications)
  • Dead Letter Queue: For failed messages
  • Monitoring: Queue depth, processing time

Search

  • Elasticsearch or OpenSearch
  • Use cases: Transaction search, analytics
  • Indexing: Real-time sync from primary database
  • Scaling: Horizontal scaling with sharding

File Storage

  • Object Storage: AWS S3, Cloudflare R2, or equivalent
  • Encryption: Server-side encryption (AES-256)
  • Lifecycle: Transition old files to Glacier after 90 days
  • CDN: Cloudflare or CloudFront for fast delivery

15.2 Infrastructure as Code

Tools

  • Terraform or AWS CDK
  • Version control for infrastructure
  • Reproducible deployments
  • Multi-environment support (dev, staging, prod)

Components

  • VPC and networking
  • Load balancers
  • Database clusters
  • Redis clusters
  • S3 buckets
  • IAM roles and policies

15.3 Monitoring & Observability

Application Monitoring

  • APM: Datadog, New Relic, or AppDynamics
  • Metrics: Request rate, error rate, latency
  • Distributed tracing: Request across services
  • Error tracking: Sentry or Bugsnag

Infrastructure Monitoring

  • CPU, memory, disk usage
  • Network traffic
  • Database connections, query performance
  • Cache hit/miss ratio
  • Queue depth

Logging

  • Centralized logging: ELK Stack, CloudWatch Logs, or Datadog Logs
  • Structured logging (JSON)
  • Log levels: ERROR, WARN, INFO, DEBUG
  • Sensitive data redaction (no credit card numbers, tokens)

Alerting

  • Critical alerts (pager duty): Service down, database failure, security breach
  • Warning alerts (email): High error rate, slow response times, disk space low
  • Recovery: Automated rollback, scale up

15.4 Disaster Recovery

Backup Strategy

  • Database: Daily full backups + continuous WAL archiving
  • Point-in-time recovery (PITR) capability
  • Backups stored in multiple regions
  • Weekly restore test

High Availability

  • Multi-AZ deployment
  • Auto-scaling for web servers
  • Database failover (primary → replica)
  • DNS failover for multi-region

Incident Response

  • Runbooks for common scenarios
  • On-call rotation
  • Incident severity levels (SEV1-SEV4)
  • Post-incident reviews (blameless)

16. Compliance & Security

16.1 PCI-DSS Compliance

Requirements

  • Never store raw card data (PAN)
  • Store only tokens from payment gateway
  • Encrypt data in transit (TLS 1.2+)
  • Encrypt data at rest (AES-256)
  • Restrict access to cardholder data
  • Regular vulnerability scans
  • Annual penetration testing

Implementation

  • Use PCI-compliant payment gateway (Stripe, Adyen)
  • Server-side tokenization (never client-side card data to server)
  • Mask card numbers in UI (**** 4242)
  • Audit trail for all card-related operations

16.2 GDPR Compliance

Requirements

  • Data consent: Explicit consent for data collection
  • Right to access: Users can request all their data
  • Right to deletion: Users can request account deletion
  • Right to portability: Export data in machine-readable format
  • Data minimization: Collect only necessary data
  • Privacy by design: Privacy built into system

Implementation

  • Cookie consent banner
  • Data export endpoint
  • Account deletion flow (soft delete with 30-day grace period)
  • Data retention policies
  • Privacy policy and terms of service

16.3 Audit Trails

Requirements

  • Log all mutations (create, update, delete)
  • Include: user_id, timestamp, action, entity_type, entity_id, changes
  • Immutable logs (cannot be deleted or modified)
  • Retention: 7 years (compliance)
  • Exportable for audits

Implementation

  • AuditLog entity (see Data Model)
  • Automatic logging via middleware or triggers
  • Queryable by merchant, user, entity, date range
  • Regular backups of audit logs

16.4 Encryption

In Transit

  • TLS 1.2 or 1.3 for all API calls
  • HSTS enabled
  • Certificate management (auto-renewal)
  • Secure cipher suites

At Rest

  • Database encryption (TDE or application-level)
  • File storage encryption (S3 server-side encryption)
  • Backup encryption
  • Key management: AWS KMS or equivalent

Application

  • Sensitive fields encrypted in database (if not using TDE)
  • Environment variables for secrets
  • No secrets in code or logs

16.5 Access Control

Authentication

  • Strong password policy (12+ chars, mixed case, numbers, symbols)
  • MFA for all users (configurable requirement)
  • Session timeout (configurable, default 24 hours)
  • Password reset with secure token

Authorization

  • RBAC (Role-Based Access Control)
  • Row-Level Security (RLS) for multi-tenancy
  • Principle of least privilege
  • Regular access reviews

Network

  • IP whitelisting for admin access (optional)
  • API key rotation for external integrations
  • Rate limiting per user
  • DDoS protection (Cloudflare, AWS Shield)

16.6 Security Best Practices

Input Validation

  • Validate all user input on client and server
  • Sanitize data to prevent XSS
  • Use parameterized queries to prevent SQL injection
  • Content Security Policy (CSP) headers

Dependencies

  • Regular dependency updates
  • Security scanning (npm audit, Snyk)
  • Use vetted, maintained libraries

Code Security

  • Code review process
  • Static analysis (ESLint security plugins)
  • Secret scanning (detect committed secrets)
  • Secure coding training

Incident Response

  • Security incident response plan
  • Regular security drills
  • Bug bounty program (optional)
  • Disclosure policy

17. Success Metrics

17.1 Performance Metrics

Response Times

  • Page load: < 2s (p95)
  • API response: < 500ms (p95)
  • Database query: < 100ms (p95) for indexed queries
  • WebSocket message delivery: < 100ms (p99)

Availability

  • Uptime: 99.9% (8.76 hours downtime/year)
  • Error rate: < 0.1% of requests
  • Successful transactions: > 99.5%

Scalability

  • Handle 10,000 concurrent users
  • Process 1,000 transactions/second
  • Support 1M+ transactions/month per merchant

17.2 User Experience Metrics

Usability

  • < 3 clicks to refund a transaction
  • < 5 seconds to find a transaction
  • < 10 seconds to export 10,000 transactions
  • Offline-first: All cached data accessible offline

Satisfaction

  • NPS score: > 50
  • CSAT score: > 4.5/5
  • Task completion rate: > 95%

Onboarding

  • < 10 minutes to complete first transaction
  • < 5 minutes to set up payment method
  • < 2 minutes to invite team member

17.3 Data Quality Metrics

Accuracy

  • Real-time balance sync: 100% accuracy
  • Zero transaction loss (all transactions recorded)
  • Audit trail completeness: 100%

Consistency

  • No orphaned records
  • No data inconsistencies across replicas
  • Reconciliation matches 100%

17.4 Developer Experience Metrics

Setup

  • < 10 minutes to local setup
  • Clear error messages for common issues
  • Comprehensive documentation

Code Quality

  • Test coverage: > 80%
  • Code review turnaround: < 24 hours
  • Bug fix time: < 48 hours for P0 bugs

17.5 Security Metrics

Vulnerabilities

  • Zero critical vulnerabilities
  • Zero high-severity vulnerabilities in production
  • < 5 medium-severity vulnerabilities
  • All vulnerabilities patched within SLA

Compliance

  • 100% of mutations audited
  • 100% of sensitive data encrypted
  • 100% PCI-DSS compliance
  • 100% GDPR compliance

Incidents

  • Security incidents: < 1 per year
  • Data breaches: 0
  • Mean time to detect (MTTD): < 1 hour
  • Mean time to respond (MTTR): < 4 hours

18. Visual Diagrams

18.1 Payment Life Cycle

sequenceDiagram
    participant Customer
    participant Merchant as Merchant App
    participant Platform as Payment Platform
    participant Gateway as Payment Gateway
    participant Bank as Customer Bank

    Note over Customer,Bank: Transaction Flow

    Customer->>Merchant: Initiates payment
    Merchant->>Platform: POST /transactions<br/>{amount, payment_method}
    Platform->>Platform: Validate request<br/>Check idempotency key
    Platform->>Gateway: Create payment intent
    Gateway-->>Platform: Payment intent created
    Platform-->>Merchant: Return client_secret
    Merchant->>Gateway: Confirm payment<br/>(client-side)
    Gateway->>Bank: Process charge
    Bank-->>Gateway: Charge response

    alt Charge Successful
        Gateway-->>Platform: Webhook: payment.succeeded
        Platform->>Platform: Update transaction: completed
        Platform->>Merchant: WebSocket: transaction.updated
        Merchant->>Customer: Show success
        Note over Platform,Gateway: Settlement (1-3 business days)
        Gateway-->>Platform: Webhook: payment.succeeded.settled
        Platform->>Platform: Update transaction: settled
        Platform->>Merchant: WebSocket: balance.updated
    else Charge Failed
        Gateway-->>Platform: Webhook: payment.failed
        Platform->>Platform: Update transaction: failed
        Platform->>Merchant: WebSocket: transaction.updated
        Merchant->>Customer: Show error
    end

    Note over Customer,Bank: Refund Flow (if requested)

    Merchant->>Platform: POST /transactions/:id/refund
    Platform->>Platform: Validate refundable amount<br/>Check idempotency key
    Platform->>Gateway: Create refund
    Gateway-->>Platform: Refund created
    Platform->>Platform: Update transaction: refunded_amount += amount
    Platform->>Merchant: WebSocket: refund.created
    Gateway->>Bank: Process refund
    Bank-->>Gateway: Refund processed
    Gateway-->>Platform: Webhook: refund.succeeded
    Platform->>Platform: Update refund: completed
    Platform->>Merchant: WebSocket: refund.completed
Loading

18.2 Transaction State Transitions

stateDiagram-v2
    [*] --> Pending: Customer initiates payment
    Pending --> Processing: Merchant submits to gateway
    Processing --> Completed: Payment captured
    Processing --> Failed: Payment declined
    Processing --> Disputed: Chargeback filed
    Completed --> Settled: Gateway settlement
    Completed --> Refunded: Refund processed
    Completed --> Disputed: Chargeback filed
    Settled --> Refunded: Refund processed
    Settled --> Disputed: Chargeback filed
    Failed --> [*]
    Refunded --> [*]
    Disputed --> DisputeWon: Merchant wins
    Disputed --> DisputeLost: Merchant loses
    DisputeWon --> Settled: Funds reinstated
    DisputeLost --> Refunded: Funds reversed

    note right of Completed
        Transaction captured
        Funds not yet available
        for payout
    end note

    note right of Settled
        Funds settled by gateway
        Available for payout
    end note
Loading

18.3 Offline Sync Logic

stateDiagram-v2
    [*] --> Online: App starts
    Online --> Offline: Network lost
    Offline --> Syncing: Network restored
    Syncing --> Online: Sync complete
    Online --> [*]: App closed

    note right of Online
        - Real-time updates via WebSocket
        - Direct API calls
        - Cache invalidation on mutations
    end note

    note right of Offline
        - Show cached data
        - Queue mutations in IndexedDB
        - Disable features requiring live data
        - Show offline indicator
    end note

    note right of Syncing
        - Process queue in order
        - Resolve conflicts
        - Update cache
        - Reconnect WebSocket
    end note
Loading

18.4 Multi-Tenancy Data Isolation

graph TB
    subgraph "Shared Database"
        subgraph "Merchant A"
            M1[Merchant: merchant_a]
            U1[User: user_a1, user_a2]
            T1[Transaction: tx_a1, tx_a2, tx_a3]
            P1[Payout: payout_a1]
        end

        subgraph "Merchant B"
            M2[Merchant: merchant_b]
            U2[User: user_b1, user_b2]
            T2[Transaction: tx_b1, tx_b2]
            P2[Payout: payout_b1, payout_b2]
        end

        subgraph "Shared Tables"
            Merchants[Merchants table]
            Users[Users table]
            Transactions[Transactions table]
            Payouts[Payouts table]
        end
    end

    M1 -.->|merchant_id| Merchants
    U1 -.->|merchant_id| Users
    T1 -.->|merchant_id| Transactions
    P1 -.->|merchant_id| Payouts

    M2 -.->|merchant_id| Merchants
    U2 -.->|merchant_id| Users
    T2 -.->|merchant_id| Transactions
    P2 -.->|merchant_id| Payouts

    style M1 fill:#e1f5ff
    style U1 fill:#e1f5ff
    style T1 fill:#e1f5ff
    style P1 fill:#e1f5ff
    style M2 fill:#fff4e1
    style U2 fill:#fff4e1
    style T2 fill:#fff4e1
    style P2 fill:#fff4e1
Loading

18.5 Idempotency Key Lifecycle

sequenceDiagram
    participant Client
    participant API as API Server
    participant Redis as Cache
    participant Gateway as Payment Gateway

    Client->>API: POST /refunds<br/>X-Idempotency-Key: uuid-123
    API->>Redis: GET idempotency:uuid-123
    Redis-->>API: null (not found)

    API->>Gateway: Process refund
    Gateway-->>API: Success: refund_id=R456

    API->>Redis: SET idempotency:uuid-123<br/>value={response}<br/>TTL=48h
    API-->>Client: 200 OK<br/>{id: R456, ...}

    Note over Client,Redis: Network timeout - client retries

    Client->>API: POST /refunds<br/>X-Idempotency-Key: uuid-123
    API->>Redis: GET idempotency:uuid-123
    Redis-->>API: Found: cached response

    API-->>Client: 200 OK<br/>{id: R456, ...}<br/>(Cached response, no duplicate)
Loading

18.6 Webhook Secret Rotation

stateDiagram-v2
    [*] --> Active_v1: Initial setup
    Active_v1 --> Rotation: Merchant initiates
    Rotation --> Dual_Secret: Generate new secret
    Dual_Secret --> Active_v2: Remove old secret<br/>(after 24h)
    Active_v2 --> Rotation: Next rotation
    Active_v2 --> [*]: Merchant disabled

    note right of Active_v1
        Only secret_v1 active
        All webhooks use secret_v1
    end note

    note right of Dual_Secret
        Both secret_v1 and secret_v2 active
        Verify with either secret
        Grace period for updates
    end note

    note right of Active_v2
        Only secret_v2 active
        All webhooks use secret_v2
        secret_v1 removed
    end note
Loading

18.7 System Architecture

graph TB
    subgraph "Client Layer"
        Web[Web App]
        Mobile[Mobile App]
        Desktop[Desktop App]
    end

    subgraph "CDN Layer"
        CDN[Static Assets & CDN]
    end

    subgraph "API Gateway"
        Gateway[API Gateway<br/>Load Balancer]
    end

    subgraph "Application Layer"
        API1[API Server 1]
        API2[API Server 2]
        API3[API Server N]
    end

    subgraph "Data Layer"
        Redis[(Redis Cache)]
        DB[(Primary Database<br/>PostgreSQL)]
        Replica[(Read Replica)]
    end

    subgraph "Message Queue"
        Queue[Message Queue<br/>RabbitMQ/SQS]
    end

    subgraph "External Services"
        Stripe[Stripe Gateway]
        SendGrid[Email Service]
        S3[File Storage<br/>AWS S3]
        ES[Elasticsearch]
    end

    subgraph "Monitoring"
        Monitor[Monitoring<br/>Datadog/Sentry]
    end

    Web -->|HTTPS| CDN
    Mobile -->|HTTPS| Gateway
    Desktop -->|HTTPS| Gateway

    CDN -->|Static Assets| Web

    Gateway -->|Load Balance| API1
    Gateway -->|Load Balance| API2
    Gateway -->|Load Balance| API3

    API1 -->|Read/Write| DB
    API2 -->|Read/Write| DB
    API3 -->|Read/Write| DB

    API1 -->|Read| Replica
    API2 -->|Read| Replica
    API3 -->|Read| Replica

    API1 -->|Cache| Redis
    API2 -->|Cache| Redis
    API3 -->|Cache| Redis

    API1 -->|Async Tasks| Queue
    API2 -->|Async Tasks| Queue
    API3 -->|Async Tasks| Queue

    API1 -->|Search| ES
    API2 -->|Search| ES
    API3 -->|Search| ES

    API1 -->|Payment API| Stripe
    API2 -->|Payment API| Stripe
    API3 -->|Payment API| Stripe

    API1 -->|Send Email| SendGrid
    API2 -->|Send Email| SendGrid
    API3 -->|Send Email| SendGrid

    API1 -->|Upload/Download| S3
    API2 -->|Upload/Download| S3
    API3 -->|Upload/Download| S3

    API1 -->|Logs/Metrics| Monitor
    API2 -->|Logs/Metrics| Monitor
    API3 -->|Logs/Metrics| Monitor

    Queue -->|Process| API1
    Queue -->|Process| API2
    Queue -->|Process| API3
Loading

Appendix A: Glossary

Term Definition
API Application Programming Interface
JWT JSON Web Token - for authentication
MFA Multi-Factor Authentication
RBAC Role-Based Access Control
RLS Row-Level Security
PCI-DSS Payment Card Industry Data Security Standard
GDPR General Data Protection Regulation
WCAG Web Content Accessibility Guidelines
TLS Transport Layer Security - for encrypted connections
CDN Content Delivery Network
SSO Single Sign-On
TOTP Time-based One-Time Password (for MFA)
PAN Primary Account Number (card number)
WAL Write-Ahead Log (database transaction log)
APM Application Performance Monitoring
E2E End-to-End (testing)
PITR Point-In-Time Recovery

Appendix B: Change Log

Version Date Changes
1.1 2024-04-10 Critical Technical Gaps Addressed
- Added Section 7: Critical Technical Patterns
- Idempotency Strategy with client/server responsibilities, TTL, and lifecycle
- Transaction State Machine with transitions diagram and validation rules
- Financial Precision: Mandated string types for amounts, decimal.js for calculations
- Multi-Tenancy Strategy: Shared Schema with Merchant Partitioning
- Webhook Security: Rolling Secrets strategy for seamless rotation
- Updated Section 10 (Data Model): Changed amount fields from number to string
- Added settled_at timestamp to Transaction entity
- Added is_partial field to Refund entity
- Added Section 18: Visual Diagrams with Mermaid diagrams
- Payment Life Cycle
- Transaction State Transitions
- Offline Sync Logic
- Multi-Tenancy Data Isolation
- Idempotency Key Lifecycle
- Webhook Secret Rotation
- System Architecture
- Enhanced UC-TXN-005.1: Refund History sub-view with partial refund support
- Updated all monetary amounts in API contracts to use string representation
- Added reconciliation grace period with settled_at timestamp
- Added detailed validation rules for transaction state transitions
1.0 2024-04-10 Initial version - comprehensive PRD with feature prioritization, third-party integrations, scalability, accessibility, edge cases, and expanded use cases

End of Document

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment