---
title: "Eine Shopify-Flow-Integration bauen: Trigger, Aktionen und die Fallen, die uns einen Zyklus kosteten"
description: "Trigger- und Aktions-Feldschlüssel folgen entgegengesetzten Schreibweisen, und jedes Trigger-Feld ist Pflicht - zwei Fallen, die uns einen Zyklus kosteten."
url: "https://www.quotway.com/de/blog/building-a-shopify-flow-integration"
type: "blog post"
category: "Engineering"
published: "2026-07-04"
updated: "2026-10-07"
verified: "2026-10-07"
shopify_api_version: "2026-10"
audience: "Shopify-App-Entwickler, die Flow-Trigger, -Aktionen und -Vorlagen bauen"
scope: "Eine Flow-App-Integration in API 2026-10: die Erweiterungen für Trigger, Aktion und Vorlage, die gegenläufigen Schreibweisen der Schlüssel, der Vertrag „alle Felder erforderlich“ sowie die Deploy- und Debug-Fallen aus unserem eigenen Bau"
locale: "de"
source: "QuotWay - B2B Quote & Negotiation App for Shopify"
---

# Eine Shopify-Flow-Integration bauen: Trigger, Aktionen und die Fallen, die uns einen Zyklus kosteten

**Kurzfassung:** Eine Shopify-Flow-Integration hat drei bewegliche Teile – **Trigger** (Ereignisse, die Ihre App in Flow ausgibt), **Aktionen** (Schritte, mit denen Flow in Ihre App zurückruft) und **Vorlagen** (fertige Workflows). Die Konfigurationen der Erweiterungen sind schlichtes TOML; die Fallen stecken in den undokumentierten Regeln der Plattform. Die beiden, die uns einen echten Debugging-Zyklus kosteten: **Feldschlüssel von Triggern und Aktionen folgen entgegengesetzten Schreibweisen**, und **jedes Feld, das Sie an einem Trigger deklarieren, ist in jedem Payload Pflicht** – ein „optionales Referenzfeld“ ist also ein Widerspruch, der Gast-Ereignisse still zerbricht. Hier die vollständige Landkarte, aus dem Ausliefern von 10 Triggern, 3 Aktionen und 6 Vorlagen in [QuotWay](/features/shopify-flow).

## Was eine Flow-Integration ist (und wer sie nutzen kann)

