Shopware Universal Commerce Protocol einrichten

Shopwares Agentic-Commerce-Erweiterung ist seit einigen Wochen verfügbar. Ich habe sie auf einem echten Shop installiert, einen simulierten Agenten daraufgesetzt und zugesehen, wie eine Bestellung entstand. Es funktioniert. Von der Installation bis zu dieser ersten Bestellung waren drei Korrekturen nötig, auf die einen nichts in der Dokumentation vorbereitet.

Das Shopware Universal Commerce Protocol ist die spannende Hälfte dieses Plugins. Es ist der Vertrag, über den ein KI-Shopping-Agent Ihren Katalog durchsucht, einen Warenkorb aufbaut und einen Checkout abschliesst, ohne Browser und ohne dass Ihre Storefront jemals rendert.

Hier ist, was tatsächlich passiert ist, inklusive der Stelle, an der das Geld nicht ankommt.

Was das Shopware Universal Commerce Protocol Plugin wirklich macht

Das Plugin bündelt drei Funktionen, über die meist als eine geredet wird. Sie sind unabhängig voneinander:

  • UCP, die transaktionale Oberfläche. REST-, A2A- und Embedded-Endpunkte unter /ucp/v1/, dazu ein öffentliches Profil unter /.well-known/ucp, das die unterstützten Fähigkeiten beschreibt. Das ruft ein Agent auf, um etwas zu kaufen.
  • Native Agentic Discovery. /llms.txt, /agents.md und /.well-known/ai-catalog.json sagen Crawlern und Shopping-Agenten, wie der Händler seinen Shop genutzt haben möchte. In 6.7 kommen diese Dateien aus dem Core, je Verkaufskanal.
  • Produktfeeds. OpenAI-JSONL und Google-Merchant-XML auf Basis des Shopware-Produktexports. Die Produktlinks tragen referringSalesChannel sowie konfigurierte Affiliate- und Kampagnencodes, sodass zurückkommende Bestellungen zuordenbar sind.

Ein Händler kann Feeds und Discovery-Dokumente betreiben, ohne UCP je nach aussen zu öffnen. Genau dort sollten die meisten anfangen. Diese Seite habe ich in was Agentic Commerce für die Sichtbarkeit Ihres Shops bedeutet beschrieben, hier geht es um die Technik darunter.

Wie Sie das Agentic-Commerce-Plugin installieren

Es liegt nicht auf Packagist. Die Anfrage nach shopware/agentic-commerce bei repo.packagist.org liefert einen 404, was mich überrascht hat, da das Plugin öffentlich auf GitHub liegt. Die Verteilung läuft über den Shopware Store oder die Release-ZIPs an jedem GitHub-Tag.

Die Installation ist also ein ZIP-Upload unter Erweiterungen oder ein Entpacken nach custom/plugins/ samt bin/console plugin:install --activate SwagAgenticCommerce. Das Plugin deklariert ucp-php-sdk/symfony-bundle als harte Abhängigkeit und zieht sie über die Composer-Befehle des Plugins während der Installation. Auf Managed Hosting, das Composer zur Laufzeit blockiert, gehört diese Abhängigkeit stattdessen fest in den Build.

Meine Testumgebung war Shopware 6.7.13.0 auf ddev mit PHP 8.4. Die Installation führte sechs Migrationen aus, das SDK legte sechs eigene Tabellen für Signing Keys, Idempotenz-Datensätze, Replay-Nonces und OAuth-State an, und das Admin-Bundle kompilierte über Vite ohne Murren. Dieser Teil war langweilig, und genau das will man.

Drei Dinge blockierten meine erste UCP-Agent-Anfrage

Jedes davon erzeugte eine Fehlermeldung, die auf etwas anderes zeigte als auf die Ursache.

Nur Storefront-Kanäle beantworten Agent-Traffic

Der Shop hatte bereits einen Agentic-Commerce-Verkaufskanal, also habe ich UCP dort aktiviert. Jede Anfrage an dessen Host kam als HTTP 400 zurück, mit einer Seite namens “Shopware Domain Mapping Misconfiguration”.

Der Grund sitzt im Shopware-Core, nicht im Plugin. Der DomainLoader der Storefront baut seine Host-Zuordnung mit genau einem Filter:

$query->where('sales_channel.type_id = UNHEX(:typeId)');
$query->setParameter('typeId', Defaults::SALES_CHANNEL_TYPE_STOREFRONT);

Jeder Host, der zu einem Kanal eines anderen Typs gehört, ist für den Request-Transformer der Storefront unbekannt, und die UCP-Routen laufen nie an. Nur /api- und /store-api-Pfade überspringen diesen Transformer, und /ucp/v1/ ist keines von beiden.

