{ }
type
Magento · GraphQL · Checkout · Headless Commerce · Debugging
Cart und Checkout in Magento GraphQL
Architektur, Grenzen und Debugging

Der Checkout-Flow in Magento GraphQL ist komplex: sieben Mutations von der Cart-Erstellung bis zur Bestellplatzierung, session-loses State-Management über die Cart-ID und eine Reihe typischer Fehlerquellen, die ohne gutes Debugging schwer zu lokalisieren sind. Dieser Artikel zeigt, wie der Flow funktioniert, wo seine Grenzen liegen und wie man Fehler systematisch findet.

20 Min. Lesezeit Cart · Mutations · Checkout-Flow · Debugging · Altair · Magento Magento 2.4 · GraphQL · Headless

1. Die Architektur des Magento GraphQL Checkout-Flows

Der Magento GraphQL Checkout-Flow folgt einem sequenziellen, mutations-basierten Modell. Im Gegensatz zu REST-APIs, wo oft ein einziger POST-Request für den gesamten Checkout ausreicht, ist der Magento-GraphQL-Checkout in mehrere separate Mutationen aufgeteilt, die in einer definierten Reihenfolge ausgeführt werden müssen. Das zentrale Konzept dabei: die Cart-ID. Sie ist der einzige Zustandsträger des Checkouts – kein Session-Cookie, keine serverseitige State-Machine, nur die opake Cart-ID, die vom Frontend gespeichert und bei jeder Mutation mitgesendet wird.

Der vollständige Flow umfasst: (1) createEmptyCart – Cart-ID generieren, (2) addSimpleProductsToCart oder Varianten für andere Produkttypen – Produkte hinzufügen, (3) setGuestEmailOnCart für Gäste oder Authentifizierung als Kunde, (4) setShippingAddressesOnCart, (5) setShippingMethodsOnCart, (6) setPaymentMethodOnCart und schließlich (7) placeOrder. Jeder Schritt gibt den aktuellen Cart-Zustand zurück, sodass das Frontend nach jeder Mutation die aktuelle Preisberechnung und Validierungsstatus abrufen kann.

2. Cart erstellen und Produkte hinzufügen

Der erste Schritt jedes Checkouts ist die Cart-Erstellung. createEmptyCart ist eine Mutation ohne Input – sie gibt eine zufällig generierte Cart-ID zurück, die das Frontend persistent speichern muss (localStorage, Session oder State-Management). Für eingeloggte Kunden kann alternativ der Kunden-Cart abgerufen oder erstellt werden. Gäste und eingeloggte Kunden teilen dieselbe Mutation-Struktur, unterscheiden sich aber im Auth-Header: Gäste senden keinen Authorization-Header, eingeloggte Kunden einen Bearer-Token.

Das Hinzufügen von Produkten ist je nach Produkttyp unterschiedlich: addSimpleProductsToCart für einfache Produkte, addConfigurableProductsToCart für konfigurierbare Produkte (mit Parent-SKU und Varianten-SKU), addBundleProductsToCart für Bundle-Produkte. Diese Unterscheidung ist ein häufiger Fallstrick in Headless-Frontend-Entwicklung: wer den falschen Mutations-Typ für einen Produkttyp verwendet, erhält keine hilfreiche Fehlermeldung, sondern oft eine generische Validation-Error-Antwort. Das Frontend muss den Produkttyp kennen und die korrekte Mutation wählen.


# Step 1: Create cart
mutation CreateCart {
  createEmptyCart  # returns cart_id string — store it persistently
}

# Step 2a: Add simple product
mutation AddSimple {
  addSimpleProductsToCart(input: {
    cart_id: "abc123def456"
    cart_items: [{ data: { sku: "24-MB01", quantity: 2 } }]
  }) {
    cart {
      id
      total_quantity
      prices { grand_total { value currency } }
    }
  }
}

# Step 2b: Add configurable product (requires parent + selected variant)
mutation AddConfigurable {
  addConfigurableProductsToCart(input: {
    cart_id: "abc123def456"
    cart_items: [{
      parent_sku: "MH01"
      data: { sku: "MH01-XS-Black", quantity: 1 }
    }]
  }) {
    cart { id total_quantity }
  }
}

