Skip to content

Shipping

Merchants define zones (sets of countries) and the rates available in each. Storefronts read the active set to price shipping at the cart. Examples reuse the api() helper.

Zones (merchant)

Reads are open to any member; writes require settings:manage. Owner/Admin retain broad access, and Staff needs that group.

const zone = await api("/merchant/shipping/zones", { method: "POST", token,
  body: JSON.stringify({
    name: "United States",        // required, 1–200
    countries: ["US"],            // required; ISO-3166-1 alpha-2, uppercase (may be empty while configuring)
    sortOrder: 0,                 // optional
  }) });

PATCH /merchant/shipping/zones/:id updates (sending countries replaces the list wholesale). Zones archive/restore rather than hard-delete:

await api(`/merchant/shipping/zones/${zone.id}/archive`, { method: "POST", token });
await api(`/merchant/shipping/zones/${zone.id}/restore`, { method: "POST", token });

An archived zone disappears from the public read immediately.

Rates (merchant)

Rates hang off a zone. A rate is a flat per-shipment fee with an optional minimum-subtotal gate.

await api(`/merchant/shipping/zones/${zone.id}/rates`, { method: "POST", token,
  body: JSON.stringify({
    name: "Standard (5–7 days)",  // required, 1–200
    priceInCents: 599,            // required, flat fee
    minimumSubtotalInCents: 0,    // optional — e.g. set to gate "free over $X"
    estimatedDelivery: "5–7 business days", // optional checkout copy
    sortOrder: 0,
  }) });

PATCH /merchant/shipping/rates/:rateId updates; rates archive/restore like zones (POST …/rates/:rateId/archive · /restore).

Read at the cart (public)

GET /api/v1/public/shipping/zones returns only non-archived zones, each with its non-archived rates inlined, ordered by sortOrder then name — exactly what a checkout cost calculator needs:

const zones = await api("/public/shipping/zones");
// → [{ name, countries, rates: [{ name, priceInCents, estimatedDelivery, … }] }]

Tax is a separate checkout concern. The shipping schema deliberately carries no tax fields. Stripe Tax is computed through the M3 checkout-session bind flow when a tax provider is explicitly enabled; shipping rates remain their own preview/configuration surface.