Guide chapters
Shipping and fulfilment
The problem#
In a store, shipping is one decision per order. In a marketplace it is a decision per group of items, because parcels leave from different places, at different times, at different people expense.
The difficulty is not calculating a price. It is that the shipping cost later feeds into settlement, and you have to know who bore it: the buyer, the seller, or the platform funding free delivery.
Minimum version#
- A shipping method belongs to the seller, not to the platform.
- The cost is calculated and recorded on that seller group of items.
- Fulfilment state lives at group level, not on the whole order.
- The tracking number is data on the order, entered by hand.
What not to build yet#
- Label generation and carrier integrations.
- A rules engine pricing by weight, dimensions and zone.
- Automatic splitting of a group into several parcels.
- Tracking parcel status on the platform side, until somebody asks for it.
Plan ahead#
Who bears the cost, recorded on the order#
Free delivery above a threshold looks like a promotion and is a financial decision: somebody pays for that shipment. If the order does not record whether the cost falls on the seller or the platform, settlement can only be done from memory.
Fulfilment state as group state#
An order with two sellers is shipped and not shipped at the same time. The only way to express that is to keep the state where fulfilment actually happens and derive the order state from it.
The dispatch location apart from the seller#
Today a seller ships from one place. Tying shipping to a location rather than directly to the seller costs the same and clears the way for a second warehouse or dispatch from a pickup point.
Triggers#
- a buyer asks why they received two parcels and paid delivery twice;
- a seller asks for free delivery above an amount;
- the first "where is my parcel" complaint;
- a seller ships from a second location;
- the number of parcels makes typing tracking numbers in by hand a chore.
Next stage#
After the second trigger: free delivery thresholds with an explicit record of who funds them. After the third: a link to the carrier tracking page, without pulling statuses yourself. After the fifth: only then a carrier integration, and preferably with one carrier, the one most used.
Common mistakes#
| Assumption | Why it costs |
|---|---|
| "Shipping is priced per order." | The cost cannot be split or settled with sellers. |
| "Free delivery is just a promotion." | With no record of who bore the cost, settlement breaks. |
| "An order has one fulfilment state." | Partial shipment has no representation. |
| "The tracking number can go in a note." | It cannot be shown to the buyer or found during a complaint. |
| "We will integrate a carrier straight away." | An external dependency at a volume a form handles fine. |
What works in practice#
The harder part was never shipping itself but its role in settlement. The delivery cost has to be broken out when a payout is calculated, and that requires knowing whose side it falls on. Without that information on the order, it has to be reconstructed each time from the promotion terms in force at the moment of purchase.
The second observation is how long a simple model holds: method, cost and tracking number on the seller group of items. Moving towards carrier integrations earns its keep once the number of parcels starts producing repeat errors, not when the process starts feeling dull.
Checklist#
- The shipping method and cost belong to the seller group of items.
- The order records who bears the delivery cost.
- Fulfilment state lives on the group, order state is derived.
- The tracking number is its own field, not a note.
- Shipping is tied to a dispatch location rather than directly to the seller.
I design multi-vendor platforms with onboarding, payments, moderation, and operational workflows.
Explore marketplace development