Shopify Orders With No Tracking After ShipStation Ships Them: Why It Happens

The warehouse says the box left yesterday. ShipStation shows a label and a tracking number. The customer is looking at a Shopify order page that still says unfulfilled, and they have just opened a support ticket asking where their order is.

If you run Shopify with ShipStation, you have probably seen this at least once. The annoying part is that it happens only sometimes, which makes it hard to trust the sync and hard to prove it is broken.

Why the sync only works most of the time

When a label is created, ShipStation is supposed to tell Shopify, and Shopify is supposed to mark the items fulfilled and email the customer. That is a chain of notifications between two services, and any link can drop.

I treat notifications like these as a best effort delivery. They usually arrive, and when they do not, nobody is told. In the ShipStation projects I have worked on, I have not found a reliable log you can open that says “this tracking update failed and here is why.”

These are the situations I check first when a store tells me tracking is missing:

  • The order was edited after it was imported. A changed item, address or shipping method can leave ShipStation and Shopify disagreeing about what the order contains.
  • Split shipments. One order leaves in two boxes, and only one of them gets matched to Shopify items.
  • Fulfillment location mismatches. Shopify decides which location fulfills which items, and a mismatch between that and what ShipStation reports can block the update.
  • Voided and recreated labels. The old shipment and the new one both exist, and the wrong one wins.
  • Temporary errors on either side. A rate limit or a short outage at the wrong moment, with no retry afterward.

Not every one of these will apply to you. The point is that the cause is rarely a single bug you can switch off.

The fix is a safety net, not a better notification

Trying to make a flaky notification perfect is a losing game. What works is a second path that does not depend on it.

Here is the shape I use:

  • A scheduled job asks ShipStation for every shipment created since the last successful run, with a small overlap so nothing falls between runs.
  • For each shipment, it finds the matching Shopify order and checks whether a fulfillment with that tracking number already exists.
  • If it does not exist, the job creates the fulfillment through the Shopify API with the carrier and tracking number, and tells Shopify whether to notify the customer.
  • If the order cannot be matched, it goes into a list that a human looks at, along with an alert.

The check before creating is the important step. It makes the job safe to run twice, so you can rerun it after an outage without sending duplicate shipping emails.

Add one alert and you will sleep better

The most useful rule I know is boring. Every morning, list the orders that ShipStation shows as shipped more than a few hours ago and that Shopify still shows as unfulfilled. If the list is not empty, send it to someone.

This works even if you never build anything else. A ten line report you read daily catches the problem before the customer does.

Should this be a custom build?

If you ship a few orders a day, a daily report and a manual fix might be enough. If you are past a few dozen orders a day, or you sell products where a delayed tracking email leads to chargebacks and refund requests, a reconcile job is cheap insurance compared with the support time it saves.

This was the missing piece in one of my own projects, where the data was flowing into ShipStation correctly but the tracking was not flowing back reliably. I describe how the two directions fit together in Why Custom Packing Slips Are So Hard. The other half, getting custom data into ShipStation in the first place, is covered in ShipStation Custom Fields 1, 2 and 3.

If your tracking sync is flaky and you want it looked at, email kevin@kevinhq.com with a couple of order numbers where it failed. Those two or three examples usually point straight at the cause.


← Back to Homepage


Get occasional breakdowns

When I find something worth writing up — a fix, a pattern I keep seeing in client stores, something that actually moved revenue — I send it out. No schedule. No filler.