ShipStation for Craft Commerce 5
Orders out, tracking back
Shipper connects Commerce to a ShipStation Custom Store. There's no Matrix field to build and no handles to type into settings. Install it, paste one URL into ShipStation, and orders start importing.
Features
The ShipStation handshake, plus the parts you need when something goes quiet.
Nothing to model
Shipments are Shipper's own data, not a field you build. Each one has a carrier, service, tracking number, ship date and the items it contained, shown on Commerce's order screen and in their own index.
A log you can read
Every request ShipStation makes is logged with its status code and timing. On Pro the log also keeps the full payload in both directions. A 401, an empty export or a rejected notification shows up there, not in a support ticket.
Partial shipments, counted
Pro counts the items in each shipment and only completes the order when every shippable unit has gone. Until then the order can sit in a "partly shipped" status of your choosing.
Retries that don't double up
ShipStation re-sends notifications every hour and gives them no ID. Shipper identifies a shipment by its tracking number and carrier, and a database constraint backs that up, so a retry is recognised and ignored instead of being counted twice.
Live rates that fail open
Pro offers real ShipStation carrier rates as Commerce shipping methods. Quotes are cached against the cart's contents. If ShipStation is slow or down, checkout carries on with your own methods.
- A carrier outage can never stop a customer paying
- Changing the cart re-quotes; re-costing the same cart is free
Works behind Apache
Apache often strips the Authorization header, which breaks HTTP Basic auth without any error. Shipper also accepts an auth key in the URL, so the connection works whatever the server does with headers.
Tracking on your own order page
The craft.shipper Twig API gives a "where's my order" page everything it needs: each shipment, a tracking link for more than 20 carriers, and how much of the order has shipped.
{% for shipment in craft.shipper.shipments(order) %}
{% set url = craft.shipper.trackingUrl(shipment.carrier, shipment.trackingNumber) %}
<p>
{{ shipment.getLabel() }}
{% if url %}<a href="{{ url }}">{{ shipment.trackingNumber }}</a>{% endif %}
</p>
{% endfor %}
{% set progress = craft.shipper.progress(order) %}
<p>{{ progress.shipped }} of {{ progress.total }} items shipped</p>
Frequently Asked Questions
The questions worth answering before you install it.
Lite is free and covers the full Custom Store connection: order export, shipment notifications, stored shipments, tracking links, the order-screen panel, the Twig API and console commands. Pro is $99, then $79 a year for updates. It adds the full-payload connection log, partial shipments, status mapping, custom fields, Sync now and live carrier rates at checkout.
Not for the connection itself. ShipStation fetches orders from your site and posts tracking back, so you only need a username and password. Pro's live rates and Sync now use the ShipStation API, and those need a key.
No. It asks ShipStation to fetch from your store straight away. Pushing orders through the API as well would give you two copies of every order.
Yes. Preview XML on the order screen, or php craft shipper/export/preview, runs the same builder as the live endpoint. The preview and the real request are byte-for-byte identical.
Craft CMS 5.3+, Craft Commerce 5.0+, PHP 8.2+.
Paste one URL into ShipStation
Install Shipper, set a username and password, and give ShipStation the endpoint. The log will show its first request.