Back to KB
Difficulty
Intermediate
Read Time
5 min

Shopify ERP Integration Architecture: What Breaks in Production and How to Design Around It

By Codcompass TeamΒ·Β·5 min read

Most Shopify ERP integrations fail not because of bad code. They fail because of three architectural decisions made before a single line was written: which system owns which data, how conflicts get resolved, and how partial failures recover without duplication.
Here is the complete production architecture covering all three.

The Non-Negotiable Design Decisions
Before writing any integration code, define these per data domain:

Data Domain

Source of Truth

Sync Direction

Sync Frequency

Inventory levels

ERP

ERP to Shopify

Every 5-15 minutes

Pricing

ERP

ERP to Shopify

Nightly or on change

Product master

ERP

ERP to Shopify

On change

Orders

Shopify

Shopify to ERP

Real-time webhook

Refunds

Shopify

Shopify to ERP

Real-time webhook

Customer addresses

Timestamp

Bidirectional

On change, last write wins

Enforce this in middleware. Do not leave it as an informal convention.

  1. The Three-Layer Middleware Model Direct Shopify-to-ERP integration creates tight coupling. Three explicit middleware tiers prevent it:
js// Layer 1: Ingestion β€” validates and enqueues in under 50ms
app.post('/webhooks/orders', express.raw({ type: '*/*' }), async (req, res) => {
  if (!verifyShopifyHmac(req.body, req.headers['x-shopify-hmac-sha256'])) {
    return res.status(401).send('Unauthorized');
  }

  await ingestionQueue.add('shopify.order.created', {
    raw:       req.body.toString(),
    shop:      req.headers['x-shopify-shop-domain'],
    webhookId: req.headers['x-shopify-webhook-id'],
  });

  res.status(200).send('OK');
});

// Layer 2: Transformation β€” maps Shopify schema to ERP schema
const transformWorker = new Worker('ingestion', async (job) => {
  const shopifyOrder = JSON.parse(job.data.raw);
  const erpOrder     = transformShopifyOrderToERP(shopifyOrder);

  await deliveryQueue.add('erp.order.create', {
    erpPayload:     erpOrder,
    shopifyOrderId: shopifyOrder.id,
    idempotencyKey: `order:${shopifyOrder.id}:${job.data.shop}`,
  });
}, { connection, concurrency: 10 

πŸŽ‰ Mid-Year Sale β€” Unlock Full Article

Base plan from just $4.99/mo or $49/yr

Sign in to read the full article and unlock all 635+ tutorials.

Sign In / Register β€” Start Free Trial

7-day free trial Β· Cancel anytime Β· 30-day money-back