ERP integration · UK Distributor

Bidirectional Shopify ↔ NetSuite Integration

A UK industrial distributor with 8,000 SKUs and 150+ trade accounts was running Shopify and NetSuite as completely separate systems. Orders were re-keyed twice daily. Inventory mismatches caused weekly oversell incidents. We built a production-grade bidirectional integration.

Role
Architecture and full-stack development
Stack
Node.js, NetSuite REST API, Shopify Admin API, GraphQL, Webhooks, Redis, PostgreSQL, Sentry
shopify-erp-netsuite-integration — project screenshot
SKUs synced in real time
8k
Manual re-keying steps
0
Integration uptime (6 months)
99.8%

The problem

The operations team was exporting orders from Shopify twice daily and manually importing them into NetSuite. Inventory levels in NetSuite were being manually copied to Shopify weekly — meaning Shopify inventory was always 3–7 days out of date. Oversell incidents were frequent and expensive to resolve with trade customers who depended on stock accuracy for their own production planning.

The technical challenge

NetSuite's REST API has strict rate limits and inconsistent response times — a synchronous webhook handler that calls NetSuite directly would time out regularly. The integration needed to be observable at every step. Idempotency was critical: Shopify delivers webhooks at least once, and duplicate orders in NetSuite are extremely difficult to clean up.

How it was built

  1. 01

    Webhook queue architecture

    Shopify order webhooks land in a Redis queue rather than being processed synchronously. A Bull worker processes the queue at a rate that respects NetSuite's API limits. Webhook receipt returns 200 immediately — no timeout risk.

  2. 02

    Idempotent order creation

    Every order is stored in PostgreSQL with its Shopify order ID before being sent to NetSuite. Duplicate webhook deliveries check this table first and skip processing if already handled. NetSuite's ExternalId field is set to the Shopify order ID for further deduplication.

  3. 03

    Inventory sync

    NetSuite inventory levels are fetched via Saved Search every 15 minutes during business hours. Changes are detected by comparing against the previous sync snapshot. Only changed SKUs are updated in Shopify using the bulk inventory mutation.

  4. 04

    Observability layer

    Every sync run is logged with record count, duration, and status. Sentry captures all exceptions with the original payload. A simple admin dashboard shows the last 50 sync runs with error details — no log access needed for the operations team.

Results

Manual re-keying was eliminated on day one. Inventory accuracy improved from a 3–7 day lag to 15-minute updates during business hours, eliminating oversell incidents entirely in the first 6 months. The integration has maintained 99.8% uptime over 6 months — the only downtime was a planned NetSuite maintenance window.

B2B & wholesaleB2B Wholesale Portal with Company-Specific Pricing
Custom appsProduct Configurator App with Real-Time Pricing

Have a project like this?

Tell me what you're building and I'll tell you exactly how I'd approach it.

Discuss a Project →