Skip to content

Powered by Grav CMS + Helios Theme

Carriers and services

This page explains the three things between your store and a courier — the aggregator, a carrier account and a service — and what you do with each one.

Before you begin

  • The add-on installed and a key pasted. See Getting started.
  • kahunacart.shipping.manage to change anything on this page, and kahunacart.settings to bind a method to a service.

The aggregator

An aggregator is one account in front of many couriers. You hold one key, and USPS, UPS, FedEx, DHL and forty-odd others quote and print through the same API. Choose Shippo, EasyPost, ShipEngine or Sendcloud in the add-on settings. The first three are strongest for stores shipping from the US. Sendcloud is the one for stores shipping from the UK and Europe: Royal Mail, Evri, DPD, PostNL, DHL, GLS, Colissimo, InPost and many more, with live prices.

One aggregator per store. Nobody runs two, so the setting is a single choice rather than a list, and the whole aggregator appears to KahunaCart as one carrier with one code.

That matters in one visible way. A method binds to the carrier shippo and the service usps_priority, and the add-on works out that the second one means USPS. The customer's tracking link still points at USPS, because the shipment records the underlying carrier rather than the aggregator.

What each driver can do

Capability Shippo EasyPost ShipEngine Sendcloud
Quotes, labels, voids and tracking Yes Yes Yes Yes
Address validation Yes Yes Yes No
Customs Yes Yes Yes Yes
Multiple parcels in one shipment Yes Yes Yes No, one box per label
Verified webhook signatures No Yes No; shared-secret header Yes
A separate test environment Yes Yes Yes No; test mode buys free test labels
Return labels through this add-on No No No No

ShipEngine offers RSA signatures, but this driver authenticates the shared header instead and therefore declares signed webhooks as unavailable. See Tracking.

Set up Sendcloud

  1. Open a Sendcloud account. The free plan includes API access. Your account's country is where it ships from: the UK, the Netherlands, Belgium, Germany, France, Spain, Italy or Austria.
  2. In Sendcloud, go to Settings → Integrations, create a Sendcloud API integration, and copy its public key and secret key. Copy the secret key straight away, because Sendcloud may not show it again. Leave Webhook feedback enabled off and the webhook URL empty; the add-on fills both in for you.
  3. In KahunaCart → Shipping carriers → Settings, choose Sendcloud and paste both keys on the Sendcloud tab. Set Account currency to what the account is billed in, usually EUR, or GBP for a UK account. Save.
  4. Click Check connection. It names the integration and your Sendcloud sender country, and warns you if your Ships from address is in another country, because Sendcloud only offers carriers from its sender country.
  5. Click Refresh carriers, then enable the carriers this store should offer. Each Sendcloud carrier is one account here, with its services.
  6. Fill in Ships from, add your boxes, and bind your zone methods to Sendcloud and the services you want.
  7. On the carriers screen, press Generate secret and then Register webhook. That switches on Sendcloud's tracking updates for your integration and points them at your store.

Sendcloud has no sandbox. One key pair serves both modes. In Test mode the prices you see are real, but every label is bought as Sendcloud's free Unstamped letter, whatever service you picked. It is a real label that costs nothing and that no carrier will carry, and the Buy label sheet and the label both say so. Switch to Live to buy the service you chose.

Service codes are Sendcloud's own. They name the carrier and the product, for example royal_mailv2:tracked_24/signature,size=s or dpd_gb:classic, so a store moving to Sendcloud from another provider binds its methods to new services. Services delivered to a pickup point or a parcel locker are left out for now, because checkout cannot ask the customer to choose one yet.

Set up ShipEngine

  1. Open a ShipEngine account and find API Management. ShipEngine is now called ShipStation API; this driver uses its shipping API, not ShipStation's orders-and-stores API.
  2. Copy the sandbox API key beginning TEST_.
  3. In KahunaCart → Shipping carriers → Settings, choose ShipEngine, leave the mode on Test, and paste the key into ShipEngine → Test API key. Save.
  4. Click Check connection. It reports the mode and the number of connected carrier accounts.
  5. Connect the carriers you want in ShipEngine's own dashboard. Sandbox accounts have their own test carriers; no production key is needed to read them.
  6. Click Refresh carriers here, then enable the accounts this store should offer. Their service names become available in the zone method editor.
  7. Fill in Ships from, including a phone number.
  8. Add the boxes you pack with, then bind your zone methods to ShipEngine and the services you want.

A production key in the sandbox field, or a sandbox key in live mode, is refused before any request. An account switched off here is excluded from quotes. With no enabled accounts, ShipEngine returns no quote.

