A pickup-first commerce platform engineered around a shadow inventory ledger, idempotent payments, and POS-resilient order injection.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Customer │ │ Merchant │ │ Admin │
│ Mobile App │ │ Dashboard │ │ Console │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└────────┬────────┴─────────┬───────┘
▼ ▼
┌───────────────┐ ┌─────────────┐
│ API Gateway │◄──┤ Auth + RBAC │
└───────┬───────┘ └─────────────┘
│
┌────────────┼──────────────┬─────────────┐
▼ ▼ ▼ ▼
┌──────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐
│Orders│ │ Inventory│ │ Payments │ │ POS Sync │
│ Svc │ │ Ledger │ │ (Stripe) │ │ Worker │
└──┬───┘ └────┬─────┘ └─────┬──────┘ └────┬─────┘
│ │ │ │
└──────┬────┴──────────────┴─────────────┘
▼
┌────────────┐
│ PostgreSQL │ + Event Bus (webhooks, retries)
└────────────┘PLACED ──▶ AUTHORIZED ──▶ ACCEPTED
│ │ │
│ ▼ ▼
│ PAY_FAILED PREPARING
│ │ │
▼ ▼ ▼
CANCELLED REFUNDED READY
│
▼
COMPLETEDEvery stock movement is an append-only event. Available = base − reserved − committed + restored.
checkout() → RESERVE(qty, ttl=15min) accept() → COMMIT(qty) # decrements available cancel() → CANCEL(qty) # restores refund() → REFUND(qty) # restores ttl_expire → CANCEL(qty) # auto-restore manual → ADJUST(+/-qty, reason)
CREATED ─▶ AUTHORIZED ─▶ CAPTURED ─▶ SETTLED
│ │
▼ ▼
VOIDED REFUNDED ─▶ PARTIAL_REFUND
│ │
▼ ▼
FAILED DISPUTEDORDER ─▶ POS_INJECT (attempt 1)
│
├─▶ 2xx → MARK_INJECTED
│
└─▶ fail → retry w/ jitter (3x)
│
└─▶ FALLBACK: route to merchant tablet
+ alert ops + auditUser ──┬──< Order >── Store ──< Product >── Modifier
│ │
└──< Notification └──< StockEvent
Order ──< Payment ──< Refund
Order ──< AuditLog