[Shopify Flow](https://shopify.dev/docs/apps/build/flow) ist Shopifys No-Code-Baukasten für Automatisierung. Ihre App klinkt sich auf drei Wegen ein:

- **Trigger** (`flow_trigger`) – Ihre App gibt ein Ereignis aus („Angebot eingereicht“), und Händler bauen Workflows, die damit beginnen.
- **Aktionen** (`flow_action`) – ein Flow-Workflow ruft Ihre App auf, damit sie etwas *tut* („Angebotsstatus aktualisieren“), und übergibt Felder, die die Händlerin konfiguriert hat.
- **Vorlagen** (`flow_template`) – vorgefertigte Workflows, die in der Flow-Vorlagengalerie erscheinen, sodass Händler mit einem funktionierenden Beispiel statt einer leeren Leinwand starten.

Ein Mythos, den man zuerst töten sollte: **Flow ist für app-seitige Erweiterungen nicht Plus-exklusiv.** Trigger und Aktionen einer öffentlichen App-Store-App stehen Händlern in **jedem kostenpflichtigen Shopify-Tarif** zur Verfügung, nicht nur in Plus. (Von Händlern selbst geschriebene Flow-Workflows haben eigene Tarifregeln, das ist aber unabhängig von der *Verfügbarkeit* Ihrer Erweiterungen.) Wir grenzen unsere durch die Paketierung ab – Trigger in unserer Professional-Stufe, Aktionen in Enterprise – nicht, weil die Plattform es erzwingt.

## Der dreiteilige Aufbau

Jeder Trigger, jede Aktion und jede Vorlage ist ein eigenes Erweiterungsverzeichnis mit einer `shopify.extension.toml`. Es gibt kein gemeinsames „Flow-App“-Objekt – Sie setzen die Integration aus vielen kleinen Erweiterungen zusammen.

### Trigger: Ihre App → Flow

Ein Trigger deklariert einen Namen und eine Reihe von Feldern, die zu den verfügbaren Daten des Workflows werden. Feldschlüssel sind der **öffentliche Payload-Vertrag**:

```toml
# extensions/flow-quote-submitted/shopify.extension.toml
[[extensions]]
type = "flow_trigger"
name = "Quote submitted"
handle = "quote-submitted"

  [[settings.fields]]
  type = "single_line_text_field"
  key = "Quote id"            # ← Title Case, mit Leerzeichen

  [[settings.fields]]
  type = "number_decimal"
  key = "Total amount"        # Händler ergänzen Bedingungen wie "Total amount >= X"

  [[settings.fields]]
  type = "single_line_text_field"
  key = "Customer id"         # LEERER String bei Gästen — siehe Falle 2
```

Sie geben ein Ereignis aus, indem Sie die Mutation `flowTriggerReceive` mit dem Trigger-Handle und einem Payload aufrufen, dessen Schlüssel exakt diesen Feldnamen entsprechen. Wir geben aus einem kleinen Dienst `flow/emit` bei jedem Zustandswechsel aus (eingereicht, Angebot gesendet, angenommen, gekontert, abgelehnt, abgelaufen, umgewandelt und die drei Freigabeereignisse – insgesamt 10).

### Aktionen: Flow → Ihre App

Eine Aktion deklariert die Felder, die eine Händlerin ausfüllt, und eine `runtime_url`, an die Flow beim Ausführen des Schritts POSTet. Wir leiten **alle** Aktionen an einen Endpunkt und verteilen nach Handle:

```toml
# extensions/flow-update-quote-status/shopify.extension.toml
[[extensions]]
type = "flow_action"
name = "Update quote status"
handle = "update-quote-status"
runtime_url = "/api/flow/action"     # ein Endpunkt für jede Aktion
validation_url = "/api/flow/validate" # Feldprüfung beim Speichern
schema = "./schema.graphql"
return_type_ref = "QuoteActionResult"

  [[settings.fields]]
  type = "single_line_text_field"
  key = "quote_id"            # ← snake_case (das Gegenteil von Triggern!)
  required = true

  [[settings.fields]]
  type = "single_line_text_field"
  key = "target_status"       # IN_REVIEW | DECLINED | EXPIRED
  required = true
```

Der Handler unter `/api/flow/action` prüft Shopifys HMAC, verteilt nach Aktions-Handle, ist **idempotent bezogen auf `action_run_id`** (Flow kann erneut versuchen) und gibt ein typisiertes Ergebnis passend zu `return_type_ref` zurück. Wir haben drei Aktionen ausgeliefert: Status aktualisieren, eine Benachrichtigung senden und einer Mitarbeiterin zuweisen – jede am Eingang des Dienstes auf Enterprise begrenzt, nicht an der Route.

### Vorlagen: ein funktionierender Ausgangspunkt

Erweiterungen vom Typ `flow_template` bündeln eine `.flow`-Datei (die Workflow-Definition) samt Lokalisierungstexten. So bekommt eine Händlerin „Wenn ein hochwertiges Angebot eintrifft, poste nach Slack“, ohne es selbst zu verdrahten. Wir haben sechs ausgeliefert. Der Haken: Vorlagen erscheinen erst **nach Prüfung durch das Flow-Team** in der Galerie (ein paar Werktage), sie laufen also auf einer anderen Uhr als der Rest Ihrer App.

## Die Fallen (jede davon eine Narbe)

| Falle | Was Sie beißt | Die Lösung |
|---|---|---|
| **Entgegengesetzte Schreibweise der Schlüssel** | Feldschlüssel von Triggern sind `Title Case With Spaces` („Total amount“); Feldschlüssel von Aktionen sind `snake_case` (`quote_id`). Verwechseln Sie sie, binden die Felder nie. | Merken Sie sich die Teilung: Trigger Title Case, Aktionen snake_case. |
| **Alle Trigger-Felder sind Pflicht** | Jedes Feld, das Sie deklarieren, **muss** in **jedem** Payload vorhanden sein. Ein „optionales Referenzfeld“ ist ein Widerspruch – lassen Sie es einmal weg (etwa bei einem Gastangebot ohne Kundin), wird das ganze Ereignis abgelehnt. | Nutzen Sie einfache Textfelder, die `""` sein dürfen, statt Referenzfeldern; lassen Sie Händler in Flow mit „ist nicht leer“ verzweigen. |
| **Konfigurationsseiten können nicht speichern** | App-seitige Konfigurationsseiten für einen Schritt sind **nur lesend** – `intent.finish({properties})` ist wirkungslos (von Shopify-Mitarbeitenden bestätigt). Eine eigene Auswahl-Oberfläche kann ihre Auswahl nie sichern. | Nutzen Sie native `[[settings.fields]]` plus eine `validation_url`, die schlechte Werte beim Speichern ablehnt. |
| **Lebenszyklus-Rückrufe sind eine eigene Erweiterung** | Eine `flow_trigger`-Erweiterung allein sagt Ihnen nicht, wer zuhört. Flow meldet das Ein- und Ausschalten von Workflows nur über eine separate `flow_trigger_lifecycle_callback`-Erweiterung, und sobald Sie eine hinzufügen, kann ein Händler einen Workflow nur aktivieren, wenn Ihr Endpunkt innerhalb von fünf Sekunden mit einem `2xx` antwortet. Koppeln Sie das Ausgeben an Abonnement-Datensätze, die Sie nie bekommen, schlägt es **geschlossen** fehl – niemand bekommt Ereignisse. | Geben Sie entweder für **jeden berechtigten Shop** aus, wie wir es tun, oder fügen Sie die Lebenszyklus-Rückruf-Erweiterung hinzu und halten Sie ihren Endpunkt schnell und erreichbar. |
| **`.flow`-Dateien prüfen sich selbst** | Vorlagendateien tragen einen SHA-256-Abdruck ihrer selbst und sind Exporte aus dem Editor. Bearbeiten Sie eine von Hand, wird sie abgelehnt. | Bearbeiten Sie `.flow` nie von Hand; exportieren Sie neu aus dem Flow-Editor und lassen Sie händlerspezifische Felder leer. `preInstallNote` steht in der Lokalisierungs-JSON, nicht im TOML. |
| **Schema-Änderungen brauchen ein abgestimmtes Release** | Ändern Sie die Felder eines Triggers, müssen Ihre ausgegebenen Payloads zum *ausgelieferten* Schema passen. Deployen Sie die Erweiterung ohne den Emitter (oder umgekehrt), wird jedes Ereignis abgelehnt. | Gemeinsam ausliefern: `shopify app deploy` **und** Ihr Backend-Push im Gleichschritt. |
| **Typen sind streng** | `number_decimal` muss eine JSON-**Zahl** sein, kein String; ein Feld vom Typ `*_reference` will die **numerische Legacy-ID**, nicht die GID. | Wandeln Sie an der Ausgabegrenze um; bevorzugen Sie einfache Felder gegenüber Referenzfeldern (siehe Falle 2). |

*Korrigiert am 7. Oktober 2026:* Die Zeile zu Lebenszyklus-Rückrufen sagte zuvor, dass in TOML definierte Trigger keine Rückrufe zum An- und Abmelden bekommen und dass `flowTriggerReceive` nichts tut, wenn niemand zuhört. Shopify dokumentierte Lebenszyklus-Rückrufe bereits als eigene CLI-Erweiterung, als dieser Beitrag entstand, und dokumentiert das Nichtstun nicht, also sagt die Zeile jetzt, was der [Leitfaden zu Lebenszyklus-Ereignissen](https://shopify.dev/docs/apps/build/flow/track-lifecycle-events) sagt.

Die ersten beiden haben uns Debugging-Zeit in Produktion gekostet. „Alle Felder sind Pflicht“ ist besonders hinterhältig, weil es nur die *Teilmenge* der Ereignisse zerbricht, denen ein Feld fehlt – bei uns Gastangebote (ohne Kunden-ID) und ein paar Randfälle – es sieht also nach einem sporadischen Fehler aus, bis Sie merken, dass er strukturell ist.

## Flow in Produktion debuggen

Flow-Fehler sind leise – ein abgelehnter Payload erreicht die Händlerin nicht. Protokollieren Sie beide Seiten der Grenze und suchen Sie danach:

- **Ausgabeseite:** Protokollieren Sie bei Erfolg ein `flow.emit.sent` und ein `flow.emit.user_errors`, wenn `flowTriggerReceive` userErrors zurückgibt (eine Schema-Abweichung taucht hier auf).
- **Aktionsseite:** Protokollieren Sie das verteilte Handle, die `action_run_id` und das Ergebnis. HMAC-Fehler und Kurzschlüsse durch Idempotenz sollten je eine Zeile hinterlassen.

Wenn ein Trigger „nicht auslöst“, prüfen Sie zuerst das Ausgabeprotokoll: Sehen Sie `sent` ohne Fehler, wurde der Payload angenommen und das Problem liegt im Workflow der Händlerin; sehen Sie `user_errors`, passt Ihr Payload nicht zum ausgelieferten Trigger-Schema (fast immer Falle 6).

## Ein vernünftiger erster Meilenstein

1. **Ein Trigger** für Ihr wichtigstes Ereignis, mit nur den Feldern, die ein Workflow tatsächlich braucht (weniger Felder = weniger Pflichtfeld-Fallen). Schlüssel in Title Case.
2. Geben Sie ihn für jeden berechtigten Shop aus Ihrem bestehenden Code für Zustandswechsel aus – ohne Abonnement-Abgrenzung.
3. **Eine Aktion**, die an eine einzige `runtime_url` POSTet, nach Handle verteilt wird, HMAC-geprüft und idempotent bezogen auf `action_run_id` ist, mit einer `validation_url` statt einer Konfigurationsseite.
4. Deployen Sie Erweiterung und Backend **gemeinsam** und prüfen Sie es in einem Entwicklungsshop mit einem echten Workflow.
5. Ergänzen Sie Vorlagen zuletzt – sie hängen an der Prüfung durch das Flow-Team, lassen Sie sie also nicht den Start von Triggern und Aktionen blockieren.

Trigger und Aktionen sind einzeln klein; die Schwierigkeit der Integration liegt ganz in den obigen Plattformregeln. Bringen Sie die Schreibweise und den Pflichtfeld-Vertrag am ersten Tag in Ordnung, und der Rest ist das Verdrahten von Ereignissen, die Sie ohnehin schon ausgeben.

Wenn Sie Händler statt Entwickler sind: Die hier beschriebene Integration steckt in QuotWay als [Shopify-Flow-Trigger und -Aktionen](/features/shopify-flow), ab Professional – siehe [Tarife und Preise](/pricing). Systeme außerhalb von Shopify, etwa ein ERP, ein CRM oder ein Headless-Shop, binden Sie stattdessen über die [QuotWay API und Webhooks](/features/api-webhooks) im Enterprise-Tarif an; [sechs Beispielintegrationen](/blog/quotway-api-webhooks-recipes) zeigen, welche Events und Endpunkte jede davon nutzt.

## Weiterführendes

Am 7. Oktober 2026 erneut gegen Shopifys Seiten geprüft; die Fallstricke oben stammen aus unserem eigenen Bau, und die Zeile zu Lebenszyklus-Rückrufen wurde an diesem Tag gegen Shopifys [Leitfaden zu Lebenszyklus-Ereignissen](https://shopify.dev/docs/apps/build/flow/track-lifecycle-events) korrigiert:

- Shopify: [Flow für App-Entwickler](https://shopify.dev/docs/apps/build/flow), [Trigger](https://shopify.dev/docs/apps/build/flow/triggers), [Aktionen](https://shopify.dev/docs/apps/build/flow/actions), [Vorlagen](https://shopify.dev/docs/apps/build/flow/templates)
- Shopify Help Center: [Shopify Flow](https://help.shopify.com/en/manual/shopify-flow) – Flow ist auf Basic, Grow, Advanced und Plus kostenlos, weshalb die Trigger und Aktionen einer App jeden kostenpflichtigen Tarif erreichen
- Schwesterbeitrag: [Eine Shopify-Sidekick-App-Erweiterung bauen](/blog/building-shopify-sidekick-app-extensions)
- Wofür die Trigger auf Händlerseite da sind: [ERP-, CRM- und PIM-Anbindung für Shopify-B2B-Angebote](/blog/shopify-b2b-erp-crm-pim-integration-patterns)