3. Versand- und Rechnungsadresse setzen

Die Adresseingabe erfolgt über setShippingAddressesOnCart. Diese Mutation akzeptiert entweder ein vollständiges Adressobjekt oder eine customer_address_id für eingeloggte Kunden, die aus dem Adressbuch wählen. Der Unterschied ist relevant: bei Gästen muss immer das vollständige Adressobjekt übergeben werden, bei Kunden kann alternativ eine gespeicherte Adress-ID verwendet werden. Ein häufiger Fehler: das Pflichtfeld country_code muss ein valides ISO-3166-1-Alpha-2-Land-Kürzel sein (DE, nicht Germany oder Deutschland).

Die Rechnungsadresse kann über setBillingAddressOnCart separat gesetzt oder – über das Flag same_as_shipping: true – identisch zur Lieferadresse definiert werden. Magento berechnet nach dem Setzen der Lieferadresse automatisch verfügbare Versandmethoden. Das bedeutet, dass setShippingAddressesOnCart im Hintergrund bereits Carrier-Plugins aufruft – bei schlecht konfigurierten Carrier-Extensions kann das zu unerwartetem Verhalten oder Performance-Problemen führen, ohne dass im Frontend eine klare Fehlermeldung erscheint.

4. Versandmethoden abrufen und setzen

Nach dem Setzen der Lieferadresse kann der Cart mit einer Query nach verfügbaren Versandmethoden abgefragt werden. Die Mutation setShippingMethodsOnCart erwartet exakt den Carrier-Code und den Methoden-Code aus der verfügbaren Liste – zum Beispiel carrier_code: "flatrate" und method_code: "flatrate". Ein falscher Code führt zu einem Validation-Error ohne weitere Erklärung, welche Codes tatsächlich verfügbar sind. Das Frontend muss deshalb immer zuerst die verfügbaren Methoden aus dem Cart-State lesen und dann die korrekte Kombination senden.

Versandmethoden-Berechnung ist einer der teuersten Schritte im Checkout-Flow. Carrier-Plugins wie DHL, UPS oder Paketdienstleister mit Preislisten-APIs führen teils externe HTTP-Requests aus, um Versandkosten zu berechnen. Das schlägt sich direkt in der Antwortzeit des setShippingAddressesOnCart-Aufrufs nieder. Im Debugging ist das ein wichtiger Indikator: wenn dieser Schritt deutlich länger dauert als andere Mutations, liegt das Problem oft nicht im GraphQL-Layer, sondern in einem langsamen Carrier-Plugin darunter.

5. Zahlungsmethoden und placeOrder

Die verfügbaren Zahlungsmethoden werden aus dem Cart-State gelesen und dann über setPaymentMethodOnCart gesetzt. Der Zahlungsflow unterscheidet sich je nach Zahlungsanbieter erheblich: einfache Methoden wie Banküberweisung oder Rechnung erfordern nur den code-Parameter. Payment-Provider wie PayPal, Stripe oder Klarna erfordern zusätzliche Provider-spezifische Input-Felder und oft einen zweistufigen Prozess: zuerst wird eine Payment-Session initiiert (über eine eigene Mutation oder einen REST-Endpunkt), dann wird der Token in setPaymentMethodOnCart übergeben.

Die letzte Mutation placeOrder ist der kritischste Schritt. Sie gibt eine order_number zurück – oder einen Fehler, wenn eine der vorherigen Bedingungen nicht erfüllt ist. Typische Fehlerszenarien: Lagerstand hat sich zwischen Cart-Erstellung und Bestellplatzierung geändert, Preis hat sich geändert (Regel-Aktualisierung), Zahlungsvalidierung schlägt fehl oder ein Pflichtfeld fehlt. Die Fehlermeldungen von placeOrder sind oft generisch und erfordern Debugging auf Resolver- und Log-Ebene.


# Steps 4-7: Complete checkout flow after shipping address is set

# Check available shipping methods from cart state
query CartWithShipping {
  cart(cart_id: "abc123def456") {
    shipping_addresses {
      available_shipping_methods {
        carrier_code
        method_code
        carrier_title
        amount { value currency }
      }
      selected_shipping_method { carrier_code method_code }
    }
  }
}

