Practical guide

How to design an order state system for an e-shop

Stop orders jumping between states in a confusing way. First write the rules down, then put them into the application.

15 minutes · E-commerce

First, the short version

Why is a free text state field not enough?

An order state system says where an order is now and where it may go next. It is not only a list of state names. The rules between them matter.

For example, an order can wait for payment, be paid, shipped, or cancelled. But it should not accidentally go from shipped straight back to waiting for payment.

Get ready

What to clarify first

Do not start with a library or a database table. Start with what really happens to an order.

  • A list of real states. Use language that customer support and the warehouse understand.
  • Who may make a change: a customer, administrator, warehouse worker, or automated payment.
  • What happens after each change, such as reserving stock, sending an email, or handing the order to a carrier.
  • Where you will store both the current state and history. Usually in a database.

Step 1

Design the rules in small steps

The goal is not a long list of exceptions. The goal is a few understandable states and clear transitions between them.

1. List states, not technical details

  1. Start with a simple list such as new, waiting for payment, paid, shipped, and cancelled.
  2. Do not try to cover every exception immediately. Add an unusual case later, when you understand it.
  3. Keep payment and delivery states separate when they change independently. Otherwise, confusing combinations appear quickly.

2. Define allowed transitions

  1. For each state, write where the order may go next. For example, from waiting for payment to paid or cancelled.
  2. Do not allow a change only because you can write it into a field. The application should refuse a step that makes no sense.
  3. Keep the rules in one place, not scattered between a controller, administration, and import.

3. Store the change and its history

  1. For every transition, store the new state, time, and reason. It also helps to know who triggered it.
  2. Perform a follow-up action only after the change is saved successfully. For example, send the shipping email only after the order is marked as shipped.
  3. The history later makes it easy to see why an order reached a particular state.

Step 2

Check the rules on a real order

Walk through the normal path and one mistake. Then you know the rules work outside the diagram too.

  1. Walk through a normal scenario

    Create a test order and move it from new to shipped. At every step, check both the current state and its history.

  2. Try a forbidden jump

    For example, try to mark a new order as shipped immediately. The application should reject the change and clearly explain why.

  3. Check the follow-up action

    Confirm that an email, warehouse action, or other follow-up work reacts only to the right transition. It must not run on every order save.

If something goes wrong

Common problems

The state can be overwritten from anywhere

Do not allow a form or every part of the code to write the change freely. Create one route for a transition that checks the rules.

One state mixes payment, delivery, and returns

Split independent areas. Payment state does not need to equal delivery state. Otherwise, unnecessary combinations quickly multiply.

You do not know who changed the state

Store transition history. Record the old and new state, time, source of the change, and optionally a reason. It saves hours when solving a complaint.

Two changes arrive at the same time

Protect data from concurrent writes. A well-designed database transaction helps ensure that a change is saved completely or not at all.

Done

The order now has a clear path.

Start with a few states and transitions you truly use. Add more rules later from real situations.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.