Skip to main content

Store Updates

This document describes what the store can update on customer orders when using the events approach.

Which Orders Can the Store Update?​

The store can only update orders that meet both of the following conditions:

  1. The order has been submitted to the Customer Order service.
  2. The order has a fulfillment assigned to the store for picking or pickup.

The store cannot update orders that are:

  • Handled by the warehouse for home delivery.
  • Assigned to be picked up by another store.

What Can the Store Update?​

The store updates fulfillments and tenders. It cannot change customer information, and it never removes a line.

🛑 The store can add lines. When a picker replaces an item with a substitute, the substitute becomes a new line on the order. See Substitutions add order lines. An order is therefore not fixed once it has been created: the lines you receive in an update can differ from the lines you sent.

Fulfillment Item Status​

The status of individual items within a fulfillment, e.g., marking a specific item as ready for pickup or as picked up by the customer.

Fulfillment Status​

The overall fulfillment status:

  • Ready for pickup -- only applicable when using the Hii Retail Click & Collect picking module.
  • Fulfilled -- set when the customer picks up the order. Every line of the fulfillment that is still open becomes fulfilled with it.

The order follows its fulfillments: it becomes FULFILLED only once none of its fulfillments is still open and at least one was fulfilled. Until then its status is left as it is, so an order with one fulfillment collected and another still on its way is not yet fulfilled.

Tenders​

Payment information associated with the order, such as payment amount and payment method.

Substitutions add order lines​

Stores that pick with the Hii Retail Click & Collect module can replace an item the shelf cannot supply with a different one. See Click & Collect substitutions. When the picked order reaches Customer Order, each substitute becomes a line of its own, on the order and on the fulfillment it was picked for.

The original lineEach substitute line
Order line (items[])quantity drops by the substituted quantity; cancelledQuantity holds it; extendedAmount drops in proportiona new line, quantity = the substituted quantity, priced as described in What a substitute costs
Fulfillment line (lineItems[])unchanged: the ordered and picked quantities stay as they werea new line with orderedQuantity 0, quantity = the picked quantity, and substituteOfLineItemId = the original's lineItemId

Ordering 2 grey packs of socks when the shelf has one, and taking a black pack instead, gives: the grey line with quantity 1 and cancelledQuantity 1, and a new black line with quantity 1 whose fulfillment line points back to the grey one.

A substitute becomes a line of its own. Anna ordered socks grey ×2, and the shelf had one. The picker took one black pack instead. On the order, the grey line drops to quantity 1 with cancelledQuantity 1 and a new black line has quantity 1. On the fulfillment, the grey line keeps orderedQuantity 2 and quantity 1 picked, and the black line has orderedQuantity 0, quantity 1 and substituteOfLineItemId pointing at the grey line.

substituteOfLineItemId is how you recognise a substitute. It is set only on substitute lines, and it stays on the line for the life of the order. Do not rely on orderedQuantity 0 for this. It holds only until you send the line back in a sync, which sets orderedQuantity to the quantity you send. The line's lineItemId is sub-<sha256 hex of fulfillmentId:parentLineItemId:itemId> (68 characters total). The itemIdentifier field in the C&C event is a GTIN field and is not used for id derivation. The same substitution always produces the same id, so an update that repeats it does not add a second line.

What an integration has to handle:

  • An update can contain lines you never sent. Create them on your side, and include them in every later sync. A sync replaces the order's lines: a substitute line you leave out is deleted, and the original line's quantity and cancelledQuantity become whatever you send. Do not reject or drop the update, and do not assume an order's lines are fixed after it has been created.
  • The original line shrinks, it does not disappear. Read cancelledQuantity together with the new line: the customer still receives something for those units.
  • This happens however the order was created. An order you sent to customer-order:sync, or one created through Unified Basket Manager, gets substitute lines the same way, because the change comes from the store. See what is published, and what is not.

What a substitute costs​

🛑 A substitution never makes the order more expensive. The customer pays the substitute's own price when it is cheaper than the item they ordered, and the ordered item's price when it is dearer. A discount the customer had on the ordered item carries over to the substitute.

A substitution never makes the order dearer. The grey socks cost 90.00 with 10.00 off, so Anna pays 80.00 a pack. A black pack at 95.00 gets the same share off, 10.00, plus a SUBSTITUTION_PRICE_CAP of 5.00, so she still pays 80.00. A black pack at 81.00 gets the same share off, 9.00, and she pays 72.00.

Each substitute line is priced from two things: the substitute's sales price as reported by the C&C event, and the original line it replaces.

Field on the substitute lineValue
unitPricethe unitPrice from the C&C substitution event, falling back to the original line's unitPrice if the C&C event does not carry one
unitDiscounts[]the original line's discounts, carried over as the same share of the price, with the same discountId and discountText. Plus one discount with discountId SUBSTITUTION_PRICE_CAP, discountText "Substitution price cap", and rewardType PRICE_REDUCTION when the substitute costs more than the ordered item: it brings the price down to the ordered item's price
extendedAmountthe line total: quantity × (unitPrice − the per-unit discounts), rounded to the currency
taxableGroupIdthe substitute's own tax group, which can differ from the ordered item's

Worked examples, per unit:

OrderedSubstituteThe substitute line
1 × 50, 10% off (pays 45)1 × 40unitPrice 40, discount 4 (the same 10%), extendedAmount 36
1 × 50, 10% off (pays 45)1 × 60unitPrice 60, discount 5 (10% of 50), SUBSTITUTION_PRICE_CAP 10, extendedAmount 45
3 × 30 on 3-for-2 (pays 60)1 of the 3 replaced by an item at 24unitPrice 24, discount 8 (the same third off), extendedAmount 16. The original line keeps 2 units at 20, extendedAmount 40. Total 56
1 × 40, no discount2 × 22 (two small packs for one large)unitPrice 22, SUBSTITUTION_PRICE_CAP 2 per unit, extendedAmount 40

The cap is per original line, not per unit. The total cost of all substitutes for one ordered line is capped at the original line's net extended amount scaled by the number of replaced units (Rule 5). All the substitutes for one ordered line together never cost more than the units they replace, which is what the last example shows.

The original line's total goes down with its quantity. Its extendedAmount is scaled to the units it still holds, so the order total is the sum of the line totals as usual. For every line, quantity × (unitPrice − per-unit discounts) equals extendedAmount, within rounding.

What an integration should do: take the substitute's price from extendedAmount and unitDiscounts, exactly as for any other line. Do not re-price it from your own catalogue, and do not treat SUBSTITUTION_PRICE_CAP as a promotion to report. It is the store keeping its promise not to charge more than the customer agreed to.

When a substitute is removed or swapped​

On every PICKED or READY_FOR_DELIVERY event, the substitutes it carries for a fulfillment are all the substitutes that fulfillment has (Rule 9). Any substitute line in that fulfillment that is not present in the event's substitution list is cancelled: its fulfillment line status is set to CANCELLED, and its order line is zeroed — quantity 0, cancelledQuantity = its former quantity, extendedAmount 0. The original line's quantity and total are restored to match the substitutes that remain.

The latest pick holds the full set of substitutes. Payment failed, so picking started again, and the picker swapped the black pack for a navy one. The black line is cancelled, with quantity 0, cancelledQuantity 1, extendedAmount 0 and its fulfillment line CANCELLED. The navy pack arrives as a new line. The grey line stays at quantity 1 with 1 cancelled.

Once an order is marked picked, the store cannot change it. The exception is when payment fails: picking then starts again, and the picker can change the substitutes before marking the order picked once more.