Shopify B2B15 min read

Shopify B2B + ERP Integration: Architecture Patterns That Hold

Webhook-driven vs polling, idempotency, ordering guarantees, and the failure modes you need to design for before your first production deployment.

  • ERP Integration
  • Shopify B2B
  • Webhooks
  • Architecture

Most Shopify ↔ ERP integrations start working and then break in production. Not because the code is wrong — because the architecture doesn't account for the failure modes that only appear at real scale.

01The fundamental problem: at-least-once delivery

Shopify delivers webhooks at least once — which means you can receive the same webhook multiple times. If your integration isn't idempotent, you'll create duplicate orders in your ERP, double-charge customers, and cause inventory discrepancies.

02Idempotency: design it from day one

Every webhook handler must be idempotent. When the same event arrives twice, the second processing should produce the same result as the first — not a duplicate.

typescript
// Store processed webhook IDs to ensure idempotency
async function handleOrderCreated(webhookId: string, payload: OrderPayload) {
  // Check if we've already processed this webhook
  const already = await db.processedWebhooks.findUnique({
    where: { webhookId }
  });
  if (already) return; // Already processed — skip

  // Process in a transaction
  await db.$transaction(async (tx) => {
    await syncOrderToERP(payload);
    await tx.processedWebhooks.create({ data: { webhookId, processedAt: new Date() } });
  });
}

03Webhook vs polling: choose deliberately

  • Webhooks: real-time, efficient, but require reliable infrastructure and idempotency handling
  • Polling: simpler to implement, inherently idempotent if done correctly, but adds latency and wastes API quota
  • Best approach: webhooks as the primary mechanism, polling as a reconciliation job (runs every 15 minutes to catch missed webhooks)

04Ordering guarantees (or lack thereof)

Shopify webhooks can arrive out of order. An order/updated webhook can arrive before the order/created webhook. Design your processing to handle this — check the updated_at timestamp and only process if the incoming data is newer than what you have.

05The reconciliation job

No webhook-based integration is complete without a scheduled reconciliation job. Run a comparison between Shopify and your ERP every 15–60 minutes. Any discrepancies trigger a re-sync. This is your safety net for missed webhooks, failed processing, and ordering issues.

All articles →
Shopify B2B · 12 min readHow Shopify B2B Company Accounts Work — Complete 2026 GuideHeadless & Hydrogen · 6 min readHydrogen Remix Tutorial: Build a Production StorefrontShopify Development · 13 min readShopify Selling Plans API: Building Native Subscriptions Without Third-Party Apps