Switching providers also means rebinding each zone method's Carrier. Matching service codes such as usps_priority, usps_ground_advantage and ups_ground keep their meaning, but a method still bound to shippo does not automatically switch to shipengine. Sendcloud's service codes are different from all three, so moving to Sendcloud means choosing new services as well.

Carrier accounts

A carrier account is your relationship with one courier, held at the aggregator. Most stores end up with three or four: the USPS account that came free with Shippo, a UPS account with your own contract on it, and a FedEx account somebody set up years ago.

They are created at your aggregator and never in your admin. Your store reads the list, mirrors it, and owns exactly one thing on each row: whether this store offers that carrier. That is a different question from whether the account is active at the aggregator, which is about every store using it.

An aggregator account is billed in one currency, and the add-on has to know which. It is the Account currency setting on the driver's own tab, and left empty it is your store's own currency, which is right unless the account was opened in another. It decides what the carrier is asked in at checkout and what a label costs you. See Selling in more than one currency for what happens when it is not the currency of the customer's cart.

Refresh the carrier list

  1. In the admin sidebar, click KahunaCart, then Shipping carriers.
  2. Click Refresh carriers.

Your store now has the current list of carrier accounts and the services each one offers.

Two things a refresh does not do, and both are on purpose:

  • It does not reset your own switches. A refresh that turned a carrier back on would quietly start offering one you had turned off on purpose.
  • It does not delete an account that has gone from the aggregator. A refresh that ran while the aggregator was half-answering would otherwise take a working carrier out of your store.

Switch a carrier on or off for this store

  1. Open KahunaCart → Shipping carriers.
  2. Find the carrier's card under Carrier accounts.
  3. Use its toggle.

A carrier switched off here is left out of every quote whatever its state is at the aggregator.

Things you do at the aggregator

What Where Why
Add a carrier account Your aggregator's carrier settings Each courier has its own forms and its own credentials.
Accept UPS's terms Shippo's web app There is no API for it. Until it is done, UPS quotes nothing and says nothing about why.

Services

A service is one product a courier sells: Priority Mail, UPS Ground, FedEx 2Day. Its code is <carrier>_<token> — usps_priority, ups_ground, fedex_ground — which is the spelling in Shippo's own documentation, because Shippo's tokens already carry the courier's name.

The list offered in a method's editor comes from the carrier accounts you have switched on, stored here after the last refresh. It is never fetched while you are looking at the screen, so a slow afternoon at the aggregator cannot make the Shipping screen unopenable.

Note

A method naming a service the list does not have is warned about and still offered. A list can be stale, and a store must not lose a working method because a list read this morning was short.

Bind a method to a service

  1. In the admin sidebar, click KahunaCart, then Shipping.
  2. Click Edit on a zone, and open one of its methods.
  3. Set Carrier to your aggregator and Service to one of the services listed.
  4. Click Save.

The method is now priced by the courier. Create one method per service you want to offer; the add-on does not shop for the cheapest of everything the courier quoted.

FedEx One Rate

A FedEx One Rate variant shares its service token with the standard rate and differs only by a terms field, so two rates in one response can carry the same code. It is listed as its own service on an extended token.

The rate a label is bought with is identified by the aggregator's own object id rather than by the token, which is why the code you bind a method to and the thing a label is bought with are two different strings. Nothing about that is visible in the admin; it matters if you are reading the API.

Refuse a whole class of thing

Core has a per-method shipping class policy — allow, require, disallow — which is right for methods you invented. A courier that will not fly lithium batteries will not fly them by any of its fourteen services, and typing that into fourteen method editors is how one of them ends up missing.

Classes this carrier will not take says the same rule once for the whole carrier.

  1. Open KahunaCart → Shipping carriers and the Settings tab.
  2. On the General tab, fill in Classes this carrier will not take with a comma-separated list of shipping class codes (excluded_classes).
  3. Click Save.

A cart holding a line in one of those classes now takes every method bound to this carrier off the list, naming the product rather than leaving the customer looking at a shorter list. Empty is the default, and a store that configures none behaves exactly as it did.

Where each fact lives

Fact Lives at Changed by
The courier relationship and its credentials the aggregator you, in the aggregator's console
Which couriers exist and what services they sell the aggregator, mirrored here Refresh carriers
Whether this store offers a courier your store the toggle on the carrier card
Which service a method sells your store the zone method editor
Where a parcel ships from your store Ships from on the Shipping carriers screen
What a parcel packs into your store the box catalogue