Ein UCP-Kanal muss also ein Storefront-Kanal mit öffentlicher HTTPS-Domain sein. Ein zusätzlicher Hostname allein hilft nicht. Ich habe die Diagnose belegt, indem ich den Kanaltyp umgestellt habe und dieselbe URL ohne weitere Änderung von 400 auf 200 sprang.

Die UCP-Einstellungen liegen auf dem Kanaltyp, der nicht ausliefern kann

Das ist der Punkt, den ich einen Konstruktionswiderspruch nennen würde. Die Agentic-Commerce-Oberflächen des Plugins, inklusive der UCP-Freigabe, rendern nur, wenn der geöffnete Verkaufskanal vom Typ Agentic Commerce ist:

isAgenticCommerce() {
    return this.salesChannel.typeId === Defaults.agenticCommerceTypeId;
}

Der Kanaltyp, den Sie im Backend konfigurieren können, ist der, den Shopware nicht ausliefert. Der Kanaltyp, der funktioniert, hat gar keine UCP-Oberfläche.

Die CLI schliesst die Lücke ebenfalls nicht. ucp:config:set deckt Signature Policy, Allowlists und Delivery-URLs ab, und der eigene Hilfetext sagt, dass die Freigabefelder im Backend bleiben. Um UCP für einen Storefront-Kanal einzuschalten, musste ich die Admin-API direkt aufrufen:

PUT /api/_admin/ucp/sales-channels/{salesChannelId}/config
{"active": true, "profileDomain": "https://shop.example.com",
 "enabledTransports": ["rest", "a2a", "embedded"]}

Dieser Endpunkt braucht die ACL ucp.editor. Gut zu wissen, bevor Sie einem Kunden ein Setup per Mausklick versprechen.

Das SDK weist jeden lokalen Hostnamen ab

Mit aktivierter Freigabe veröffentlichte /.well-known/ucp endlich Transporte und Capabilities. Der erste Laufzeitaufruf scheiterte trotzdem:

Profile host "shop.ddev.site" resolves to a blocked IP address.

Jede UCP-Anfrage trägt einen UCP-Agent-Header mit der Profil-URL des Agenten, und der Shop lädt dieses Profil, um an dessen Signing Keys zu kommen. Der UrlSafetyValidator des SDK weist jeden Host ab, der auf eine private Adresse auflöst, also jeden ddev- oder lokalen Hostnamen. Zwei Details machen das strenger, als es zuerst aussieht:

  • Die Blocked-IP-Prüfung läuft vor der Allowlist-Prüfung, das Eintragen des eigenen Hosts in remoteProfileAllowlist ändert also nichts.
  • Die Entwickler-Ausnahme akzeptiert nur ein wörtliches localhost, und auch nur, wenn ucp_sdk.profile_fetching_development_mode in der Bundle-Konfiguration aktiv ist.

Das Plugin übergibt dieses Flag beim Aufbau seiner Runtime-Konfiguration nie, es lässt sich also gar nicht pro Verkaufskanal setzen. Lokal brauchen Sie eine Konfigurationsdatei auf Projektebene, abgesichert, damit sie nie in Produktion landet:

# config/packages/ucp_sdk.yaml
when@dev:
    ucp_sdk:
        profile_fetching_development_mode: true

Auf einem Live-Shop mit öffentlicher Domain spielt das alles keine Rolle. Echte Agent-Plattformen haben öffentliche Profil-Hosts, und der Schutz tut seine Arbeit. Er beisst nur während der lokalen Entwicklung, also genau dann, wenn Sie die Sache gerade lernen wollen.

Wie eine echte Agent-Bestellung aussieht

Sind die drei Punkte erledigt, ist der Ablauf angenehm schlicht. Jeder Aufruf braucht den UCP-Agent-Header und einen eindeutigen Idempotency-Key:

curl -X POST https://shop.example.com/ucp/v1/catalog/search \
  -H 'content-type: application/json' \
  -H 'UCP-Agent: my-agent; profile="https://agent.example.com/.well-known/ucp"' \
  -H "Idempotency-Key: $(openssl rand -hex 8)" \
  -d '{"query":"linen","limit":2}'

Die Suche liefert Produkte mit Preisen in kleinster Währungseinheit und Bild-URLs. Danach folgen POST /ucp/v1/checkout-sessions mit Line Items, Käufer und Lieferadresse und schliesslich POST /ucp/v1/checkout-sessions/{id}/complete. Die Session wechselt von ready_for_complete auf completed, und im Backend liegt eine echte Shopware-Bestellung mit echter Bestellnummer.

