Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Spring Boot REST API Development

Spring Boot Basics

  • What is Spring Boot?
  • Dependency Injection
  • Building REST Controllers

Validation & Error Handling

  • Bean Validation with @Valid
  • Global Exception Handling

Spring Framework Internals

  • IoC Container Fundamentals
  • Bean Lifecycle In Detail
  • Component Scanning & Configuration
  • Auto-Configuration Mechanism
  • Spring AOP
  • @Transactional Deep Dive

Microservices Architecture

  • Monolith to Microservices Decomposition
  • API Gateway
  • Service Discovery
  • Inter-Service Communication Choices
  • Event-Driven Architecture Patterns
  • Messaging Technology Choices

Resilience Patterns

  • Configuration Management
  • Circuit Breaker Pattern
  • Retry & Backoff Strategies
  • Bulkhead & Rate Limiting
  • Timeout Strategy
  • Why Microservices Fail

Distributed Data & Consistency Patterns

  • Two-Phase Commit
  • Saga Pattern
  • Outbox Pattern
  • Eventual Consistency Design
  • CQRS Basics
  • CAP Theorem

Observability & Operations

  • Centralized Logging
  • Distributed Tracing
  • Metrics & Monitoring
  • Alerting Strategy
  • Health Checks

Payment Systems

  • Payment — Requirements
  • Payment — Core Flow
  • Payment — Idempotency Implementation
  • Payment — Failure Handling & Reconciliation
  • Payment — Security

Order Management System

  • OMS — Requirements
  • OMS — State Machine Design
Chaturmind
← Spring Boot REST API Development

Spring Boot Basics

  • What is Spring Boot?
  • Dependency Injection
  • Building REST Controllers

Validation & Error Handling

  • Bean Validation with @Valid
  • Global Exception Handling

Spring Framework Internals

  • IoC Container Fundamentals
  • Bean Lifecycle In Detail
  • Component Scanning & Configuration
  • Auto-Configuration Mechanism
  • Spring AOP
  • @Transactional Deep Dive

Microservices Architecture

  • Monolith to Microservices Decomposition
  • API Gateway
  • Service Discovery
  • Inter-Service Communication Choices
  • Event-Driven Architecture Patterns
  • Messaging Technology Choices

Resilience Patterns

  • Configuration Management
  • Circuit Breaker Pattern
  • Retry & Backoff Strategies
  • Bulkhead & Rate Limiting
  • Timeout Strategy
  • Why Microservices Fail

Distributed Data & Consistency Patterns

  • Two-Phase Commit
  • Saga Pattern
  • Outbox Pattern
  • Eventual Consistency Design
  • CQRS Basics
  • CAP Theorem

Observability & Operations

  • Centralized Logging
  • Distributed Tracing
  • Metrics & Monitoring
  • Alerting Strategy
  • Health Checks

Payment Systems

  • Payment — Requirements
  • Payment — Core Flow
  • Payment — Idempotency Implementation
  • Payment — Failure Handling & Reconciliation
  • Payment — Security

Order Management System

  • OMS — Requirements
  • OMS — State Machine Design
HomeLearnSpring BootSpring Boot REST API DevelopmentOrder Management System
✓ FreeIntermediate· 6 min read

OMS — Requirements

The order lifecycle's states, why some transitions must be forbidden outright, the difference between customer-initiated and warehouse-initiated updates, and defining SLA requirements for how fast a state change reaches the customer.

Published September 23, 2026


OMS — Requirements

The order lifecycle's states

CREATED → PAID → SHIPPED → DELIVERED
              ↘ CANCELLED
                     ↘ REFUNDED

