Picking
This is the part of the flow that is easiest to misread, because the picking does not happen in Store Transfer.
When a transfer is requested, it becomes a picking job in Click and Collect at the sending store. The staff there pick it with the same handset flow they use for a customer's click-and-collect order, and when they finish, the transfer completes and the stock moves.
The loop
receiving store Store Transfer sending store
─────────────── ────────────── ─────────────
raise transfer ───────────────► CREATED
add lines
send request ───────────────► REQUESTED
│
│ store-transfer-requested
▼
Click and Collect ──────────► appears as a picking job
▲ (Order-Type = STORE_TRANSFER)
│ │
│ order-status-changed │ staff pick it
│◄─────────────────────────────┘
│
IN-PROGRESS│ (picking started)
COMPLETED │ (picking finished)
│
│ store-transfer-completed
▼
Stock Transaction Processing ─► stock moves
Goods Received ─► delivery created
What the picker sees
A store transfer arrives in Click and Collect as an order carrying Order-Type = STORE_TRANSFER,
which is what separates it from a customer order in the same picking queue. The transfer's own id is
used as the order id, so the two systems refer to the same thing by the same identifier — there is no
mapping table and no derived key.
Each transfer also carries an order code: a short, human-readable code such as S4K9M2X that
staff can read aloud or type at a counter. Store transfer codes always begin with S; a customer
order's code begins with C. See Events for where the code appears on the wire.
What finishing the pick does
Click and Collect reports the picker's progress back, and Store Transfer reacts to two of those signals and ignores the rest:
| Click and Collect reports | Store Transfer does |
|---|---|
| picking has started | moves the transfer to IN-PROGRESS |
| picking finished | completes the transfer and publishes store-transfer-completed |
| anything else — paused, resumed, cancelled | nothing |
⚠ IN-PROGRESS means "somebody has started", never "N of M lines done". It is set once, when
picking begins. Line-by-line progress is not reported to Store Transfer, and pausing a pick does not
move the transfer back. Quantities arrive only at the end, all at once.
Picked quantities become quantityApproved. The picker is the one who decides what actually
travels — if only four of the six requested units are on the shelf, four is what ships, and four is
what moves stock. The original quantityRequested is kept on the line so both numbers stay visible,
but it is quantityApproved that the rest of Hii Retail acts on.
Completing from your own system
Store staff do not complete transfers over the API. In the supplied setup the sending store's only involvement is the pick, in Click and Collect, and finishing it is what completes the transfer. Nothing in the Store Transfer API is part of a picker's day.
The API path exists for a different case: a customer who replaces the picking app entirely, and decides in their own system — an ERP, a warehouse system — what actually ships. If that is you, you complete the transfer yourself:
POST /business-units/{fromBusinessUnitId}/store-transfers/{storeTransferId}:submit
The effect is identical to a finished pick: the transfer moves to COMPLETED and the same
store-transfer-completed event is published, so everything downstream behaves the same way. The
business unit in the URL must be the transfer's sending store.
⚠ This is an either/or, not a fallback. A transfer being picked in Click and Collect will be
completed by that pick; calling :submit alongside it races the pick and completes the transfer with
whatever quantities happen to be stored at that moment. Choose one route per tenant.
🛑 Set the approved quantities before completing. :submit completes the transfer as it stands;
it carries no quantities of its own. Write the approved quantity onto each line first — as the
sending store, so that the quantity lands in quantityApproved rather than in
quantityRequested:
PUT /business-units/{fromBusinessUnitId}/store-transfers/{storeTransferId}/lines
{ "lineId": "line-1", "itemId": "7350053850019", "quantity": 4 }
A quantity of 0 refuses the line. Skip this step and the transfer completes with whatever is
already on the lines — and because a new line's approved quantity is seeded from the requested one,
that means every line silently ships in full. See
the API.
Ordering and redelivery
The reports coming back from Click and Collect are ordinary Pub/Sub messages, so they can arrive more than once and out of order. Store Transfer guards against both: a status report that would move the transfer backwards is discarded, and a report that arrives without a usable event time is skipped rather than being trusted with a wall-clock guess.
The practical consequence for an integrator: a transfer never regresses. If you see COMPLETED,
a later IN-PROGRESS will not undo it.