Zwei Details lohnen sich zu merken:

  • Der Shop gewinnt beim Preis. Ich habe im Line Item bewusst falsche 777,63 übergeben. Die Bestellung kam mit 304,81 heraus, dem Preis des Shops. Vom Agenten gelieferte Preise sind ein Vorschlag, was korrekt ist und jedem Händler gesagt gehört, der fragt, ob ein Agent den Preis herunterhandeln kann.
  • Idempotenz wird durchgesetzt, nicht dekoriert. Ein wiederverwendeter Key mit anderem Request-Body liefert idempotency_conflict als nicht behebbaren Fehler. Jeder Client braucht frische Keys pro Anfrage.

Wie werden Agent-Checkouts bezahlt?

Diese Frage gehört geklärt, bevor jemand das einem Kunden verkauft, und die ehrliche Antwort lautet: Der Agent zahlt nicht. Als ich einen Checkout über REST abgeschlossen habe, kam die Bestellung mit einer Transaktion im Status open gegen CashPayment an, die Standardzahlart des Kanals. Also eine unbezahlte Rechnungsbestellung.

Der tokenisierte Weg, bei dem ein Agent Zahlungsdaten übergibt und der Shop belastet, ist nicht enthalten. POST /ucp/v1/tokenize antwortet mit 501, und die Plugin-Dokumentation ist deutlich, warum: Es liefert bewusst keinen Schein-Tokenizer aus. Der einzige mitgelieferte Handler ist ShopwareInvoicePaymentHandler, und der gibt bei supportsTokenization() ein false zurück. Für echte Tokenisierung braucht es einen PHP-Service, der Ucp\Sdk\Contract\PaymentHandlerInterface implementiert, mit ucp_sdk.payment_handler getaggt ist und aus einem Payment-Plugin kommt.

Dieses Tag ist wichtiger, als es aussieht. Es ist ein PHP-Service-Tag, der Handler muss also aus einem Plugin kommen. Shopware Payments wird als App ausgeliefert, die per HTTP mit Shopware spricht, und eine App kann keinen PHP-Service registrieren, also auch diesen Handler nicht liefern.

Was funktioniert, ist die Übergabe. Der Embedded-Transport rendert eine Übersichtsseite von Warenkorb oder Checkout mit einem Button “Continue checkout”, der Ihre konfigurierte Continue-URL im obersten Frame öffnet:

{% if data.continue_url is defined and data.continue_url is not empty %}
    <a class="cta" target="_top" href="{{ data.continue_url }}">Continue checkout</a>
{% endif %}

Der Käufer schliesst im Checkout des Shops mit den Zahlarten des Shops ab, Shopware Payments eingeschlossen, und die Bestellung wird bezahlt wie jede andere. Setzen Sie --continue-url-template auf dem Kanal, erlauben Sie den Origin der Agent-Plattform für den Iframe, und dieser Weg steht.

Die Aussage, die Sie treffen können, lautet also: Agenten finden den Katalog, bauen einen Warenkorb und übergeben den Käufer an den Checkout. Die Aussage, die Sie vermeiden sollten, ist autonomes Einkaufen durch Agenten.

Die Testsuiten des Plugins ausführen

Das Plugin bringt Unit-, Integrations- und Functional-Tests mit, und die Functional-Suite treibt die UCP-Routen durch einen gebooteten Kernel bis zu einer echten Bestellung. Auf einer Installation nach shopware/production läuft davon zunächst nichts.

Das Bootstrap ermittelt das Projektverzeichnis aus den Composer-Metadaten, ohne den Pfad zu normalisieren:

$corePath = InstalledVersions::getInstallPath('shopware/core');
// /var/www/html/vendor/composer/../shopware/core
$projectDir = dirname($corePath, 3);
// /var/www/html/vendor/composer   <- falsch

Ein realpath() auf diesen Wert repariert es. Shopwares eigene CI sieht den Fehler nie, weil dort Monorepo-Checkouts laufen, bei denen der Pfad auf /src/Core endet und den anderen Zweig dieses dirname() nimmt. Nach der Korrektur laufen alle drei Suiten durch: 579 Unit-Tests, 2 Integrationstests und 7 Functional-Tests, darunter ein Checkout, der zu einer Bestellung wird und wieder ausgelesen wird.

Eine Warnung vorab. Das Kernel-Bootstrap führt system:install --create-database --force aus, sobald es keine Plugin-Tabelle findet, und APP_ENV=test lässt Symfony .env.local überspringen, wo ddev Ihre Datenbank-URL hinterlegt. Richten Sie diese Suite ausdrücklich auf eine Wegwerf-Datenbank, sonst installiert sie über Ihren Arbeits-Shop.

Was das für Ihren Shopware-Shop bedeutet

