There are two completely different things in PrestaShop that both get called "setting up a carrier," and conflating them is where most merchants get stuck. The first is creating a carrier by hand in the back office — a name, some zones, a price grid — which is plumbing PrestaShop has always shipped with. The second is installing a carrier module: a piece of software that registers one or more carriers for you, talks to a real courier's API, prints labels, pulls live rates, and drops pickup-point maps into your checkout. This guide is about the second one — what a carrier module actually is, how it hooks into PrestaShop, how to install and configure it without breaking checkout, and how to tell a good one from a liability. For building carriers manually from zones and ranges, that's a different job and we cover it in the complete shipping configuration guide.

What a carrier module actually is (and why it's different from a back-office carrier)

When you go to Shipping → Carriers and click "Add new carrier," you create a row in the ps_carrier table that PrestaShop evaluates against the cart at checkout. It's static: the price comes from a grid you typed in, and the carrier knows nothing about the courier beyond a name and a tracking-URL template. That's fine for "Standard Shipping €5.99," and it's the right tool for a lot of stores.

A carrier module is a different animal. On install, it programmatically creates its own carrier(s) — it instantiates the Carrier class in its install() method, sets id_reference, ranges, zones and groups in code, and stores the resulting carrier ID in its own configuration so it can manage that carrier across upgrades. From then on the module owns that carrier. So what does that buy you? Behaviour the static grid can't do:

  • Live rates. Instead of a price you guessed, the module calls the courier's API at checkout and returns the real quote for this cart's weight, dimensions and destination — by implementing getOrderShippingCostExternal() on a carrier flagged as a module carrier with need_range off, so PrestaShop asks the module for the price instead of reading a static range grid.
  • Pickup points. Relay-point and locker carriers inject a map or dropdown into the delivery step (via the displayCarrierExtraContent hook, the 1.7+ replacement for the deprecated displayCarrierList) so the customer chooses a specific locker, and the module saves that choice against the order. The hook only fires for the carrier whose external_module_name points at the module.
  • Labels and manifests. A back-office button (or an order-status hook) generates the courier's shipping label PDF and writes the tracking number straight onto the order — no copy-pasting into the courier's own portal.
  • Self-healing config. Because the carrier is created in code, the module can recreate or update it after a PrestaShop upgrade instead of you rebuilding a price grid by hand.

The practical takeaway: if your courier offers an official PrestaShop module, you almost always want it over a hand-built carrier — the manual version can't print a label or quote a real price. If your courier doesn't, a manual carrier is your fallback, and the configuration guide above is where to start.

Before you install anything: three checks that prevent broken checkouts

Carrier modules touch the most fragile page in your store, so the order of operations matters. Store owners' single biggest fear is a module that breaks checkout — earn that trust by checking three things first.

  • Compatibility with your exact version. The carrier API landscape changed across PrestaShop 1.6 → 1.7 → 8 → 9; a module written for 1.6 may register its carrier in a way 8.x ignores. Confirm the module lists your version before you buy, not after.
  • A staging copy. Never install a carrier module first on production. Clone the shop, install there, and run a real test order to each zone. A carrier that fails to register correctly shows up as the dreaded "no carriers available" at checkout — and you do not want to discover that with live customers.
  • A database backup. Because these modules write to ps_carrier, ps_carrier_zone and the range tables on install, a clean restore point means a bad install is a five-minute rollback rather than an afternoon.

The install-and-configure sequence that actually works

Most official carrier modules follow the same shape. Knowing the sequence means you can configure any of them — DHL, GLS, Colissimo, InPost — without re-learning the workflow each time.

  • 1. Install the module. Modules → Module Manager → Upload a module, drop the ZIP, install. At this moment the module creates its carrier(s) — go to Shipping → Carriers and you'll see them appear automatically.
  • 2. Enter your account credentials. Open the module's configuration and paste the API key / client ID / contract number the courier gave you. This is what separates a working live-rate carrier from a dead one. Most modules have a "test connection" button — use it; a green tick here saves you a failed checkout later.
  • 3. Map zones and services. The module created a carrier, but you still decide where it ships and which of the courier's services (standard, express, locker) you expose. Assign the carrier to your zones under its Shipping → Carriers entry, or inside the module if it manages zones itself.
  • 4. Set the fallback price. Live-rate modules need a fallback for when the courier API times out — otherwise an API hiccup becomes a lost order. Set a sensible flat price the module falls back to so checkout never shows zero carriers.
  • 5. Configure handling and label options. Sender address, default package weight, label format (A4 vs thermal), and which order status triggers label generation.
  • 6. Place a real test order through to payment for each zone, confirm the carrier appears, the rate looks right, and (if supported) a label generates.

Manual carrier vs carrier module — which to use

Hand-built back-office carrierCarrier module
SetupYou type a name, zones, price gridInstall ZIP; carrier appears automatically
PricingStatic grid you maintain by handCan pull live rates from the courier API
Pickup points / lockersNot possibleMap or dropdown injected into checkout
Labels & trackingManual — copy into the courier portalOne-click label PDF; tracking written to the order
MaintenanceYou re-edit prices when the courier changes ratesLive rates update themselves; flat grids still need edits
Best when…Simple flat/threshold shipping, or no official module existsYour courier offers a module and you want real rates, lockers or labels

Picking real-courier modules: the integrations that exist

Once you've decided you want a module, the question is which one — and that's courier-specific, because each integration has its own quirks (contract numbers, locker APIs, label formats). Rather than cram them into one rushed list, here's the map to the carrier-by-carrier guides:

The "no carriers available" problem — and what causes it with modules

The most common failure after installing a carrier module is checkout showing no shipping options at all. With a hand-built carrier this is almost always a missing zone assignment; with a module there are a few extra suspects, because the module added a layer:

  • The module's carrier isn't assigned to the customer's zone. The module created the carrier but you never mapped your destination countries to it. Fix under Shipping → Carriers → the carrier's Shipping locations and costs.
  • No price range covers this cart. Some modules still rely on a weight/price range row for availability or as a fallback, so if the API returns nothing and no range covers the cart, the carrier can vanish. A true external-rate carrier with need_range off won't depend on a static range row at all — but if the module left a range requirement in place, that's a suspect.
  • API credentials are wrong or the courier API is down. Without a fallback price, a failed API call silently drops the carrier. This is exactly why step 4 above matters.
  • Group or shop restriction. The module may default its carrier to one customer group or one shop in a multistore. Check Group access and Shop association on the carrier.
  • Product has no weight. Weight-based and live-rate carriers both lean on real product weights in the catalogue; depending on the module and range setup, a missing or 0 kg weight can break weight-based or API rating — or fall outside every configured range — so the carrier mis-prices or disappears.

For the deeper logic of how zones, ranges and carriers fit together — the model these errors all trace back to — the complete shipping configuration guide is the reference.

Carrier modules are half the job — the customer-facing half still matters

A perfectly installed carrier module quotes the right price and prints the label, but the customer experience around it is a separate decision you shouldn't skip:

  • What delivery date do they see? PrestaShop's built-in transit-time field shows the same "3–7 business days" to every destination regardless of zone or your handling time. Showing a real date instead is its own topic — see setting realistic delivery expectations and why a concrete date reduces customer anxiety. Our Estimated Delivery Date module fills that gap: it calculates an actual arrival date per carrier and zone, factoring your handling time and business days, so a German customer sees "Delivery: Wednesday" while a Spanish customer sees "Delivery: Friday" — without you editing a theme file.
  • Do they get told once it ships? The tracking number your module wrote onto the order is only useful if it reaches the customer — covered in tracking numbers and delivery notifications.
  • What do you charge on top of the courier's rate? Whether you pass live rates straight through, flatten them, or absorb them into free shipping is a margin decision — start with free vs flat vs calculated and, if you're a smaller store, shipping strategy for small stores.

The short version

"Setting up a carrier module" isn't the same as adding a carrier in the back office — a module installs software that owns its own carrier, talks to the courier, and does the things a static price grid never could: live rates, locker maps, one-click labels. Install on staging with a backup, enter your contract credentials and test the connection, always set a fallback price so an API blip can't empty your checkout, and place a real test order to every zone before you go live. Then pick the right courier integration for your markets, and make sure the customer-facing side — delivery dates, tracking, what you charge — is as considered as the plumbing behind it. Get those right and the carrier step stops being a source of abandoned carts and starts being one less reason to leave.

Share this post:
David Miller

David Miller

Over a decade of hands-on PrestaShop expertise. David builds high-performance e-commerce modules focused on SEO, checkout optimization, and store management. Passionate about clean code and measurable results.

Enjoyed this article?

Get our latest tips, guides and module updates delivered to your inbox.

Comments

No comments yet. Be the first!

Be the first to ask a question or share useful feedback.

Loading...
Back to top