Shipping
List shipping methods and fetch live carrier quotes for the checkout picker
Behio supports two pricing modes per shipping method, set by the merchant in the admin:
- Fixed price — the merchant sets a per-currency price (e.g. PPL = 120 CZK). Free-shipping thresholds work.
- Live quote — the price is fetched from a meta-provider (Zaslat.cz today, others coming) per destination. The merchant configures markup + rounding rules; the customer sees the adjusted price.
Both routes are exposed through the same SDK module — pick the call that matches your checkout flow.
Always-on listing
When you need a quick list of available methods (sidebar widget, info page, default cart summary), use listMethods. Fixed-price methods come back fully resolved; live-quote rows return price: 0 here — call quote() once you have a destination address.
const {data, error} = await client.shipping.listMethods({
currency: 'CZK',
country: 'CZ',
cartTotal: 1850,
cartWeightKg: 1.2,
});
if (data) {
data.items.forEach((m) => {
console.log(m.name, m.price, m.currency, m.deliveryType);
});
}Live quote at checkout
Once the customer enters their delivery address, call quote() to get destination-specific prices. The endpoint dispatches each live-quote method to its upstream meta-provider and applies the merchant's markup + rounding rules. Fixed-price methods are returned unchanged for completeness.
const {data} = await client.shipping.quote({
destinationAddress: {country: 'CZ', zip: '11000', city: 'Praha'},
items: [
{whItemId: 'wh_01H...', quantity: 2, weightKg: 0.4},
{whItemId: 'wh_01H...', quantity: 1, weightKg: 1.8},
],
cartTotal: 1850,
currency: 'CZK',
});
// Filter unavailable rows for the picker
const offers = (data?.items ?? []).filter((q) => q.available);Quote response shape
Each entry extends the ShippingMethodSummary returned by listMethods with quote-only fields:
| Field | Type | Notes |
|---|---|---|
strategy | "fixed" | "live_quote" | How the price was resolved |
available | boolean | false when the upstream provider didn't return a rate (carrier not contracted, destination outside coverage, max-price cap exceeded, provider not implemented yet) |
reason | string | null | Machine-readable hint when unavailable: "no_rate_returned", "live_quote_not_implemented" |
price | number | Final customer price (already includes markup/rounding for live quotes) |
basePrice | number | Raw price before adjustments, informational only |
etaDaysMin / etaDaysMax | number | null | Live providers fill these from the upstream response when available |
currency | string | null | Resolved currency for the price |
Free shipping thresholds
Fixed-price methods support per-currency free-shipping thresholds set by the merchant. When cartTotal (in the quote's currency) exceeds the threshold, the response carries isFreeShipping: true + price: 0. The threshold itself is on freeShippingThreshold so you can render hints like "Add 150 CZK more for free shipping".
data.items.forEach((q) => {
if (q.freeShippingThreshold && !q.isFreeShipping) {
const remaining = q.freeShippingThreshold - cartTotal;
console.log(`${q.name}: ${remaining} ${q.currency} away from free shipping`);
}
});Currency handling
The quote request currency should match the cart's currency. The merchant decides which methods are available per currency:
- A method's
currencies[]allow-list restricts which currencies see it (empty = inferred frompricing[]rows). - For fixed pricing, the method needs a
pricing[]row in the requested currency or it's skipped. - For live quote, the meta-provider returns the currency in its response — usually matches the cart, but always check
q.currencyto be safe.
Pickup points (coming soon)
Methods with supportsPickupPoints: true (Zásilkovna, Packeta, PPL ParcelShop, …) require the customer to pick a specific drop-off location. The pickup-point picker SDK is on the roadmap. For now, you can fetch the cached list directly via the admin pickup-point endpoints.
Meta-providers under the hood
Behio's storefront SDK is provider-agnostic — your storefront code never names Zaslat, Shippo, Sendcloud, or any specific aggregator. The merchant picks a provider per shipping method in the admin; the SDK just sees provider as an internal id. As Behio adds providers, your existing code keeps working without changes.