Entwickler · API v1.0.0

Integration für Shopify-Store-Apps

Dieser Leitfaden richtet sich an Teams, die eine mobile App für ihren Shopify-Store betreiben. Die App kann mit der Storefront API, der Customer Account API oder dem Checkout Kit auf Basis von Expo, React Native, Flutter oder nativ entwickelt worden sein. Die allgemeine API-Referenz finden Sie in der Überblick.

Aufbauend auf der Plattform-Einrichtung beschreibt dieser Leitfaden die Shopify-spezifischen Schritte: Kundenzuordnung, E-Commerce-Attributes, Aktualisierungen aus dem Backend (Webhooks) und die Gestaltung von Kampagnen.

Unterstützte Versionen: Alle unterstützten Versionen der Shopify Storefront API und der Customer Account API (die Beispiele sind mit 2025-01 und neuer kompatibel) · Für die mobile Seite gelten die Versionen aus dem jeweiligen Plattform-Leitfaden.

Wurde Ihre App mit einem No-Code-App-Builder wie Tapcart, Shopney oder Plobal erstellt, müssen Sie für die NotiPilot-Integration eigenen Code in die App einfügen können. Klären Sie mit Ihrem Anbieter, ob die Plattform eigenen Code bzw. ein SDK unterstützt.

1. Zuerst die Plattform-Integration

Richten Sie die Geräteregistrierung passend zur Technologie Ihrer mobilen App ein:

App-Technologie Leitfaden
Expo expo.md
React Native react-native.md
Flutter flutter.md
Ionic / Capacitor ionic.md
Android (Kotlin / Java) kotlin.md · android.md
iOS (Swift / Objective-C) swift.md · ios.md

Nach diesem Schritt sollte jedes Gerät in NotiPilot registriert sein und Sendungen an „Alle Nutzer“ empfangen.

2. Kunden mit dem Gerät verknüpfen

Rufen Sie identify-device auf, sobald sich der Kunde in der App anmeldet. Verwenden Sie als external_id die Shopify-Kunden-ID mit Präfix:

gid://shopify/Customer/7234567890123  →  external_id: "shopify:7234567890123"

Das Präfix (shopify:) verhindert künftige Kollisionen mit Nutzer-IDs aus anderen Quellen.

Kundendaten über die Storefront API abrufen

GraphQL
query Customer($token: String!) {
  customer(customerAccessToken: $token) {
    id
    acceptsMarketing
    defaultAddress { city countryCodeV2 }
  }
}

Wenn Sie die neue Customer Account API verwenden: customer { id defaultAddress { city territoryCode } emailAddress { marketingState } }

identify-device-Aufruf (TypeScript-Beispiel)

TypeScript
async function identifyShopifyCustomer(customer: {
  id: string;
  acceptsMarketing: boolean;
  defaultAddress?: { city?: string | null; countryCodeV2?: string | null } | null;
}) {
  const numericId = customer.id.split('/').pop(); // "gid://shopify/Customer/123" → "123"

  await fetch('https://app.notipilot.com/api/v1/identify-device', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      app_id: 'IHRE-EXPO-PROJEKT-ID',
      device_uid: await getDeviceUid(),          // Funktion aus dem Plattform-Leitfaden
      external_id: `shopify:${numericId}`,
      consent_marketing: customer.acceptsMarketing,
      attributes: {
        customer_type: 'registered',
        country: customer.defaultAddress?.countryCodeV2 ?? null, // "TR"
        city: customer.defaultAddress?.city ?? null,             // "Istanbul"
      },
    }),
  });
}

Wenn sich der Kunde abmeldet, senden Sie die register-device-Anfrage erneut mit "external_id": null und "attributes": { "customer_type": "guest" }.

Wichtig für Standortsegmente: city und countryCodeV2 aus der Standard-Lieferadresse des Kunden sind die zuverlässigste Quelle für Standortsegmente in NotiPilot. Für nicht angemeldete Nutzer sollten Sie zumindest country aus der Geräteregion senden.

3. Empfohlene E-Commerce-Attributes

Das NotiPilot-Dashboard erzeugt für jeden Attribute-Wert automatisch ein Segment. Verwenden Sie daher Felder mit einer begrenzten Anzahl unterschiedlicher Werte und teilen Sie Zahlen in Bereiche ein.

Attribute Beispielwerte Quelle
customer_type guest, registered, vip App / Kunden-Tags
country TR, DE defaultAddress.countryCodeV2
city Istanbul, Izmir defaultAddress.city
locale tr, en Gerätesprache
orders_bucket 0, 1, 2-5, 6+ Backend (Webhook)
spend_bucket 0-500, 500-2000, 2000+ Backend (Webhook)
cart_status empty, active, abandoned App / Backend
last_order_month 2026-09 Backend (Webhook)

