Outgoing Events
When using the events approach, there are two mechanisms for receiving notifications about customer order status changes (e.g., an order being picked up in store).
Customer Order Events (WebHook)
When using the events approach, the service also emits dedicated customer order events when an order is updated -- for instance, when a customer order is picked up in store.
Key characteristics:
- Same schema as the PUT request -- the event payload matches the schema used for incoming events, simplifying the mapping for external systems. The one addition is
substituteOfLineItemIdon a fulfillment line, which marks a line the store added as a substitute. The PUT request has no such field: if you send it back, it is ignored rather than rejected, and the marker stays on the line. - Delivered via WebHook -- events are emitted to a WebHook topic using the Hii Retail ExternalEvents framework, allowing for straightforward integration with external systems.
- Focused notifications -- unlike PosLogs, these events are specific to customer order updates, eliminating the need for filtering.
Using the dedicated customer order events can reduce the processing load compared to subscribing to the full PosLog stream, and provides a more streamlined integration for systems that only need customer order status updates.
🛑 What is published, and what is not
The rule is about where the change came from, not what changed:
| The change came from | Published to you? |
|---|---|
| An order created through Unified Basket Manager — at a till, or from a webshop | yes — including the order number we assigned, which is how you learn the order exists |
| Something that happened in a store — picked, ready, handed over, fulfilled | yes |
Your own update, sent to customer-order:sync | no |
Your own writes are not replayed at you. If you send an update and change nothing else, no event follows. Two consequences, and both directions catch people:
- Do not wait for an event to confirm your update was applied. It is not coming. The response to your request is the confirmation.
- Do not read silence as rejection. No event means nothing happened here that you did not already know.
⚠ The exception is worth being precise about: an order created through the basket is published, even though you did not create it. That is not an echo — it is news. It is how an OMS learns that a colleague sold something at a till, and it carries the order number that everything afterwards is keyed on.
This is also why the stream is safe to consume in a loop: you send an update, we do not send it back, and there is no cycle to break.
🛑 An update can carry lines you never sent
Do not assume an order's lines are fixed once it has been created. When a store picks with Click & Collect and replaces an item with a substitute, the substitute arrives as a new line, and the original line's quantity drops by the same amount. This applies to orders you sent to customer-order:sync too, because the change came from the store. Create the new line on your side rather than rejecting the update, and include it in every later sync, because a sync that leaves it out deletes it. See Substitutions add order lines for the exact shape.
🛑 Keep the newest version of the order
Every event carries the whole order: every line, every fulfillment and every tender as they stand after the change. An order with several fulfillments, for example socks picked in a store and a mug shipped from a warehouse, produces an event each time any of them changes. Each event replaces the one before. Two events for the same order are not duplicates and not halves of it: the newer one is the order.
Events can arrive out of order. Delivery is at-least-once, and a redelivery or a replay can bring an older version after a newer one. So compare the Order-Timestamp attribute, the time the order last changed, with the one you stored for the order:
- newer: apply it, and store its
Order-Timestamp; - older or equal: ignore it. Equal is the same version again.
That rule is safe because every change to an order gets a later Order-Timestamp than the change before it. The
value is the commit time of the change, and changes to one order are committed one after another, never at the same
instant. Two different versions of an order never share a value, so an equal value can only be a repeat.
Webhooks receive the attribute as meta.orderTimestamp. The value is RFC 3339 in UTC with six fractional digits, for example 2026-10-13T11:05:10.481902Z, so comparing the strings compares the times.
⚠ Do not use status.changedDateTime for this. It moves only when that status changes, and most updates leave it as it was: one fulfillment picked or shipped, a substitute added, a payment. And do not use the time the event reached you.
PosLog Subscription
The PosLog subscription is available regardless of whether you use the proxy or events approach. PosLogs are emitted for various POS activities including login, regular sales, refunds, and customer order pickups. To detect customer order events, the external system must filter the PosLog stream to identify the relevant entries.
PosLogs are delivered via WebHook through the Hii Retail ExternalEvents framework, the same delivery mechanism used for the dedicated customer order events described below.
This option remains available when using the events approach, so existing integrations that rely on PosLogs continue to work.
Choosing Between PosLog and Customer Order Events
The external system should subscribe to one event type per order -- either PosLog or Customer Order events, not both. Using both for the same order can lead to processing redundant or conflicting information. Choose the event type that best fits your integration needs:
| PosLog | Customer Order Events | |
|---|---|---|
| Scope | All POS operations (requires filtering) | Customer order updates only |
| Schema | PosLog format | Same schema as the PUT request |
| New orders created by POS | Not visible until paid or fulfilled | Emitted for all updates, including new orders |
If using PosLog events, new customer orders created directly at the POS will not be visible to the external OMS until the order is paid or picked up by the customer. This is because PosLogs are only emitted for fulfilled or paid orders. To receive events for new orders as well, use the Customer Order events.
Customer Order events are designed for external OMS systems that need easy access to customer order state updates. Other systems such as accounting or financial systems should use PosLog data, which contains the financial information needed for those purposes.