Der Termin ist der Grund zu handeln, nicht der Trend. Shopware 6.7 lieferte Agentic Commerce im Core aus, 6.7.12.0 verschob es in die Erweiterung, und das Core-Backend zeigt Händlern jetzt diesen Hinweis: Die eingebaute Funktion wird in 6.8 entfernt, die Erweiterung muss installiert werden, damit nichts bricht. Jeder Shop, der die Funktion aktiviert hat, hat Migrationsarbeit an seinem nächsten Hauptversions-Update hängen.

Darüber hinaus ist die sinnvolle Reihenfolge:

  • Feeds und Discovery zuerst. Günstig zu konfigurieren, keine Protokoll-Freigabe nötig, und die Attributionscodes in den Feed-Links zeigen, ob etwas dabei herumkommt.
  • Agent-Checkout danach, mit eingerichteter und getesteter Zahlungsübergabe, sobald der Shop einen Grund dafür hat.
  • Nichts vor den Zahlen. Das SDK steht bei Version 0.0.5. Vor 1.0 heisst Breaking Changes, planen Sie also einen zweiten Durchgang ein statt einer einmaligen Installation.

Jede freigegebene Fähigkeit ist ein Endpunkt, den Bots ansteuern können. Signature Policy, Agent-Allowlists und Embedded-Origins sind Konfiguration, die Sie tatsächlich vornehmen müssen, keine Voreinstellung, die Sie erben.

Wenn Sie das auf einem Live-Shop sauber eingerichtet haben möchten oder eine ehrliche Einschätzung brauchen, ob es sich für Ihren Katalog lohnt: Schreiben Sie mir oder sehen Sie sich die Case Studies an.

Häufige Fragen

Was ist das Universal Commerce Protocol in Shopware? UCP ist der Transaktionsvertrag, über den ein KI-Shopping-Agent einen Katalog durchsucht, einen Warenkorb aufbaut und einen Checkout abschliesst, per HTTP statt über einen Browser. In Shopware kommt es über die kostenlose Erweiterung Agentic Commerce, die Katalog, Cart, Checkout und Bestellverarbeitung an das ucp-php-sdk anbindet. Der Shop veröffentlicht seine Fähigkeiten unter /.well-known/ucp.

Welche Shopware-Versionen unterstützt das Agentic-Commerce-Plugin? 6.5, 6.6 und 6.7 aus einer Codebasis, mit Feature-Erkennung zur Laufzeit statt toter Links. Shopware 6.7.10 hatte die Funktion kurzzeitig im Core, 6.7.12.0 verschob sie in die Erweiterung, und das Backend warnt jetzt vor der Entfernung in 6.8.

Wie installiere ich das Shopware Agentic Commerce Plugin? Es liegt nicht auf Packagist. Laden Sie SwagAgenticCommerce.zip von der GitHub-Releases-Seite oder installieren Sie Agentic Commerce aus dem Shopware Store und laden Sie es unter Erweiterungen hoch. Shopware führt bei der Installation die Composer-Befehle des Plugins aus, um das UCP SDK zu holen.

Kann ein KI-Agent in Shopware eine Bestellung bezahlen? Heute nicht eigenständig. Ein abgeschlossener UCP-Checkout erzeugt eine echte Bestellung, aber die Transaktion landet im Status open auf der Standardzahlart, und /ucp/v1/tokenize antwortet mit 501, weil kein Tokenisierungs-Handler mitgeliefert wird. Der funktionierende Weg ist die Embedded-Übergabe, bei der der Käufer im Checkout des Shops abschliesst und jede Zahlart inklusive Shopware Payments kassiert.

Welchen Verkaufskanal nutze ich für UCP? Einen Storefront-Kanal mit öffentlicher HTTPS-Domain. Der DomainLoader der Storefront ordnet nur Domains von Storefront-Kanälen zu, jeder andere Host endet auf der Domain-Mapping-Fehlerseite, bevor UCP-Routen laufen. Der Kanaltyp Agentic Commerce ist für Produktfeed und Tracking gedacht.

Ist Shopwares UCP-Umsetzung produktionsreif? Discovery-Dokumente und Produktfeeds können Sie ausrollen. Die transaktionale Seite läuft auf ucp-php-sdk 0.0.5, also vor 1.0 und mit Breaking Changes zu rechnen, und braucht vorher Entscheidungen zu Zahlung, Betrugsprävention und Support.

Artikel teilen

Fanden Sie das hilfreich? Teilen Sie es mit Ihrem Netzwerk

Huzaifa Mustafa

Huzaifa Mustafa

Shopware 6 zertifizierter Entwickler mit 166+ individuellen Plugins und 97+ Kunden in der DACH-Region. Ich schreibe über Shopware-Architektur, E-Commerce-Performance und Erfahrungen aus realen Projekten.

Brauchen Sie Hilfe mit Shopware?

Lassen Sie uns besprechen, wie ich bei Ihrem E-Commerce-Projekt helfen kann.