ERP-IntegrationShopify APIWebhooksAutomatisierung

Shopify ERP-Integration: Technischer Leitfaden für DACH-Händler

JTL, Xentral, WeClapp oder SAP mit Shopify verbinden — Webhook-Architektur, GraphQL Admin API 2026-01, Fehlerbehandlung und konkrete Code-Beispiele für stabile ERP-Anbindungen.

Justin KreutzmannJustin Kreutzmann16 min Lesezeit

Morgens um 7:14 Uhr zeigt Ihr ERP 38 Stück — Shopify zeigt 51. Um 7:42 Uhr bestellt ein Kunde 45 Stück. Shopify nimmt die Bestellung an. Ihr Lager kann sie nicht erfüllen. Was folgt: eine Storno-Mail, ein verlorener Kunde und ein Support-Ticket, das niemand gebraucht hätte.

Das ist kein Ausnahmefall. Das ist der Alltag von Shopify-Händlern, deren ERP und Shop nicht sauber miteinander sprechen. Und je mehr Kanäle Sie bespielen — Shopify, Amazon, stationärer Handel — desto explosiver wird das Problem.

In diesem Guide zeige ich Ihnen den technischen Weg zu einer stabilen ERP-Integration: Welches System zu welchem Setup passt, wie die Webhook-Architektur aussieht, was die Shopify GraphQL Admin API 2026-01 Neues bringt — und welche konkreten Code-Muster sich in der Praxis bewährt haben.

Das Wichtigste in Kürze

  • Die Shopify Admin API 2026-01 erlaubt bis zu fünf parallele Bulk-Mutations — entscheidend für Bestandsabgleiche bei großen Katalogen.
  • JTL ist Marktführer im DACH-Raum; seit Januar 2026 läuft die Installation ausschließlich über den offiziellen Shopify App Store.
  • Webhook-basierte Event-Driven-Architektur mit Queue ist Pflicht — Polling als tägliches Safety-Net ergänzend.
  • Idempotente Verarbeitung verhindert Doppelbuchungen bei Shopify-Webhook-Retries (bis zu 19 Versuche in 48 Stunden).
  • Absolute statt relative Bestandswerte eliminieren die häufigste Quelle für Bestandsdiskrepanzen.
  • Eine tägliche Reconciliation ist kein Nice-to-have — sie ist das einzige zuverlässige Netz unter der Integration.

Warum fehlende ERP-Integration so teuer ist

Ohne saubere Verbindung zwischen Shopify und Ihrem ERP entstehen drei Kostentreiber, die sich monatlich summieren:

ProblemKosten (ca. 500 Bestellungen/Monat)
Manuelle Dateneingabe (45 Min/Tag × Stundensatz)1.500–2.500 €/Monat
Überverkäufe, Stornos, Kundenverlust800–3.000 €/Monat
Unnötige Support-Anfragen500–1.200 €/Monat
Gesamt2.800–6.700 €/Monat

Eine Custom-Integration für 300–600 € Hosting- und Wartungskosten pro Monat amortisiert sich bei 200+ Bestellungen monatlich bereits im ersten Quartal.

Die 3 Integrations-Ansätze im Vergleich

Standard-Connector (JTL, Synesty)

  • Schnellste Time-to-Market (1–5 Tage)
  • Kein Entwicklerwissen nötig
  • Bewährte Mappings für Standard-ERPs
  • Regelmäßige Updates durch Anbieter

Custom-Middleware (Node.js/Python)

  • Höhere Initialkosten (8.000–20.000 € Entwicklung)
  • Wartung und Monitoring liegen bei Ihnen
  • Längere Time-to-Market (4–12 Wochen)
  • Erfordert Entwickler-Expertise
KriteriumStandard-ConnectoriPaaS/MiddlewareCustom
BeispieleJTL-Connector, SynestyMake, Celigo, WorkatoEigene Node.js-Middleware
Setup-Zeit1–5 Tage1–4 Wochen4–12 Wochen
Monatliche Kosten50–250 €/Monat200–800 €/Monat200–600 € (Hosting + Wartung)
Einmalkosten0–1.000 €500–3.000 €8.000–20.000 €
Geeignet fürStandard-Flows, < 500 SKUsMulti-System, moderate LogikHohe Volumina, Eigenlogik

ERP-Systeme im DACH-Raum: Überblick 2026

Laut einer Marktanalyse von digitalsprung.de dominieren im deutschsprachigen Raum folgende Systeme:

SystemTypShopify-AnbindungStärke
JTL-WawiWaWiOffizieller App-Store-Connector (seit 01/2026)Marktführer DACH, WMS-Integration
XentralERP + WaWiREST API + nativer ConnectorDATEV-Anbindung, Multichannel
WeClappERP + WaWiREST API, eigener ConnectorOnboarding, Cloud-nativ
BillbeeWaWiNativer Shopify-ConnectorEinsteiger, schnelles Setup
SAP Business OneERPService Layer REST APIMittelstand, Komplettlösung
MS Dynamics BCERPOData v4 REST APIMicrosoft-Ökosystem

Welche Daten werden synchronisiert?

Eine vollständige Integration umfasst fünf Datendomänen — die Synchronisationsrichtung ist dabei entscheidend:

DatendomäneRichtungHäufigkeitPriorität
LagerbeständeERP → ShopifyNear-Realtime (< 5 Min)Kritisch
BestellungenShopify → ERPEchtzeit (Webhook)Kritisch
Fulfillment/TrackingERP → ShopifyBei VersandHoch
Produkte & PreiseERP → ShopifyBei Änderung / täglichHoch
RetourenBidirektionalBei EreignisHoch

Technische Architektur: Webhooks + Queue

Die robusteste Architektur kombiniert Event-Driven Webhooks mit einer Queue und einem täglichen Reconciliation-Job.

Warum Queue statt direkter Verarbeitung?

Shopify erwartet eine HTTP-200-Antwort innerhalb von 5 Sekunden. Dauert Ihre ERP-Verarbeitung länger, markiert Shopify den Webhook als fehlgeschlagen und wiederholt — bis zu 19 Mal über 48 Stunden. Ohne Queue landen Sie in einer Retry-Spirale.

webhook-handler.js
import { Queue } from 'bullmq';
import { createHmac, timingSafeEqual } from 'crypto';
 
const orderQueue = new Queue('shopify-orders', {
  connection: { host: process.env.REDIS_HOST, port: 6379 }
});
 
// HMAC-Verifizierung — immer zuerst
function verifyWebhook(rawBody, hmacHeader) {
  const digest = createHmac('sha256', process.env.SHOPIFY_WEBHOOK_SECRET)
    .update(rawBody, 'utf8')
    .digest('base64');
  try {
    return timingSafeEqual(Buffer.from(digest), Buffer.from(hmacHeader));
  } catch {
    return false;
  }
}
 
app.post('/webhooks/orders/create', async (req, res) => {
  // 1. Authentizität prüfen
  if (!verifyWebhook(req.rawBody, req.headers['x-shopify-hmac-sha256'])) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
 
  // 2. Sofort in Queue — nicht inline verarbeiten
  await orderQueue.add('process-order', {
    orderId: req.body.id,
    orderName: req.body.name,
    payload: req.body,
    webhookId: req.headers['x-shopify-webhook-id'],
  }, {
    attempts: 5,
    backoff: { type: 'exponential', delay: 5000 },
  });
 
  // 3. Sofort 200 zurückgeben
  res.status(200).send('OK');
});

Idempotenz: Doppelte Verarbeitung verhindern

Shopify kann denselben Webhook mehrfach senden. Ohne Idempotenz buchen Sie Bestellungen doppelt ins ERP.

idempotent-handler.js
// In Produktion: Redis SETNX statt Map
const processed = new Map();
 
async function handleIdempotent(webhookId, topic, handler) {
  const key = `${topic}:${webhookId}`;
  if (processed.has(key)) {
    return { skipped: true };
  }
  processed.set(key, Date.now());
  try {
    return await handler();
  } catch (err) {
    processed.delete(key); // Retry ermöglichen
    throw err;
  }
}

Bestandssync: Absolut statt relativ

inventory-sync.graphql
# Admin API 2026-01: Bestand absolut setzen
mutation inventorySetQuantities($input: InventorySetQuantitiesInput!) {
  inventorySetQuantities(input: $input) {
    inventoryAdjustmentGroup {
      reason
      changes {
        name
        delta
        quantityAfterChange
      }
    }
    userErrors {
      field
      message
      code
    }
  }
}
sync-inventory.js
// Absolute Werte — nie relative Deltas verwenden
async function syncStock(sku, erpQty, locationId) {
  const variables = {
    input: {
      reason: 'correction',
      referenceDocumentUri: `erp://sync/${Date.now()}`,
      quantities: [{
        inventoryItemId: await resolveInventoryItemId(sku),
        locationId,
        quantity: erpQty, // Absoluter Wert aus ERP
      }],
    },
  };
  return shopifyGraphQL(INVENTORY_SET_MUTATION, variables);
}

