Merit · E-Commerce Solution · Product explainer
Every order in the E-Commerce Solution moves through one service. This page shows what it owns, the states an order can be in, how items and sellers move it, and every feature with the rules to test it by.
It is an order state service, not a full order management system.
Core hands over the confirmed basket, and from that moment only OMS moves the state. It does not reserve stock, pick a carrier, process a payment or hold product data. Those belong to Core, the Fulfillment Service, Payment and PIM. The service map shows every seam.
Read off the code, because that is what runs.
Twelve order states, as the code defines them. Any other move is rejected with INVALID_ORDER_STATUS_TRANSITION. The table below lists every allowed move.
| From | Allowed next states |
|---|---|
| DRAFT | AWAITING_PAYMENT, CANCELLED, EXPIRED |
| AWAITING_PAYMENT | PAYMENT_COMPLETED, FAILED, CANCELLED, EXPIRED |
| PAYMENT_COMPLETED | PROCESSING, CANCELLED, REFUNDED |
| PROCESSING | CONFIRMED, PARTIALLY_FULFILLED, FULFILLED, FAILED, CANCELLED |
| CONFIRMED | SHIPPED, PARTIALLY_FULFILLED, CANCELLED |
| SHIPPED | FULFILLED |
| PARTIALLY_FULFILLED | FULFILLED, REFUNDED, PROCESSING (gift cards only) |
| FULFILLED | REFUNDED |
| FAILED | DRAFT, PROCESSING (gift cards only) |
| CANCELLED, REFUNDED, EXPIRED | none, terminal |
Items move first, and the order follows them.
| When the items are | The order becomes |
|---|---|
| Any item PROCESSING | PROCESSING |
| Every item CONFIRMED, SHIPPED, FULFILLED, REFUNDED, FAILED or CANCELLED | the same status |
| Settled items that disagree, such as FULFILLED and FAILED together | PARTIALLY_FULFILLED |
| Items still pending or in progress in a mix | no change yet, wait for more updates |
| Seller Portal status | OMS item status |
|---|---|
| IN_PROCESS | PROCESSING |
| CONFIRMED | CONFIRMED |
| READY_TO_SHIP | CONFIRMED, with carrier sub-status READY_TO_SHIP |
| SHIPPED | SHIPPED |
| DELIVERED | FULFILLED |
| CANCELED | CANCELLED |
| SHIPPED_TO_MERIT, RETURN states | CONFIRMED, with the matching carrier sub-status |
Cancelling and refunding are two separate things.
Two ways in, one refund path. For Al Fursan, client staff cannot cancel: cancelling is a Merit Ops action, and the client keeps the order report.
The PRDs were written before the build. Each row needs one answer: update the PRD, or change the code.
| Topic | The PRD says | The code does |
|---|---|---|
| Order states | Seven: DRAFT, PENDING, CONFIRMED, FULFILLED, CANCELLED, FAILED, REFUNDED | Twelve. PENDING is split into AWAITING_PAYMENT and PAYMENT_COMPLETED, and PROCESSING, SHIPPED, PARTIALLY_FULFILLED and EXPIRED are added |
| Unpaid orders | Cancelled after 30 minutes, reason SYSTEM_PAYMENT_TIMEOUT | Expired after 15 minutes, to EXPIRED, not CANCELLED |
| SLA breach | A CONFIRMED order past its SLA is escalated to a LiveOps queue | Not found in the code |
| Partial fulfilment | No order-level state for it | PARTIALLY_FULFILLED exists at order level |
| Refund states | REQUESTED, VALIDATED, REJECTED, ESCALATED, SUBMITTED, COMPLETED, FAILED | PENDING, APPROVED, PROCESSING, COMPLETED, REJECTED, CANCELLED |
| Refund amount | Full amount only in Phase 1 | Any amount from 0.01 is accepted |
| Bulk gift card orders | One parent order, batched into calls of five | The five-item limit exists. The parent order does not |
| Event names | order.created, order.confirmed and so on | ORDER_CREATED and eight more, including ORDER_PARTIALLY_FULFILLED and ORDER_EXPIRED |
Every feature and the services it crosses. A story is split per service by engineering, not by product.
| Feature | E-commerce Core | OMS | Payment | Fulfillment Service | Seller Portal | Settlement | Storefront Admin Portal | Communication Hub |
|---|---|---|---|---|---|---|---|---|
| 1. Create an order | ● | ● | ● | |||||
| 2. Status from payment | ● | ● | ||||||
| 3. Unpaid orders expire | ● | ● | ||||||
| 4. Fulfilment and status roll-up | ● | ● | ||||||
| 5. Seller Portal orders | ● | ● | ||||||
| 6. Gift card fulfilment and reprocess | ● | ● | ||||||
| 7. Cancellation | ● | ● | ● | ● | ||||
| 8. Refunds | ● | ● | ||||||
| 9. Cooling-off delay | ● | ● | ||||||
| 10. Status history | ● | |||||||
| 11. Order events | ● | ● | ● | |||||
| 12. Seller order reference | ● | ● | ||||||
| 13. Bulk gift card orders | ● | ● | ||||||
| 14. Settlement trigger | ● | ● | ||||||
| 15. Cashback release | ● | ● |
Who each one serves, what it does, the rules to test it by, and its spec. OPEN marks a question not yet decided.
As a member, I pay once and get exactly one order, even if my app retries.
Core creates the order from the confirmed basket. The order carries its items, the customer, the tenant and the payment legs.
As a member paying with points and card, my order confirms only when both legs are paid.
Each payment leg is tracked on its own. The order status follows the legs.
As a member who abandons checkout, my reserved basket does not stay open forever.
A job finds DRAFT and AWAITING_PAYMENT orders past their expiry time and moves them to EXPIRED.
As a member with a phone and a gift card in one order, I see each item move on its own.
OMS asks the Fulfillment Service to fulfil each line, and each item carries its own status. The order status is derived from its items, per the roll-up table in section 03.
As a seller, what I do in the portal shows up as the order status everywhere else.
Merchandise orders enter OMS through an internal path, with no customer id and no payment legs. Seller actions come back as webhooks and map to OMS statuses, per the table in section 03.
As Merit Ops, when one gift card in an order fails, I retry that one without touching the rest.
Gift cards are issued through the legacy gift card engine. A failed or partly fulfilled item can be reprocessed.
As a seller who cannot fulfil, I cancel before shipping and the member is refunded.
An order or item is cancelled with a reason and a trigger: customer, system or admin.
As customer care, I refund an order or one item, and the record shows who asked and why.
A refund belongs to an order or to one item. A failed fulfilment that runs out of retries opens a refund request by itself. A person still approves it.
As the fraud team, a risky gift card order waits a few hours before it is fulfilled.
Admin rules hold an order before fulfilment. They match on product type, minimum price, category or collection. When several match, the longest wait wins.
As Merit Ops, I can see every status an order went through, when, and who moved it.
Every change writes a row to the order status history.
As a downstream service, I subscribe to the order events I need instead of polling.
OMS sends nine events to registered webhook endpoints.
As a seller packing boxes, I read a short reference, not a long system id.
A short reference sits next to the system order id and is printed on the pick and pack label.
As a client ordering 3,000 gift cards, I place one order and track one status.
Large gift card orders are split into calls of five behind one order the client sees.
As Finance, money moves only when an order is final.
Settlement is its own service. It runs once fulfilment completes or breakage happens, turns the hold into a charge, and records the revenue line.
As an Al Fursan member, my Miles cashback lands after delivery, not at payment.
Earned cashback is released by order state, anchored on delivery.
The order words, used the same way every time.