❌ Senden Sie keine Werte wie orders_count: 17, total_spent: 1234.56, E-Mail-Adressen oder Telefonnummern: Sie erzeugen entweder eine Vielzahl nutzloser Segmente oder sind personenbezogene Daten.

Das Feld tags können Sie für kurze, aus Kunden-Tags abgeleitete Labels nutzen (z. B. ["vip", "wholesale"]). Wird tags gesendet, ersetzt es die bestehende Liste.

4. Aktualisierung aus dem Backend (Shopify-Webhooks)

Die NotiPilot-API ist eine schlichte HTTP-API; sie kann neben der mobilen App auch aus Ihrem eigenen Backend aufgerufen werden. Speichern Sie dazu den device_uid-Wert bei der Anmeldung des Kunden zusammen mit dem Kunden in Ihrem Backend. Ein Kunde kann mehrere Geräte haben.

Beispiel: Aktualisieren Sie beim Eingang des orders/create-Webhooks alle Geräte des Kunden (Node.js):

JavaScript
app.post('/webhooks/orders-create', verifyShopifyHmac, async (req, res) => {
  const order = req.body;
  const customerId = order.customer?.id;
  if (!customerId) return res.sendStatus(200);

  const ordersCount = order.customer.orders_count ?? 1;
  const bucket = ordersCount >= 6 ? '6+' : ordersCount >= 2 ? '2-5' : String(ordersCount);
  const devices = await db.devicesForCustomer(customerId); // [{ device_uid }, ...]

  await Promise.all(devices.map((d) =>
    fetch('https://app.notipilot.com/api/v1/identify-device', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        app_id: process.env.NOTIPILOT_APP_ID,
        device_uid: d.device_uid,
        external_id: `shopify:${customerId}`,
        attributes: {
          orders_bucket: bucket,
          last_order_month: new Date().toISOString().slice(0, 7),
          cart_status: 'empty',
        },
      }),
    })
  ));

  res.sendStatus(200);
});

Nützliche Webhook-Topics:

Webhook Zu aktualisierende Attributes
orders/create orders_bucket, spend_bucket, last_order_month, cart_status: empty
customers/update city, country, customer_type (anhand der Tags), consent_marketing
checkouts/update cart_status: active

Das Rate Limit liegt bei 300 Anfragen pro Minute und IP-Adresse. Reihen Sie Anfragen bei Massenaktualisierungen in eine Warteschlange ein und warten Sie bei einer 429-Antwort die in retry_after angegebene Zeit ab.

Tragen Sie beim Versand aus dem Dashboard im Feld Data eine Navigationsangabe ein, die Ihre App versteht:

JSON
{ "screen": "product", "handle": "rotes-kleid" }
{ "screen": "collection", "handle": "neue-saison" }
{ "screen": "cart" }

Lesen Sie diese Felder in der App beim Tippen auf die Benachrichtigung aus und leiten Sie zum entsprechenden Screen weiter (siehe die Beispiele zu „Benachrichtigung angetippt“ in den Plattform-Leitfäden). Die Produktseite können Sie über handle aus der Storefront API laden: product(handle: "rotes-kleid") { ... }.

6. Kampagnenbeispiele

Kampagne Segment
Stadtspezifische Versandaktion city: Istanbul
Ankündigung für Kunden im Ausland country: DE, country: NL …
Anreiz zur ersten Bestellung orders_bucket: 0
Rabatt für Stammkunden orders_bucket: 6+ oder customer_type: vip
Warenkorb-Erinnerung cart_status: abandoned

7. Rechtliche Hinweise

  • Übernehmen Sie für Marketing-Benachrichtigungen die Marketing-Einwilligung aus Shopify (acceptsMarketing / marketingState) in das Feld consent_marketing.
  • Legen Sie keine personenbezogenen Daten (E-Mail, Telefonnummer, Adresszeile) in den Attributes ab; verwenden Sie für die Zuordnung ausschließlich external_id.
  • Geht im Rahmen von KVKK/DSGVO bzw. GDPR ein Löschantrag ein, senden Sie für die Geräte des Kunden external_id: null und leeren Sie die betreffenden Attributes mit null.

Checkliste

  • Plattform-Integration abgeschlossen (Geräte sind registriert)
  • Bei der Anmeldung wird identify-device mit external_id: "shopify:<id>" aufgerufen
  • country und city werden aus der Standardadresse gesendet
  • consent_marketing wird aus der Shopify-Marketing-Einwilligung befüllt
  • Zahlenwerte werden in Bereiche (Buckets) eingeteilt
  • (Optional) device_uid wird im Backend gespeichert und per Webhooks aktualisiert