A typical order lifecycle moves through: created (the order exists, payment not yet confirmed), paid (payment succeeded — see Payment — Core Flow's authorize/capture state machine, which this state directly depends on), shipped (handed to a carrier), delivered (confirmed received). Cancelled and refunded are exit paths that can branch off at different points, not a single linear "failure" state — cancelling a CREATED order is trivial (nothing has shipped or been charged); cancelling a SHIPPED order means something entirely different (an in-flight return, not a simple cancellation).

Valid vs invalid transitions — and why this needs to be explicit

An order moving from DELIVERED back to CREATED is nonsensical — the state machine needs to explicitly ENUMERATE which transitions are valid and reject everything else, rather than allowing any state field to be set to any value by whichever code path happens to touch it. This is the same discipline as Payment — Core Flow's guarded state transitions ("you cannot capture a payment that was never authorized") — an order's state machine is exactly as consequential to get right, since an invalid transition here means real inventory, shipping, and customer-communication inconsistencies, not just a data-quality issue.

Multi-actor updates: who's allowed to trigger which transition

Customer-initiated:  cancel (only while CREATED or PAID, before shipment)
Warehouse-initiated:  mark as shipped, mark as delivered (via carrier webhook)
Support-initiated:    process a return/refund after delivery

Unlike a single-actor state machine (Payment — Core Flow's flow is driven almost entirely by the payment processor's responses), an order's state is updated by MULTIPLE independent actors — the customer (cancellation), the warehouse/fulfillment system (shipped), the carrier (delivered, via a tracking webhook), and support staff (refunds, returns). Each actor should only be ALLOWED to trigger specific transitions from specific states — a customer shouldn't be able to mark their own order as "delivered," and the warehouse system shouldn't be able to trigger a refund. This access-scoping is a genuine requirement, not an implementation detail to figure out later.

SLA requirements: how fast a state change must reach the customer

Different transitions have different acceptable latency for reaching the customer-visible order status: a payment confirmation probably needs to reflect within seconds (the customer is actively waiting on the checkout page); a "shipped" status update from the warehouse might have an acceptable few-minutes-to-an-hour lag; a carrier's "delivered" webhook processing within a few minutes is usually fine. Stating this explicitly PER TRANSITION (not one blanket "real-time" requirement for everything) is what actually justifies later architecture decisions — Event-Driven Architecture Patterns' choice between event notification and event-carried state transfer, for instance, is partly informed by how urgently a given state change needs to propagate.

Follow-up questions this topic invites — and their answers

Q: Why can't 'cancelled' just be one of the linear states in the main flow? A: Because the CONSEQUENCES of cancelling differ completely depending on when it happens — cancelling before payment is a no-op cleanup; cancelling after shipment requires an actual physical return process — modeling these as one flat 'CANCELLED' state loses this distinction, which is exactly why OMS — State Machine Design treats cancellation-after-shipment as its own explicit transition into a return flow, not a simple revert.

Q: How would you handle an order that needs to be cancelled by support on the customer's behalf? A: This needs its own explicit actor/permission scoping decision — is 'support-initiated cancellation' the same transition as 'customer-initiated cancellation' with different allowed actors, or a genuinely distinct transition with different downstream consequences (e.g., different refund-reason-code tracking)? Stating this explicitly in requirements avoids the ambiguity showing up as an undocumented special case in the implementation later.

Q: Is there a risk in having overly strict transition SLAs? A: Yes — an unrealistically tight SLA (e.g. demanding sub-second propagation for every transition regardless of actual customer need) can force unnecessarily expensive architecture (synchronous calls everywhere instead of appropriate async messaging) for no real customer-facing benefit; SLA requirements should be driven by genuine user expectation per transition type, not a uniform maximum-urgency default.

Q: How does this connect to the read-model considerations in a system like this? A: An order's current status is read FAR more often than it changes (a customer repeatedly checking their order status page) — this read-heavy skew is exactly the kind of signal Back-of-Envelope Estimation's read:write ratio reasoning says should drive caching decisions for the order-status read path, independent of how the underlying state machine itself is implemented.

Previous

Payment — Security

Next

OMS — State Machine Design

AI Tutor

Lesson: OMS — Requirements

Quick actions

AI responses can be inaccurate. Verify critical information.