automations.help

Order & fulfillment ops

Sync 3PL tracking numbers back to Shopify

When your 3PL ships an order, the carrier and tracking number should land on the Shopify order on their own — and trigger Shopify's shipping-confirmation email. Here's how to wire ShipBob's shipment event back to the order, split shipments and all.

Difficulty
Intermediate
Time to build
3-5 hrs
Updated
  • ShipBob
  • Shopify
  • n8n

The manual way today

Someone opens the 3PL portal, pulls the day's shipments, and for each one copies the carrier and tracking number, finds the matching Shopify order, pastes it into the fulfillment, ticks 'notify customer', and marks it fulfilled — one order at a time.

Until that copy-paste happens, the order still shows as unfulfilled and the customer has no tracking, so they open a 'where's my order?' ticket — for an order that already shipped. The lag grows with volume, weekends pile up, and a fat-fingered tracking number points someone at the wrong parcel, which becomes its own support thread.

What running looks like

A label created in ShipBob flips the matching Shopify order to fulfilled, writes the carrier, tracking number, and tracking URL onto it, and fires Shopify's native shipping-confirmation email — usually within a minute, untouched. The order timeline and the customer's status page both reflect it. Shipments that can't be matched stop and wait for a person instead of attaching a wrong number.

01The build

How to build it

  1. Catch ShipBob's shipment event (or poll for it)

    Runs itself

    Turn on ShipBob's order-shipped webhook so it pushes a payload the moment a label is created — it carries the carrier, tracking number, tracking URL, and the reference ID you set when the order was created. No webhook on your plan? Poll ShipBob's shipments/orders API every 10–15 minutes for anything newly marked shipped. Point either at an n8n webhook (or schedule) node.

  2. Match the shipment back to the right Shopify order

    Runs itself

    Key off the reference ID you wrote into ShipBob when the order was created (the Shopify order name or ID), not the customer email — email isn't unique and breaks on repeat buyers. Use that ID to look the order up through Shopify's Admin API so you've got the order and its line items in hand.

  3. Pull the order's fulfillment orders from Shopify

    Runs itself

    Shopify fulfills through Fulfillment Orders now, not the old REST fulfillment endpoint. Query the order's fulfillmentOrders to get each fulfillment order ID, its assigned location, and the line items it covers. That's what you create the fulfillment against in the next step.

  4. Create the fulfillment with tracking and notify the customer

    Runs itself

    Call Shopify's fulfillmentCreateV2 GraphQL mutation against the fulfillment order, passing trackingInfo with the company, number, and url, and set notifyCustomer to true. That single call marks the order fulfilled, attaches the tracking, and fires Shopify's own shipping-confirmation email — so you never build or send the email yourself.

  5. Handle split shipments and multiple tracking numbers

    Runs itself

    If the 3PL boxes an order into two parcels, you'll get two shipments with two tracking numbers. Create one fulfillment per parcel, each scoped to the line items actually in that box, so every tracking number maps to the right items instead of stamping one number across the whole order. Shopify sends a shipping email per fulfillment.

  6. Skip anything already fulfilled, and dedupe retries

    Runs itself

    Before creating a fulfillment, check whether that fulfillment order is already fulfilled — a teammate may have marked it by hand. Dedupe on the tracking number plus order so a retried or re-fired webhook can't create a second fulfillment or send a second email. Already done? Log it and move on.

  7. Flag the shipments you can't safely place

    Needs a human

    If no Shopify order matches the reference ID, the order is already cancelled, or the carrier string is one Shopify won't recognize, don't guess — post the shipment payload and the reason to a Slack channel and stop. A person resolves the oddball and re-runs that one shipment.

  8. Reconcile shipped-vs-fulfilled once a day

    Runs itself

    Once a day, compare orders marked shipped in ShipBob against orders fulfilled in Shopify and flag any gaps to Slack. That catches the rare dropped webhook before it becomes a customer wondering why a delivered order still reads 'unfulfilled'.

02The stack

What it’s built on

Shopify
System of record for the order. Receives the fulfillment and tracking, updates the order timeline and customer status page, and sends its own shipping-confirmation email.
ShipBob
The 3PL that creates the shipping label and emits the carrier and tracking number. The reference ID you set at order creation is what links its shipment back to the Shopify order.ShipBob's shipment webhooks and orders API make this clean, so it's an honest pick if you're still choosing a 3PL. Any 3PL that exposes a shipment event or a shipments API works the same way — only the field names change.
n8n
The glue: catches the shipment event, matches the order, pulls the fulfillment orders, creates the fulfillment, and runs the daily reconcile.n8n is open-source and self-hostable for free; their cloud tier just saves you running it yourself.
Slack
Where unmatched shipments, unknown carriers, and reconcile gaps get flagged for a human.

03Questions

Before you build

Will this email my customers, or do I still send tracking myself?

Shopify sends it. Setting notifyCustomer to true on the fulfillment fires Shopify's native shipping-confirmation email with the tracking link, so you don't build a separate one. Turn off any duplicate tracking email on the 3PL side so customers don't get two.

Isn't Shopify's fulfillment API deprecated?

The old REST fulfillment endpoint is. The current path is Fulfillment Orders: query the order's fulfillmentOrders, then create the fulfillment with the fulfillmentCreateV2 GraphQL mutation and trackingInfo. This recipe is built on that newer model, so it won't break on the REST sunset.

What happens with split shipments or multiple tracking numbers?

Each parcel gets its own fulfillment, scoped to the line items in that box, so every tracking number maps to the right items. The customer gets one shipping email per parcel — which is what they actually want when an order ships in two boxes.

Will it double-fulfill an order a teammate already marked shipped?

No. The flow checks whether the fulfillment order is already fulfilled and dedupes on tracking number plus order before doing anything, so a manual fulfillment or a re-fired webhook won't create a second fulfillment or send a second email.

What if my carrier isn't one Shopify recognizes?

Shopify auto-links tracking for known carriers; for an unrecognized one you pass the carrier name plus the full tracking URL so the customer still gets a working link. If the carrier string is genuinely ambiguous, the flow flags it to Slack rather than attaching a dead link.

Can I build this myself, or should you build it?

Every trigger, field, and edge case is spelled out above so you can — if you've got API comfort and a few spare hours, wire it up. If you'd rather not own the debugging, we'll build it on the Shopify, ShipBob, and n8n accounts you already pay for, document it, and hand you the keys. You own the workflow outright — no monthly retainer, no platform you can't walk away from. It starts with a free 20-minute teardown, not a contract.

Support & returns

Auto-draft Gorgias replies to 'where is my order' tickets

'Where is my order?' is the most common ticket in DTC support, and almost every answer is the same lookup: find the order, find the tracking, paste it back. This watches Gorgias for WISMO tickets, pulls the live fulfillment status from Shopify (and ShipBob when Shopify's tracking is stale), and writes a ready-to-send draft into the ticket — your agent reviews, tweaks if needed, and hits send. It never auto-sends, and the messy cases (no order, delivered-but-missing) get flagged to a human instead of a canned reply. Build it yourself with the steps below — or we build it, wire in the guardrails, and hand it over so you own it outright with no monthly fee. Free teardown of your current setup first.

  • Gorgias
  • Shopify
  • ShipBob

Intermediate4-7 hrs