Design checkout, payment and shipping

Stock, locations and availability

Locations, on-hand and reserved quantities, reorder points, and the two settings that decide what happens when the shelf is empty.

"Is it in stock?" is the question B2B buyers ask most, and the one they trust least. Getting it right is less about the number than about what the number means: available is not the same as on hand, and both are different from what your ERP thinks.

Before you begin. Decide first whether this platform keeps your stock or merely displays it. If your ERP is the authority (the normal case for a Mittelstand wholesaler), the availability answer can be handed over to a live ERP call, and what you set up here is the fallback and the reservation logic. See Deciding your system of record.

The model

ThingWhat it is
LocationA place stock sits: warehouse, store, dropship or virtual. Carries a code, a priority and an address
Stock levelOne row per (location, article): on_hand, reserved and a reorder_point
ReservationA hold on stock for one order, with a status and an expiry
MovementA booking row. Every change to stock is one

And the number that matters:

available = on_hand − reserved

available is not stored. It is computed, every time, from the other two. That is the number a buyer should see. on_hand includes goods already promised to someone else.

on_hand and reserved are not fields you edit. They are the running total of the movement ledger. Correcting stock means booking an adjustment with a reason, not typing a new number over the old one. A stock figure you can overwrite is a stock figure nobody can explain a week later.

Locations and priority

Most Mittelstand companies start with one warehouse and should. Create more when they are separate stock: a second site, a trade counter, a supplier who drop-ships.

priority decides which location serves an order first: lowest first. The virtual type is for stock that is not yours to count, such as a supplier's availability you display but do not hold.

To create one: Order Management › Stock › Locations, then New location. Give it a code (main, hamburg, dropship-hansgrohe), a name, a type and a priority.

Reorder points

reorder_point is the level at which a row starts alerting. A row alerts when available has fallen to or below its own reorder point, or a tenant-wide default when it carries none. A point of 0 never alerts.

Set explicit points on your A-articles (the ones a stockout costs you) and leave the long tail on the default. Reorder points are surfaced as a sortable column on the stock list.

The three decisions that matter

These are settings rather than data, and they change behaviour across every order.

Which location serves an order.

StrategyBehaviour
priorityEnabled locations by priority, lowest first. Each item takes the first that fits
nearestRe-ranks against the delivery address: the named location first, then anything in the same country. Stops a German order pulling from a foreign warehouse because it sorts first
single_locationOne location must cover the whole order, or the reservation is refused

single_location is the right answer when splitting an order costs you a second freight. That is a commercial decision, and an allocator should not make it silently.

What happens when nothing can cover the line.

PolicyBehaviour
denyThe reservation is refused. The default
allowReserve anyway; the shortfall shows as negative available and is recorded on the reservation
allow_per_skuBackorder only articles explicitly flagged for it

allow_per_sku is the setting that matches how wholesalers work: catalogue articles you can always get from the manufacturer are backorderable, your own stock items are not.

How long a hold lasts. A reservation can carry its own expires_at, and a tenant-wide lifetime covers the ones that do not. A sweeper releases anything past its deadline and books the stock back. Without a lifetime, an abandoned checkout holds stock until a human notices. That is the single most common cause of "we have it but the shop says no".

Two more worth setting

  • Reason required on bookings. None, adjustments only, or all. Adjustments only is the sensible default: an inbound delivery explains itself, a stocktake correction does not.
  • Restock on return. Whether returned goods rejoin sellable stock by default. Turn it off if returns go to a quarantine bench first; the decision is then recorded per return instead.

Set it up

  1. Go to Order Management › Stock › Locations and create your locations, lowest priority for the one that should serve first.
  2. Load your stock. Use Receive goods on Order Management › Stock › Stock levels for goods that arrive; use Adjust stock with a reason for corrections.
  3. Set reorder_point on the articles worth alerting on.
  4. Set the allocation strategy, the backorder policy and the reservation lifetime for your market.
  5. Decide whether checkout reserves stock. See Checkout configuration.

What to check

  • Open a stock row and confirm available equals on_hand − reserved.
  • Place a test order for an article with a reservation-on-checkout setting, and confirm a reservation appears under Order Management › Stock › Reservations with the order reference on it.
  • Abandon a checkout and confirm the hold is released after the lifetime you set. Release expired runs the sweep on demand.
  • Order more than you have and confirm the backorder policy does what you expect.

If the shop shows an article as unavailable that you know is on the shelf, work through Why a product is not showing up first. Stock is only one of six causes.

Next