Incoming Events
The events approach allows external Order Management Systems (OMS) to push customer order data into Hii Retail. Instead of Hii Retail fetching data from the external system on demand (as in Proxy Mode), the external system sends order data to Hii Retail using a PUT endpoint.
Sending Customer Orders
To submit or update a customer order, use the PUT endpoint documented in the API reference:
The request body schema is identical to the response schema used by the GET endpoint in the proxy approach, making it straightforward to adopt events if you are already familiar with the proxy integration.
⚠ A sync replaces the whole order. A line you leave out is deleted, and a fulfillment you leave out is cancelled, so always send the order as it now stands. The one exception is a payment taken at a till: it is kept even when your sync does not carry it, because your system never knew about it.
Whether a line may be substituted
Each line item takes an optional isSubstitutionAllowed. It is the customer's answer to "may the store replace this item if it is out of stock?", and it is passed on to the store that picks the order.
| You send | The store |
|---|---|
true | may offer a substitute |
false | may not offer a substitute for this line |
| nothing | may offer a substitute: not set means allowed |
⚠ Send it on every update, not only the first. A sync replaces the order's lines, so an update that leaves the field out sets it back to not set, which means allowed. A customer's "no" survives only if every update repeats it.
A customer who refuses substitutes for the whole order needs false on every line; there is no order-level switch. When a store does substitute, the substitute arrives back to you as a new line. See Substitutions add order lines.
🛑 Not every update is accepted
An order or a fulfillment that has been fulfilled or cancelled is closed. It is a final state, and a later update against it is refused rather than applied — the goods have already gone, or the order has already been called off, and no message can undo that.
So check the response. A refusal names the order or fulfillment, its current status, and the status you attempted, which is enough to work out what happened without asking us.
The transitions that are allowed:
| From | To |
|---|---|
CREATED | IN_PROGRESS, FULFILLED, CANCELLED |
IN_PROGRESS | FULFILLED, CANCELLED |
FULFILLED | — nothing, it is final |
CANCELLED | — nothing, it is final |
Fulfillments follow the same shape, with READY_FOR_PICKUP in place of IN_PROGRESS.
⚠ Sending the same order again is not a rejected update — it is a sync, and a resend with newer content updates the order normally. Only a transition out of a closed state is refused.
Changing the status of one fulfillment
To report progress on one fulfillment without resending the whole order, for example a warehouse shipment that has gone out, use:
POST /business-units/{businessUnitId}/customer-orders/{customerOrderId}/fulfillments/{fulfillmentId}:setStatus
with the new status, and optionally a status per line in lineItems. The transition is checked against the stored order at once, and a disallowed one is refused with 409 Conflict in the response. Like a sync, it is not echoed back to you on the order updates.
Migration from Proxy
When migrating from the proxy approach to events, the external system must send all existing customer orders to Hii Retail using the PUT endpoint. This ensures that Hii Retail has the complete and up-to-date order data for processing and synchronization with the POS.
Ideally, the migration can reuse the same synchronization logic used for ongoing event updates -- i.e., send all customer orders that have been updated and not yet synced.
Event Processing
Incoming orders are emitted to PubSub for processing. This provides:
- Automatic retries -- if processing fails, the message is automatically retried up to a configured number of times.
- Eventual consistency -- the system guarantees that orders will be processed, even if temporary failures occur.
Ordering Guarantees
The PubSub subscription is ordered, meaning events are processed in the sequence they were received. This ensures that order updates are applied in the correct chronological order.
Error Handling
If the processing of an incoming event fails:
- The service retries the request automatically up to a configured number of times.
- If retries are exhausted, the message is moved to a Dead Letter Queue (DLQ) for further investigation and manual intervention if necessary.
When a DLQ message is retried manually:
- If a newer message for the same customer order has already been processed, the retried DLQ message is ignored to prevent overwriting with outdated information.