# Set shipping method
mutation SetShipping {
  setShippingMethodsOnCart(input: {
    cart_id: "abc123def456"
    shipping_methods: [{ carrier_code: "flatrate", method_code: "flatrate" }]
  }) {
    cart { prices { grand_total { value currency } } }
  }
}

# Set payment method and place order
mutation SetPaymentAndOrder {
  setPaymentMethodOnCart(input: {
    cart_id: "abc123def456"
    payment_method: { code: "checkmo" }
  }) {
    cart { selected_payment_method { code } }
  }
}

mutation PlaceOrder {
  placeOrder(input: { cart_id: "abc123def456" }) {
    order { order_number }
  }
}

6. Architektonische Grenzen des Magento GraphQL Checkouts

Der Magento GraphQL Checkout hat einige strukturelle Grenzen, die in Headless-Projekten zu ernsthaften Einschränkungen werden können. Erstens: komplexe Zahlungsanbieter sind oft nur über hybride Ansätze integrierbar – GraphQL für den Cart-Flow, REST-Endpunkte für provider-spezifische Zahlungs-Handshakes. Das bedeutet, dass ein vollständig GraphQL-basierter Checkout für alle Zahlungsanbieter in Magento noch nicht realistisch ist. Entwickler müssen auf eine Kombination aus GraphQL und REST-Calls vorbereitet sein.

Zweitens: Magento-Erweiterungen, die den traditionellen Checkout über Observer-Events, Plugins und Controller-Overrides anpassen, funktionieren im GraphQL-Checkout nur, wenn sie explizit GraphQL-Support implementiert haben. Drittens: Multi-Shipping-Checkout (verschiedene Produkte an verschiedene Adressen) ist in Magento GraphQL nicht vollständig unterstützt. Und viertens: Custom-Checkout-Steps, die in Luma oder Hyvä über JavaScript-Komponenten gesteuert werden, müssen für GraphQL-Frontends als explizite Mutations neu implementiert werden. Diese Grenzen zu kennen, ist essenziell für eine realistische Projektplanung bei Magento-Headless-Projekten.

7. Debugging-Strategien: Altair, Logs und Query-Analyse

Altair GraphQL Client ist das bevorzugte Tool für Magento-GraphQL-Debugging. Im Gegensatz zu GraphiQL unterstützt Altair HTTP-Headers und Request-Collections – beides essenziell für Checkout-Tests, bei denen Authorization-Token, Content-Type und ggf. Store-View-Header gleichzeitig gesetzt werden müssen. Das Vorgehen beim Checkout-Debugging: jeden Schritt in Altair als eigene Collection-Request abspeichern, Cart-ID als Variable extrahieren und durch alle Schritte durchreichen. So kann jeder Checkout-Schritt isoliert und reproduzierbar getestet werden.

Auf Server-Seite sind die Magento-Logs das wichtigste Debugging-Instrument. Das exception.log zeigt unkontrollierte Exceptions aus Resolvern. Das system.log zeigt Warnungen aus dem Business-Logic-Layer. Für tiefer liegende Probleme – etwa warum eine Versandmethode nicht berechnet wird – lohnt sich das Aktivieren von Magento-Developer-Mode und das temporäre Einbauen von Debug-Logs in die relevanten Carrier-Plugin-Klassen. Ein weiterer hilfreicher Ansatz: den vollständigen Cart-State nach jedem Schritt über eine cart(cart_id: "...")-Query abfragen und mit dem Expected State vergleichen.

8. Typische Fehlerquellen und ihre Lösungen

Die häufigste Fehlerquelle im Magento GraphQL Checkout ist eine inkonsistente Cart-ID: die ID ist abgelaufen, wurde nicht korrekt persistiert oder gehört einer anderen Session. Der Fehler sieht im Frontend aus wie ein generischer Validation-Error, ist aber durch eine neue createEmptyCart-Mutation schnell behoben. Ein weiteres häufiges Problem: ein konfigurierbares Produkt wird mit der Varianten-SKU statt der Parent-SKU in addConfigurableProductsToCart übergeben – das führt zu einem Silent-Failure oder einem generischen Fehler ohne klare Hinweise auf das tatsächliche Problem.

