All articles
Shopify B2B15 min read20 June 2026

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 IntegrationShopify B2BWebhooksArchitecture

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.

The 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.

Idempotency: 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() } });
  });
}

Webhook 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)

Ordering 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.

The 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.

ShareLinkedInX / Twitter
Arslan
Shopify developer specializing in B2B, Shopify Plus, and custom app development. 6+ years building on Shopify.
About

Building something like this on Shopify?

I build exactly what I write about. If you need help implementing this, get in touch — I respond within 24 hours.

Discuss your project

Get new Shopify guides by email

Practical, technical articles on Shopify development — no fluff, no sales emails.

No spam. Unsubscribe anytime.