Fulfillment zurückmelden

Wenn das WMS den Versand bucht, muss Shopify die Tracking-Nummer erhalten:

fulfillment-create.graphql
mutation fulfillmentCreateV2($fulfillment: FulfillmentV2Input!) {
  fulfillmentCreateV2(fulfillment: $fulfillment) {
    fulfillment {
      id
      status
      trackingInfo {
        number
        url
        company
      }
    }
    userErrors {
      field
      message
    }
  }
}
push-fulfillment.js
async function pushFulfillment(fulfillmentOrderId, tracking) {
  return shopifyGraphQL(FULFILLMENT_CREATE_MUTATION, {
    fulfillment: {
      lineItemsByFulfillmentOrder: [{ fulfillmentOrderId }],
      trackingInfo: {
        number: tracking.trackingNumber,
        url: tracking.trackingUrl,
        company: tracking.carrier, // z.B. "DHL", "DPD", "GLS"
      },
      notifyCustomer: true,
    },
  });
}

Admin API 2026-01: Was ist neu?

Die Admin API Version 2026-01 bringt für ERP-Integrationen relevante Änderungen:

5x
Parallele Bulk Mutations (vorher: 1)Admin API 2026-01
500 Pkt/s
Rate Limit auf Shopify Plusvs. 50 Pkt/s auf Basic
100 MB
Max. JSONL-Dateigrösse je Bulk-OperationShopify Docs 2026

Für Bulk-Preisänderungen oder Massenbestandsupdates lohnt sich jetzt der Wechsel auf bulkOperationRunMutation:

bulk-inventory-update.graphql
# Bulk-Operation: Tausende SKUs in einem Job
mutation {
  bulkOperationRunMutation(
    mutation: """
      mutation inventorySet($input: InventorySetQuantitiesInput!) {
        inventorySetQuantities(input: $input) {
          inventoryAdjustmentGroup { reason }
          userErrors { field message }
        }
      }
    """,
    stagedUploadPath: "tmp/inventory-update.jsonl"
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}

Webhook-Konfiguration und Retry-Verhalten

Pflicht-Webhooks für jede ERP-Integration

register-webhooks.js
const WEBHOOKS = [
  { topic: 'ORDERS_CREATE',         handler: '/webhooks/orders/create' },
  { topic: 'ORDERS_UPDATED',        handler: '/webhooks/orders/updated' },
  { topic: 'ORDERS_CANCELLED',      handler: '/webhooks/orders/cancelled' },
  { topic: 'REFUNDS_CREATE',        handler: '/webhooks/refunds/create' },
  { topic: 'INVENTORY_LEVELS_UPDATE', handler: '/webhooks/inventory/update' },
  { topic: 'FULFILLMENTS_CREATE',   handler: '/webhooks/fulfillments/create' },
  // DSGVO-Pflicht für App-Store-Apps
  { topic: 'CUSTOMERS_DATA_REQUEST', handler: '/webhooks/gdpr/data-request' },
  { topic: 'CUSTOMERS_REDACT',      handler: '/webhooks/gdpr/redact' },
  { topic: 'SHOP_REDACT',           handler: '/webhooks/gdpr/shop-redact' },
];

Retry-Zeitplan (Shopify sendet bis zu 19 Mal)

VersuchWartezeitKumuliert
1Sofort0
25 Sek5 s
35 Min~5 Min
430 Min~35 Min
52 Stunden~2,5 Std
6+bis 48 StdMax. 19 Versuche

Nach 48 Stunden ohne Erfolg wird der Webhook automatisch und still deaktiviert — kein Alert von Shopify. Deshalb ist eigenes Monitoring unverzichtbar.

Fehlerbehandlung und Monitoring

Dead-Letter-Queue

Wenn ein Job nach allen Retries fehlschlägt, gehört er in eine Dead-Letter-Queue — nicht ins Nirvana:

worker-with-dlq.js
import { Queue, Worker } from 'bullmq';
 
const dlq = new Queue('shopify-orders-dlq');
 
const worker = new Worker('shopify-orders', async (job) => {
  await processOrderForERP(job.data);
}, {
  connection: { host: process.env.REDIS_HOST, port: 6379 },
  concurrency: 5,
});
 
worker.on('failed', async (job, err) => {
  if (job.attemptsMade >= job.opts.attempts) {
    await dlq.add('failed', {
      original: job.data,
      error: err.message,
      failedAt: new Date().toISOString(),
    });
    await alertCritical('ORDER_SYNC_FAILED', job.data.orderName, err.message);
  }
});

Tägliche Reconciliation (Safety Net)

reconciliation.js
async function dailyReconciliation() {
  const since = new Date(Date.now() - 86_400_000).toISOString();
 
  // Bestellungen der letzten 24h aus beiden Systemen
  const [shopifyOrders, erpOrders] = await Promise.all([
    fetchShopifyOrders(since),
    fetchERPOrders(since),
  ]);
 
  const erpNumbers = new Set(erpOrders.map(o => o.externalOrderId));
  const missing = shopifyOrders.filter(o => !erpNumbers.has(o.name));
 
  if (missing.length > 0) {
    // Fehlende Bestellungen mit hoher Priorität nachsynchronisieren
    for (const order of missing) {
      await orderQueue.add('reconcile', { payload: order }, { priority: 1 });
    }
    await alertHigh('RECONCILIATION_GAP', `${missing.length} Bestellungen nachsynchronisiert`);
  }
}
// Täglich um 03:00 Uhr per Cron

ERP-spezifische Hinweise (DACH)

JTL-Wawi

Seit Januar 2026 läuft die Shopify-Anbindung ausschließlich über den offiziellen JTL-Shopify-Connector im App Store. Custom Apps für JTL sind nicht mehr neu erstellbar. Das JTL-WMS mit Barcode-Scanner-Unterstützung ist Standard in vielen mittelständischen Lagern.

Xentral

Xentral bietet eine saubere REST-API mit guter Dokumentation. Stärke: native DATEV-Anbindung und GoBD-konforme Archivierung — wichtig für Steuerberater und Jahresabschluss.

WeClapp

Cloud-natives ERP mit gutem persönlichen Onboarding. API-Token-Authentifizierung. Für Händler, die ohne Agentur starten wollen, einer der zugänglichsten Einstiege.

Billbee

Eigener nativer Shopify-Connector bereits vorhanden. Custom-API-Nutzung lohnt sich nur, wenn Sie Bestellungen vor dem Import filtern oder anreichern müssen (z.B. B2B-Kunden anders behandeln).

SAP Business One

Seit Version 10: Service Layer REST API. Ältere Versionen: DI API (COM-basiert) oder Integration Framework. Wichtig: Sessions laufen nach 30 Minuten ab — automatisches Re-Login implementieren.

Kostenvergleich: 3-Jahres-Perspektive

Für einen Shop mit ca. 1.000 Bestellungen/Monat:

AnsatzJahr 1Jahr 2Jahr 33 Jahre gesamt
Standard-Connector3.500 €2.100 €2.100 €7.700 €
iPaaS (Celigo/Make)11.500 €8.400 €8.400 €28.300 €
Custom-Middleware14.000 €4.800 €4.800 €23.600 €

Die Custom-Lösung überholt den iPaaS-Ansatz bereits im zweiten Jahr. Bei stark wachsendem Volumen werden iPaaS-Kosten überproportional teurer (Preis pro Operation).

Checkliste vor dem Projektstart

  1. Technische Voraussetzungen klären

    API-Dokumentation des ERPs beschaffen und prüfen (REST? Version? Auth-Verfahren?). Shopify Admin API Access Token mit korrekten Scopes einrichten: read_orders, write_inventory, read_products, write_fulfillments. Netzwerk-Konnektivität prüfen — On-Premise-ERPs brauchen oft VPN oder Tunnel.

  2. Datenhoheit definieren

    Klären: Welches System ist Master für welche Daten? Das ERP ist typischerweise Product Master und Inventory Master. Shopify ist Order Master. Erstellen Sie ein Mapping-Dokument — welches Shopify-Feld fließt in welches ERP-Feld?

  3. Testumgebung aufbauen

    Shopify Development Store einrichten. ERP-Sandbox oder Testsystem bereitstellen. Mindestens 20 Testbestellungen mit Sonderfällen vorbereiten: B2B, internationale Adressen, Teillieferungen, Retouren.

  4. Monitoring konfigurieren

    Dashboard für Sync-Status einrichten (wie viele Jobs laufen, wie viele schlagen fehl?). Alerting für kritische Szenarien: fehlgeschlagene Bestellübertragung, Webhook-Endpunkt nicht erreichbar, Bestandssync-Verzögerung über 15 Minuten. Reconciliation-Job planen.

  5. Rollback-Plan definieren

    Wie schalten Sie bei einem Ausfall auf den manuellen Prozess zurück? Wer wird benachrichtigt? Was ist die maximale tolerierbare Ausfallzeit?

Fazit: Der richtige Ansatz für Ihre Situation

Eine ERP-Integration ist kein einmaliges Projekt — sie ist ein lebendes System, das mit Ihrem Business wächst. Die Entscheidung für den richtigen Ansatz hängt von drei Faktoren ab: Bestellvolumen, Systemkomplexität und langfristiger Kostenperspektive.

Standard-Connector (JTL, Synesty): Wenn Sie ein gängiges DACH-ERP haben, Standard-Prozesse leben und unter 500 Bestellungen/Tag bleiben.

Custom-Middleware: Wenn Sie komplexe Geschäftslogik haben, über 1.000 Bestellungen/Tag verarbeiten oder langfristig Kosten gegenüber iPaaS einsparen wollen.

Mein Rat: Starten Sie mit dem einfachsten Ansatz, der Ihre Anforderungen zu 80 % erfüllt — und bauen Sie gezielt aus, wenn Sie an die Grenzen stoßen.

Häufige Fragen

Welches ERP-System eignet sich am besten für Shopify im DACH-Raum?

JTL-Wawi ist nach Installationszahlen Marktführer im deutschsprachigen Raum — besonders für Händler mit Lagerbetrieb. Billbee ist ideal für den schnellen Einstieg ohne Agentur. Xentral und WeClapp eignen sich wenn DATEV-Anbindung und ERP-Funktionen (Buchhaltung, CRM) gebraucht werden. SAP Business One und Microsoft Dynamics BC sind für komplexen Mittelstand.

Wie lange dauert eine ERP-Integration mit Shopify?

Ein Standard-Connector wie JTL ist in 1–5 Tagen konfiguriert. Eine Custom-Middleware benötigt je nach Komplexität 4–12 Wochen Entwicklungszeit. Rechnen Sie zusätzlich 1–2 Wochen für Tests mit echten Daten.

Was kostet eine Shopify ERP-Integration?

Standard-Connectoren kosten 50–250 €/Monat laufend. Custom-Integrations haben Einmalkosten von 8.000–20.000 € Entwicklung und dann 200–600 €/Monat für Hosting und Wartung. Über 3 Jahre ist Custom meist günstiger als iPaaS-Plattformen.

Warum schlagen meine Shopify-Webhooks manchmal fehl?

Die häufigsten Ursachen: (1) Ihre Verarbeitung dauert länger als 5 Sekunden — Lösung: Queue. (2) Der Server ist kurzzeitig nicht erreichbar — Shopify retries bis zu 19 Mal. (3) HMAC-Verifizierung schlägt fehl, weil der Raw Body geparsed wurde. Implementieren Sie immer Idempotenz und ein Monitoring-Dashboard.

Muss ich für eine Custom-Integration Shopify Plus haben?

Nein. Die Shopify Admin API und Webhooks sind auf allen Plänen verfügbar. Shopify Plus bietet höhere Rate Limits (500 Punkte/Sekunde statt 50) und ist bei Volumen über 2.000 Bestellungen/Tag relevant — für die meisten Mittelständler ist das kein Thema.

Wie verhindere ich Überverkäufe bei der Bestandssynchronisation?

Drei Maßnahmen: (1) Near-Realtime-Sync unter 5 Minuten für schnelldrehende Artikel. (2) Absolute statt relative Bestandswerte. (3) Sicherheitspuffer im ERP konfigurieren — z.B. Shopify-Bestand = ERP-Bestand minus 5 % als Reserve gegen Race Conditions.

Weiterführende Artikel

Teilen
Justin Kreutzmann

Geschrieben von

Justin Kreutzmann

Shopify-Entwickler für Custom Apps, ERP-Integrationen und Prozessautomatisierung. Ich helfe Marken, technische Grenzen zu überwinden — mit Lösungen, die im Alltag von Händlern wirklich funktionieren.

Projekt anfragen