Fehler beim placeOrder-Schritt sind oft schwerer zu debuggen, weil sie von Backend-Validatoren ausgelöst werden, die nicht direkt in der GraphQL-Fehlermeldung sichtbar sind. Das Pattern: nach einem placeOrder-Fehler zuerst das exception.log und system.log prüfen, dann den aktuellen Cart-State abfragen und alle Felder kontrollieren (Adresse vollständig? Versandmethode gesetzt? Zahlungsmethode valide?). Oft liegt das Problem an einer Extensions-Interaktion, die im Log sichtbar ist, aber in der GraphQL-Antwort als generischer Fehler erscheint.


# Diagnostic query: full cart state inspection for debugging
query CartStateInspection {
  cart(cart_id: "abc123def456") {
    id
    email
    is_virtual
    total_quantity
    items {
      id
      quantity
      product { sku name __typename }
    }
    shipping_addresses {
      firstname lastname street city postcode country { code }
      available_shipping_methods { carrier_code method_code amount { value } }
      selected_shipping_method { carrier_code method_code }
    }
    billing_address {
      firstname lastname street city postcode country { code }
    }
    available_payment_methods { code title }
    selected_payment_method { code }
    prices {
      subtotal_excluding_tax { value currency }
      subtotal_including_tax { value currency }
      applied_taxes { amount { value } label }
      grand_total { value currency }
    }
    applied_coupons { code }
  }
}

9. Checkout-Mutations im Überblick

Der Magento GraphQL Checkout-Flow hat eine klare Mutation-Reihenfolge. Abweichungen von dieser Reihenfolge führen zu Fehlern, weil spätere Schritte den Zustand vorheriger Schritte voraussetzen. Die folgende Tabelle zeigt alle Schritte mit Pflichtvoraussetzungen und typischen Fallstricken.

Schritt Mutation Voraussetzung Typischer Fallstrick
1. Cart erstellen createEmptyCart Keine Cart-ID nicht persistent gespeichert
2. Produkte hinzufügen add*ProductsToCart Gültige Cart-ID Falscher Mutations-Typ für Produkttyp
3. Adresse setzen setShippingAddressesOnCart Produkte im Cart country_code als ISO-Code, nicht Text
4. Versandmethode setShippingMethodsOnCart Lieferadresse gesetzt Carrier-Code aus available-Liste entnehmen
5-7. Zahlung + Order setPaymentMethodOnCart + placeOrder Versand gesetzt placeOrder-Fehler in Logs, nicht in Response

Ein besonders wichtiger Aspekt: der Flow gilt für Gäste und Kunden gleichermaßen. Für Kunden kann die Cart mit einem Merge-Schritt verbunden werden: eine Gast-Cart, die durch Login eines Kunden mit einer bestehenden Kunden-Cart zusammengeführt wird. Das geschieht über mergeCarts. Wer diesen Schritt vergisst, verliert die Gast-Cart-Produkte beim Login. Headless-Frontend-Entwickler müssen dieses Szenario explizit implementieren.

Mironsoft

Magento Headless Commerce, GraphQL Checkout und Debugging

Magento GraphQL Checkout zuverlässig zum Laufen bringen?

Wir implementieren und debuggen den vollständigen Magento GraphQL Checkout-Flow für Headless-Frontends – von Cart-Mutations über Zahlungsintegration bis zu systematischem Fehler-Debugging und Extension-Kompatibilität.

Checkout-Implementierung

Vollständiger Checkout-Flow mit Cart, Adresse, Versand und Zahlung implementieren

Debugging & Analyse

Fehlerquellen in Resolver-Ketten, Carrier-Plugins und Zahlungs-Extensions lokalisieren

Extension-Kompatibilität

Checkout-Extensions auf GraphQL-Support prüfen und fehlende Mutations implementieren

10. Zusammenfassung

