Design checkout, payment and shipping

Shipping methods and carriers

Rate matrices, carriers, cut-off times and the delivery promise a buyer sees at checkout.

Shipping in B2B ranges from a parcel of seals to two pallets on a forwarder with a timed slot. One flat rate cannot describe that, and neither can one carrier. This is how the pieces fit.

Before you begin. Know your weight unit, whether your free-shipping threshold is measured net or gross, and which carriers you have contracts with. Standard carriers can be seeded with one action: you do not have to type DHL and DPD in by hand.

Methods, carriers, tiers

Three levels, and they answer different questions.

LevelAnswersScreen
Shipping methodWhat the buyer chooses and what it costsOrder Management › Shipping › Methods
CarrierWho moves it, how long it takes, and where the tracking link pointsOrder Management › Shipping › Carriers
Rate tierThe rows of a price matrixOrder Management › Shipping › Rate matrix

A method names a carrier; the carrier contributes the facts a price cannot hold.

The three pricing models

ModelBehaviourTypical use
fixedOne priceStandard parcel, €4.90
freeNo priceCollection, promotions
matrixA tiered price over a measureEverything else

A matrix prices over one basis: weight, quantity, order value, or any product attribute. The tiers are rows of from_value → price, and the tier with the highest from_value at or below the measured value wins:

FromPrice
0€5.00
10€10.00
20€20.00

A 12 kg shipment pays €10.00. The tiers are open-ended upwards. There is no top row that says "and above this, refuse"; the last row prices everything heavier. If you sell pallets alongside parcels, add a row that prices them properly, or the forwarder shipment goes out at the parcel rate.

The attribute basis is the one worth knowing about. Pricing on a product attribute such as pallet spots, hazardous class or length lets you charge for the thing that drives the cost. It requires that the attribute exists on your products. See Attributes.

On top of the model:

  • free_above: free shipping over an order value. It beats every pricing model. Whether the threshold is measured net or gross is a tenant setting, and the answer at checkout states which basis it used.
  • quote_above: above this value the method stops quoting a price and the freight is agreed by hand. This is Speditionsversand auf Anfrage, and it is the honest answer when a tariff cannot price the shipment.
  • countries: where the method is offered. ANDed with the carrier's own country list: a method is not offered into a country its carrier does not reach.
  • tax_class: which tax class the shipping line is booked on.

What a carrier contributes

A carrier is a row of its own rather than a string on the method, because four facts belong to the carrier and not to the price:

FieldWhy it matters
tracking_url_templateThe tracking link shape, once, instead of copied onto every shipment. {tracking_code}, {postal_code} and {country} are substituted
service_levelOne row is one class of service: DHL Paket and DHL Express are two carriers, the way they are two methods. The set of levels is yours to define
statusactive, paused or retired. Anything but active takes every method using that carrier out of the quote. A lapsed contract is one switch, not six methods disabled one at a time
cutoff_time, handling_days, eta_days_min/maxThe delivery promise

cutoff_time is HH:MM, 24-hour, UTC. Anything else is refused rather than stored. A malformed cut-off that was accepted and then ignored would mean a delivery promise computed without the rule you thought you set.

Mind the UTC. A carrier that collects at 16:00 German time is 15:00 in summer and 14:00 in winter. The platform knows no holiday calendar either, and the delivery window it computes is in calendar days. Treat the estimate as a promise you can keep rather than as a guarantee.

The delivery promise

Cut-off and handling days turn the carrier's transit range into an actual window on every quote: a ship date, an earliest and a latest arrival, and whether the cut-off has already passed today. A method inherits whatever it does not state itself. A carrier that needs longer than the shop-wide default wins, which is right: a pallet is not a parcel.

Set up a method

  1. Go to Order Management › Shipping › Carriers and select Seed standard carriers. Four arrive active: DHL, DPD, GLS and UPS. Seeding never overwrites a row you have edited.
  2. Open your carrier and fill in the facts the catalogue cannot know: your contracted cutoff_time, your handling_days, and the transit range you achieve in practice.
  3. Go to Order Management › Shipping › Methods and select New method. Give it a code and a name, point it at the carrier, and choose the pricing model.
  4. For a matrix, choose the basis, then add tiers under Order Management › Shipping › Rate matrix, one row per band, starting at 0.
  5. Set free_above if you offer free shipping, and quote_above if there is a size above which you quote by hand.
  6. Restrict countries if the method is not offered everywhere.
  7. Enable it.

What to check

Run a checkout for a realistic basket and confirm:

  • The method appears, and the price matches the tier you expect.
  • A basket immediately below and immediately above a tier boundary prices differently.
  • A basket above free_above costs nothing to ship.
  • The delivery window is plausible, and check it after your cut-off time as well as before.
  • Pause the carrier and confirm every method using it disappears from the quote.

If a method is missing from a quote, the answer says why it was excluded. The usual causes are the carrier's status, the country lists, and a matrix method whose basis is not set.

Next