01 / the front door
Shopify holds the order
Shopify Plus is the system of record for the order: customer, line items, payment, address. It is where the sale happens.
Integration / Makro Middleware
Shopify Plus is the system of record for the order. ShipStation owns shipping once the order lands there. We build the reliability layer in the space between: idempotent writes, reconciliation, and a console you operate.
The real problem
Orders that never imported. Tracking that never wrote back. Duplicate fulfillments. Oversells from one-way, ten-minute stock. The gap between the storefront and the shipping platform is where fulfillment breaks.
01 / the front door
Shopify Plus is the system of record for the order: customer, line items, payment, address. It is where the sale happens.
02 / the back room
Once an order lands in ShipStation it owns rating, labels, carrier and tracking. It becomes the shipping system of record.
03 / the gap
Orders that never imported. Tracking that never wrote back. Duplicate fulfillments. Oversells from one-way, ten-minute stock.
We built a product around that exact gap. ShipStation plugs into it as a first-class, path-mapped adapter.
Architecture
Orders are pushed from Shopify into ShipStation, where labels print and shipments are created. Fulfillment status and tracking are written back into Shopify. The middleware sits in the middle, makes both writes idempotent, and reconciles what neither side guarantees to deliver.
Order system of record
where the sale is placed
The platform
map · reconcile · audit
Shipping system of record
rate · label · track
orderKey, full-resource only. We set orderKey to the Shopify id for idempotent retries, always set advancedOptions.storeId, and read-merge-write so we never clobber a field. Open-status only.Shopify → SSmodifyDateStart / modifyDateEnd window with a page loop is the canonical delta sync. Datetimes are PST/PDT, not UTC.SS → MKresource_url for the batch, then write back into Shopify with fulfillmentCreate + fulfillmentTrackingInfoUpdate at FulfillmentOrder granularity.SS → ShopifyAPI-Key header, both static and full-access. The credential lives server-side in a vault, never in client code, behind the least-privilege boundary the middleware owns. TLS 1.1+ throughout.handshakemarketplaceNotified and notifyErrorMessage to prove the tracking reached Shopify, and replay any miss against the idempotent targets.SS ↔ ShopifyThe console
Every order import, every writeback, every failed sync is visible. This is the same Makro Middleware console your fulfillment team would watch in production. Move through the views.
| Time | Entity | Error class | Attempts | Next | Action |
|---|---|---|---|---|---|
| 08:13:04 | writeback · order #1042 | PERMANENT · validation | 3 / 3 | held | Inspect |
| 07:55:22 | createorder · #1038 | TRANSIENT · timeout | 2 / 5 | 09:50 | Retry now |
| 06:40:11 | delta poll · GET /orders | RATE_LIMIT · 429 | 1 / 5 | paced | Inspect |
Every order carries three identities at once: the Shopify gid, the ShipStation orderKey we stamp for idempotent upserts, and the ShipStation orderId that results.
Set orderKey to the Shopify id and a replayed webhook writes the order once, never twice. The map also pins advancedOptions.storeId so an order can never land in the default manual store.
This is what stops duplicate fulfillments and double-imported orders before they reach your shipping queue.
entity key map · order stitched Shopify → ShipStation → fulfillment
Inside the platform
The native path is a black box: no surface to observe, no alert, no replay, on an at-least-once substrate. These are the ten subsystems the middleware brings to ShipStation's exact, documented gaps.
01 / 10
When a write fails
It is classified before it is retried, and nothing disappears into a log file. Colour carries the verdict: amber arrives and is sorted, teal retries, red is held, green replays.
A notifyErrorMessage comes back on a tracking writeback, or a 429 hits on the 40/min V1 ceiling. Instead of disappearing into a log, it enters the pipeline.
Every failure is sorted before anything is retried, so a bad record never loops forever and a real outage never gets buried.
classifiedA 429 enters the RATE_LIMIT lane and paces against X-Rate-Limit-Reset. Timeouts retry with backoff, automatically, until they clear.
A validation failure routes straight to the dead-letter queue for review. It is never retried blindly or lost.
held for reviewFix the cause, replay from the queue against the idempotent targets. A daily reconciliation pass catches anything the live path missed.
replayed · reconciledWhen the native ShipStation connector stops being enough
The native connector is fast, free, and genuinely the right answer for a single store with vanilla order-in, label-out, tracking-back. These are the failure modes no vendor page admits, every reality traced to a primary ShipStation, ShipEngine or shopify.dev source. A custom middleware layer is built to handle all of them, explicitly.
POST /orders/createorder or drives POST /stores/refreshstore on its own cadence.notifySalesChannel, and it defaults to false. Mark an order shipped via API without explicitly setting it true and Shopify never learns the order shipped, the classic "tracking not appearing in Shopify." ShipStation also does not ingest Shopify-side fulfillment changes after import, so fulfilling the same order in Shopify creates drift it will not auto-correct.resource_url (200-char) plus resource_type; you make an authenticated GET to fetch the records, and that callback is batch-scoped, so one notify fans out to N orders. Every callback costs against the 40/min budget.GET /orders?modifyDateStart=… on a timer, and ShipStation datetimes are PST/PDT, not UTC, a classic delta-window off-by-timezone bug.POST /orders/createorder requires the entire resource in the body and is keyed on orderKey. Only open-status orders (awaiting_payment, awaiting_shipment, on_hold) can be updated; shipped and cancelled are terminal. Middleware must read-merge-write to avoid clobbering fields.on_hand / allocated / available), and only with the separate Inventory API add-on enabled. Building inventory middleware against V1 is a dead end.On Hand − Committed every ~10 minutes, exact-SKU match only (non-matches silently skipped). And there is no inventory webhook in either generation, you poll or infer.warehouseId, which is an unrelated id namespace.x-shipengine-* headers, a JWKS endpoint, and a 5-minute replay window, but you must confirm which path the account is on and verify every inbound webhook. There is no documented at-least-once or retry guarantee for V1 webhooks; treat them as best-effort and back with a reconciliation sweep.X-Rate-Limit-Reset seconds. V2 is 200/min and steers bulk work to batch endpoints. High volume plus batch-webhook fan-out plus a 40/min ceiling is a throttling problem you engineer around with a rate-aware token bucket.orderKey, X-Shopify-Webhook-Id), which is exactly where the middleware lives.What we build
One platform, your exact order flow. The four build modules below cover the Shopify and ShipStation API surface, the routing, and the volume the native connector cannot model.
Module 01
Custom-field and metafield mapping across the order, fulfillment and webhook surface, both API generations.
Right for brands that need custom fields and labels to carry the data the native mapping drops.
Module 02
ShipStation routes to and from your ERP and WMS. We own the routing logic the native "Do Not Import" rule cannot express.
Right for routed fulfillment that has to reconcile with an ERP or WMS, not just print a label.
Module 03
A consolidated, custom-mapped integration across stores and expansion stores, with Shopify Locations mapped to V2 inventory warehouses.
Right for multi-store and expansion-store brands tired of stacking native connectors.
Module 04 at volume
A rate-aware token bucket against the 40/min ceiling, V2 batch and multi-package rates, and split or partial shipments handled cleanly.
Right for Plus brands whose fulfillment has outgrown the native connector: high volume, multiple stores, multi-warehouse, B2B and wholesale routing, custom field or label data, or ERP and WMS-adjacent flows.
The decision guide
There are three ways to connect ShipStation to Shopify: the native connector built into ShipStation, a third-party iPaaS layer for advanced data mapping, and a custom integration on the Shopify and ShipStation APIs for fully tailored workflows. The right choice depends on store count, routing complexity, and order volume.
Option 01
The connector built into ShipStation. The fastest path, sets up in minutes, limited to orders and basic customer data.
Right for a single store with vanilla order-in, label-out, tracking-back and no B2B or routing needs. If that is you, this is the right answer.
Option 02
A subscription middleware layer on a shared platform for advanced data mapping across templated connectors.
Right for standard multi-system data mapping where the routing logic fits a template and rented infrastructure is acceptable.
Option 03 our build
Built on the Shopify and ShipStation APIs around your exact workflows, owned by you, operated with a support agreement. Where Plus and B2B brands end up.
Right for multiple stores, B2B and wholesale routing, multi-warehouse fulfillment, custom data mapping, ERP and WMS sync, or a Plus environment where tracking writeback and automation must be reliable at volume.
How we deliver
A ShipStation × Shopify Plus build lands in one of three bands depending on store count, routing complexity, and how many of the break points above are in play. Discovery first, then build, then a parallel-run to go-live.
Band 01 · foundation
weeks · single store · standard fulfillment
Band 02 · multi-store / B2B
weeks · multiple stores · custom fields
Band 03 · ERP / WMS / 3PL
weeks · routed fulfillment · high volume
We price a ShipStation integration as an engineering engagement: a build with a support agreement, not a per-record meter or a platform seat that renews forever. For market context, enterprise iPaaS commonly runs $30,000 to $100,000+ a year before the work begins. Your exact figure is scoped to the band and the break points in play, and we put it in writing before anything starts.
Security posture
The ShipStation key is static, long-lived and full-access, so it is held as an encrypted field, isolated per tenant, rotatable without downtime, and never in client code or version control.
Shopify webhooks are HMAC-verified and ShipStation webhooks RSA-SHA256-verified via ShipEngine, three x-shipengine headers, a JWKS endpoint and a 5-minute replay window, then deduplicated so a replay cannot create a second order.
ShipStation has no scoped or read-only keys, so the boundary is ours. V1 Basic and V2 API-Key are vault-stored, and the middleware exposes only the operations the integration needs, never the raw full-access key.
An append-only audit trail logs every operation, source-tagged, so you can prove what happened to any order, label or tracking writeback.
Frequently asked questions
The details that separate a team that read the docs from a team that shipped against them. Open any one.
notifySalesChannel, and it defaults to false. Mark an order shipped via the API without explicitly setting it true and Shopify never learns the order shipped. We own the write instead: consume SHIP_NOTIFY and write into Shopify with fulfillmentCreate and fulfillmentTrackingInfoUpdate at FulfillmentOrder granularity, then watch marketplaceNotified and notifyErrorMessage to confirm or repair the writeback.ssapi.shipstation.com, HTTP Basic) carries the order, store, fulfillment and webhook model. V2 (api.shipstation.com/v2, API-Key header) is shipping-first: rates, labels, tracking, batch, plus the inventory add-on. A Shopify Plus fulfillment integration is mostly a V1 job, with V2 brought in for cross-carrier rates, batch labels and real stock.orderKey upsert and Shopify webhook-id dedup, means a replay during cutover writes once, never twice. The audit trail covers every record from day one.The framework underneath
Every system sits behind the same contract: authenticate, fetch master data, push orders, validate, report. The platform runs in production today against a live enterprise ERP. ShipStation is a registered target on that same framework, its path fully mapped: a V1-first order, store and fulfillment surface with V2 for rating, labels and inventory.
We say this plainly: the credibility is a proven platform and a precisely understood ShipStation path, not years of ShipStation traffic. That distinction is exactly what your fulfillment lead can verify, which is why we lead with it.
The engineering standard
There is no ShipStation case study to borrow, and we will not invent one. What we lead with is the platform's checkable standard, the same platform that runs NetSuite in production, that the ShipStation adapter is built to.
Automated tests across 139 suites, run on every change. Counted in the repository, not rounded for the slide. No code reaches your production data without passing them.
Coverage gate enforced before any deploy.
End-to-end browser tests, Chromium, Firefox, WebKit.
Failure classes, each with its own pre-decided policy.
Credentials stored in plaintext, anywhere, ever.
A real conversation about your stores, your routing, your order volume, and the failure modes you have already hit.