Cart und Checkout in Magento GraphQL folgen einem klar definierten, mutations-basierten Flow mit der Cart-ID als einzigem Zustandsträger. Das Modell ist elegant und ermöglicht vollständig session-losen Checkout – aber es erfordert, dass Frontend-Entwickler jeden Schritt kennen, die richtigen Mutations für Produkttypen wählen und mit den architektonischen Grenzen des Magento-GraphQL-Checkouts umgehen können.

Debugging ist entscheidend: Altair für isolierte Schritt-Tests, Magento-Logs für Backend-Fehler, die in der GraphQL-Response nicht sichtbar sind, und diagnostische Cart-Queries für vollständige Zustandsinspektion. Wer die typischen Fallstricke kennt – falsche Produkttyp-Mutations, ISO-Ländercodes, Carrier-Code-Kompatibilität und placeOrder-Fehler im Log – kann den Magento GraphQL Checkout zuverlässig implementieren und debuggen. Die Grenzen des Checkouts – komplexe Zahlungsanbieter, nicht-GraphQL-kompatible Extensions, Multi-Shipping – müssen in der Projektplanung realistisch einkalkuliert werden.

Magento GraphQL Checkout — Das Wichtigste auf einen Blick

Cart-ID als Zustandsträger

Einziger State-Träger des Checkouts. Persistent im Frontend speichern. Ablauf oder Verlust bricht den gesamten Flow. mergeCarts für Gast-zu-Kunde-Übergang.

Produkttyp-Mutations

Unterschiedliche Mutations für Simple, Configurable, Bundle, Virtual. Falscher Typ führt zu generischem Fehler. Frontend muss __typename des Produkts kennen.

Debugging-Strategie

Altair für isolierte Schritt-Tests. Cart-State-Query nach jedem Schritt zur Inspektion. exception.log und system.log für placeOrder-Fehler prüfen.

Architektonische Grenzen

Komplexe Zahlungsanbieter: oft Hybrid-Ansatz nötig. Nicht-GraphQL-Extensions: kein automatischer Support. Multi-Shipping: nicht vollständig unterstützt.

11. FAQ: Cart und Checkout in Magento GraphQL

1Wie viele Mutations braucht der Checkout?
Mindestens sieben: createEmptyCart, add*ProductsToCart, setGuestEmailOnCart, setShippingAddressesOnCart, setShippingMethodsOnCart, setPaymentMethodOnCart, placeOrder.
2Was passiert mit der Gast-Cart beim Login?
Sie geht verloren ohne explizites mergeCarts. Diese Mutation muss beim Login implementiert werden um Produkte zu erhalten.
3Warum schlägt addConfigurableProductsToCart fehl?
Oft vertauschte parent_sku und data.sku. parent_sku muss das konfigurierbare Produkt sein, data.sku die gewählte Variante.
4Wie debugge ich einen placeOrder-Fehler?
exception.log und system.log prüfen. Vollständigen Cart-State inspizieren: Adresse, Versand und Zahlung alle korrekt gesetzt?
5Alle Zahlungsanbieter über GraphQL?
Nicht alle. Komplexe Anbieter wie PayPal oder Stripe erfordern oft Hybrid-Ansatz: GraphQL für Cart-Flow, REST für Provider-Handshake.
6Bestes Tool für Checkout-Debugging?
Altair GraphQL Client – unterstützt HTTP-Headers und Request-Collections. Jeden Schritt als eigenen Request speichern, Cart-ID als Variable durchreichen.
7Warum ist setShippingAddressesOnCart langsam?
Carrier-Plugins berechnen Versandkosten – manche mit externen HTTP-Requests. Problem liegt meist im Carrier-Plugin, nicht im GraphQL-Layer.
8Checkout-Extensions im GraphQL-Checkout?
Nur wenn explizit GraphQL-Support implementiert. JS-Komponenten-basierte Extensions haben keinen automatischen Effekt auf den GraphQL-Flow.
9Cart-Status während des Debuggings prüfen?
Mit cart(cart_id: ...) Query alle Felder abfragen: items, shipping_addresses, billing_address, available_payment_methods, prices, applied_coupons.
10Wichtigste Checkout-Praxisregel?
Mutations-Reihenfolge strikt einhalten, Cart-State nach jedem Schritt inspizieren. placeOrder-Fehler haben ihre Ursache fast immer in einem früheren Schritt.