Skip to content
EcomOps
IntegrationsShopify PlusNetSuiteCeligo

The complete Shopify ↔ NetSuite architecture guide

Every data flow, every edge case, with Celigo flow diagrams and failure recovery patterns that survive Black Friday.

Dmytro Perederii
4 min read

Every quarter, a $30M+ Shopify Plus brand lands in my inbox with some version of the same message: "NetSuite is out of sync with Shopify. Finance is angry. We don't know what's actually in the warehouse."

The diagnosis is almost always the same, too. Someone — usually an agency, usually three years ago — wired up a Celigo template, ticked the "Shopify to NetSuite" box, and shipped it on a Friday. It worked in dev. It held up in the first quarter. And then Black Friday happened, or the catalog tripled, or a new 3PL joined, and the seams split.

This post is the architecture I wish every one of those teams had when they started.

The three flows that matter

Pretty much every Shopify ↔ NetSuite integration boils down to three flows. Everything else is a variation.

  1. Order flow — Shopify order → NetSuite sales order → NetSuite invoice
  2. Inventory flow — NetSuite item availability → Shopify variant inventory
  3. Customer flow — Shopify customer → NetSuite customer record (with dedupe)

If you don't have clean answers for each of these three, you don't have an integration. You have a liability.

The order flow

The canonical path:

flows/order.ts
// High-level contract
async function onShopifyOrderCreate(order: ShopifyOrder) {
  // 1. Upsert customer in NetSuite first (FK requirement)
  const customer = await upsertNetSuiteCustomer(order.customer);

  // 2. Map line items → NetSuite items by SKU
  const items = await mapLineItems(order.line_items);

  // 3. Create sales order idempotently
  return await createOrUpdateSalesOrder({
    externalId: order.id.toString(),
    customer: customer.internalId,
    items,
    tranDate: order.processed_at,
  });
}

The trap most teams fall into: they treat this as a fire-and-forget webhook handler. That's fine when everything's healthy. It's a catastrophe when NetSuite is in read-only mode during month-end close and a dozen orders silently die in a dead-letter queue nobody monitors.

What "survives Black Friday" actually means

I use a simple 4-point test for any production integration:

  • Idempotent. Re-running the same event twice produces the same state once.
  • Observable. Every message has a trace ID that lets you follow it from Shopify to NetSuite in under 60 seconds.
  • Recoverable. When something fails, there's a documented runbook, not a Slack thread with "has anyone seen this?"
  • Bounded. Failure in one flow cannot block the other two.

If you can't draw your integration on a whiteboard in under five minutes, your customers will eventually experience it as outages.

Me, to every founder, every time

A concrete failure pattern

Here's the one that bites newer teams:

The fix isn't "run the flow more often" — that just papers over the timing gap and raises your NetSuite API usage toward the governance limit. The fix is to put Shopify's own inventory as the authoritative source during a sale window and reconcile after.

The reference architecture

Shopify Plus  ──┐                   ┌── NetSuite ERP
                │                   │
                └─► Celigo iPaaS ◄──┘
                        │
            ┌───────────┼───────────┐
            │           │           │
        Order Flow  Inventory Flow  Customer Flow
            │           │           │
          Idempotent  Reconcile   Dedupe by email
          on event    every 15m   + phone

Three rules this architecture enforces that most templated installs don't:

RuleWhy it matters
Every flow has its own error queueOne bad record doesn't freeze the rest
Every message carries a trace_idOps can follow it end-to-end in logs
Customer upserts run before order createsAvoids NetSuite FK failures

What I'd skip

If I had to cut the project to its bones and still ship something useful in two weeks, I'd cut inventory reconciliation and customer dedup refinement. Do the order flow right, wire up observability, and add the others in week 3 and 4.

The piece you cannot skip is the trace ID. Everything else is a feature. The trace ID is the thing that turns a 4am incident from a panic into a ticket.

Next up

In the next post I'll walk through the Celigo flow-level config I actually use: retry policy, saved-search cadence, and the three scripted lookups I add to every deploy.

If your stack is closer to "we don't know what state we're in" than "we have this wired up well," that's exactly the conversation a stack audit exists for.

// newsletter

Ship smarter integrations.

One architectural breakdown every Friday. Shopify Plus, NetSuite, Celigo, AI. No fluff.

No spam. Unsubscribe in one click.