Direkt zum Inhalt springen
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 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 bis 2.500 €/Monat
Überverkäufe, Stornos, Kundenverlust800 bis 3.000 €/Monat
Unnötige Support-Anfragen500 bis 1.200 €/Monat
Gesamt2.800 bis 6.700 €/Monat

Eine Custom-Integration für 300 bis 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 bis 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 bis 20.000 € Entwicklung)
  • Wartung und Monitoring liegen bei Ihnen
  • Längere Time-to-Market (4 bis 12 Wochen)
  • Erfordert Entwickler-Expertise
KriteriumStandard-ConnectoriPaaS/MiddlewareCustom
BeispieleJTL-Connector, SynestyMake, Celigo, WorkatoEigene Node.js-Middleware
Setup-Zeit1 bis 5 Tage1 bis 4 Wochen4 bis 12 Wochen
Monatliche Kosten50 bis 250 €/Monat200 bis 800 €/Monat200 bis 600 € (Hosting + Wartung)
Einmalkosten0 bis 1.000 €500 bis 3.000 €8.000 bis 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. Es gibt keinen 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, daher 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 bis 5 Tagen konfiguriert. Eine Custom-Middleware benötigt je nach Komplexität 4 bis 12 Wochen Entwicklungszeit. Rechnen Sie zusätzlich 1 bis 2 Wochen für Tests mit echten Daten.

Was kostet eine Shopify ERP-Integration?

Standard-Connectoren kosten 50 bis 250 €/Monat laufend. Custom-Integrations haben Einmalkosten von 8.000 bis 20.000 € Entwicklung und dann 200 bis 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