B2B-Onlineshop von Grund auf bauen

Diese Anleitung führt Sie durch den Aufbau einer öffentlichen Workspace-Storefront. Sie richtet sich an Entwickler, die einen B2B-Onlineshop, ein Kundenportal oder eine Shop-ähnliche Bestellstrecke ohne interne Produktunterlagen umsetzen.

Nutzen Sie diese Seite, wenn Sie einen Onlineshop für Hersteller, technischen Großhandel oder B2B-Vertrieb bauen und dafür öffentliche Workspace-Verträge nutzen möchten. Nach dem Lesen kennen Sie die Reihenfolge für Katalog, Preise, Warenkorb, Checkout, Login, Firmenzugang, Angebotsanfrage und Storefront- Erweiterungen.

Ziel

Bauen Sie eine Storefront, die nur öffentliche Verträge nutzt:

  • Site-Kontext laden
  • veröffentlichte Produkte suchen und darstellen
  • Preise und Verfügbarkeit anzeigen
  • Warenkorb mit Cart Token führen
  • Versand prüfen
  • Checkout vorbereiten
  • Zahlart wählen
  • Bestellung auslösen
  • Gastkauf, Login und Firmenzugang unterstützen
  • Angebotsanfrage anbieten, wenn Checkout nicht möglich ist
  • Kontaktformulare und Website Chat einbinden, wenn die Site sie nutzt
Produkt-Route mit URL-Schlüssel für den Webshop
Produkt-Route mit URL-Schlüssel für den Webshop

Storefront-Ablauf

b2b_storefront_flow context Storefront Context für Site und Sales Channel catalog Katalog und Produktdetails context->catalog pricing Preise, Steuer und Verfügbarkeit catalog->pricing cart Tokenbasierter Warenkorb pricing->cart identity Gast, Login oder Firmenkontext identity->cart checkout Checkout mit Versand und Zahlart cart->checkout order Bestellung checkout->order quote Angebotsanfrage als Fallback checkout->quote Review nötig

Voraussetzungen

Klären Sie vor dem ersten API-Aufruf:

Wenn eine Voraussetzung fehlt, baut der Client keinen lokalen Ersatz. Geben Sie den Befund an die Administration oder das Commerce-Team zurück.

Begriffskarte für Entwickler

Nutzen Sie diese Begriffe als Schnittstelle zwischen Storefront-Code und fachlicher Pflege. Der Client setzt sie nicht selbst, sondern liest die serverseitig aufgelösten Ergebnisse.

BegriffBedeutung im Storefront-CodeWo Sie Details nachlesen
System Setup, Betriebsbereitschaft und Tenant InitStellen globale Workflow-Artefakte sowie mandantenlokale Commerce-, PIM-, Lokalisierungs-, Gruppen-, Job- und Preset-Grundlagen bereit. Betriebsbereitschaft zeigt, ob systemweite Verträge blockieren. Ohne diese Basis können Produkt-Lifecycle, Readiness, Commerce-Kontext oder Workflow-Aktionen fehlen.System-Initialisierung, Betriebsbereitschaft, Tenant Init, System Setup, Betriebsbereitschaft und Tenant Init prüfen
Site und DomainDer Host muss eine aktive öffentliche Site über eine verifizierte Tenant Domain und Site-Domain-Bindung auflösen, bevor Storefront Context, Katalog oder Widgets funktionieren.Storefront- und Site-Domains einrichten, Site, Tenant Domain, Site-Domain-Bindung
Sales ChannelGrenzt sichtbare Produkte, Inhalte, Preise, Locale, Währung und Checkout-Regeln ein.Sales Channel, Produktdaten veröffentlichen
Commerce ProfileOrdnet die kaufmännischen Regeln ein, die später in Cart, Checkout, Steuer und Dokumenten wirken.Commerce-Profil, Commerce-Fähigkeiten
Customer GroupBeeinflusst, welche Preise, Preislisten, Zahlarten oder Freigaben für Gast-, Account- oder Firmenkontext gelten.Kundengruppe, Commerce-Fähigkeiten
Price List und Product PriceLiefern die serverseitige Preisquelle. Die Storefront zeigt nur Preiswerte aus Pricing- oder Cart-Antworten an.Preisliste, Verkaufspreis, PIM-Grundlagen
Payment Terms und ZahlartSteuern, ob Rechnung, Vorauskasse oder ein Zahlungsanbieter im aktuellen Kontext angeboten werden darf.Zahlungsbedingungen, Zahlart, PayPal einrichten
Steuer-JurisdiktionLiefert die steuerliche Grundlage für Lieferland, Rechnungsadresse, Lieferadresse und Produktkontext.Steuer-Jurisdiktion, Commerce-Fähigkeiten
Produktveröffentlichung und ReadinessEntscheiden zusammen mit Inhalt, Route, Preis und Katalogprojektion, ob eine Variante öffentlich sichtbar wird.Produktveröffentlichung, Readiness, Produktdaten veröffentlichen

Produktdetailseiten planen

Legen Sie Produktdetailseiten nicht als einzelne CMS-Seiten pro Produkt an. Definieren Sie pro Site und Sprache eine dynamische Produktdetailseite im Site Manager. Diese Seite bestimmt Layout, Navigation, Styles und Snippet-Bereiche. Die sichtbare URL entsteht aus dem Prefix dieser Site-Seite und dem ProductRoute.slug des Produkts.

So können zwei Sites im selben Mandanten unterschiedlich aussehen:

SiteAufgabeDetailseiten-Template
B2C-ShopStandard-Shop mit Warenkorb und CheckoutProduktdetailseite mit Preis, Verfügbarkeit, Warenkorb und Supportbereichen
Kampagnen-ShopLandingpage oder AktionsshopProduktdetailseite mit reduziertem Layout, Kampagneninhalt und ausgewählten Snippets

Preis, Verfügbarkeit, Cart und Checkout bleiben öffentliche Runtime-Verträge. Snippets liefern nur vorgerenderte Inhaltsbereiche. Verwenden Sie Snippets nicht als Quelle für Preise, Lagerbestand oder kaufmännische Entscheidungen.

Grundmodell

Ein Onlineshop besteht aus getrennten Schichten:

  • Storefront Context: Site, Sales Channel, Locale, Währung, Anzeige- und Checkout-Regeln.
  • Public Catalog: Suche, Treffer-IDs, Facetten, Produktzusammenfassungen, Produktdetails und veröffentlichte Produktrelationen für Empfehlungen.
  • Pricing: serverseitige Preis-, Steuer- und Verfügbarkeitsauflösung.
  • Cart: tokenbasierter Warenkorb mit serverseitigen Preisen, Totals und Review-Hinweisen.
  • Checkout: Eligibility, Adressen, Zahlart und Bestellung.
  • Account: Registrierung, Login, Firmenzugang und Firmenkontext.
  • Quote: Angebotsanfrage aus dem Warenkorb, wenn Checkout nicht erlaubt oder nicht passend ist.

Der Server entscheidet über Tenant, Site, Sales Channel, Customer Group, Price List, Steuer, Preise, Verfügbarkeit, Versand, Checkout, Zahlarten und Angebotsfähigkeit. Der Client rendert diese Entscheidungen.

Öffentliche Endpunkte

Nutzen Sie nur öffentliche Storefront-Endpunkte:

text
/api/v1/public/v1/storefront/context
/api/v1/public/v1/catalog/...
/api/v1/public/v1/pricing/...
/api/v1/public/v1/cart...
/api/v1/public/v1/checkout...
/api/v1/public/v1/auth/...
/api/v1/public/v1/account/...
/api/v1/public/v1/quotes...
/api/v1/public/v1/contact-forms/...
/api/v1/public/v1/widgets/...

Verwenden Sie keine internen PIM-, Commerce-, Inventory-, Admin- oder CRUD-Endpunkte als Fallback. Wenn ein öffentliches Ergebnis leer oder blockiert ist, ist das ein Daten-, Kontext- oder Freigabethema, kein Grund für einen internen Bypass.

Für Produktdetail-URLs nutzt der Server zusätzlich den öffentlichen Route-Resolver:

http
GET /api/v1/public/v1/catalog/products/by-route/<sichtbarer-detailpfad>

Der Resolver verwendet Host, Site, Sales Channel und Locale aus dem Storefront-Kontext. Der Client sendet keinen Tenant-, Site- oder Sales-Channel-Override.

Domain und Storefront-Auflösung prüfen

Prüfen Sie die Shop-Domain, bevor Sie Katalog, Warenkorb oder Checkout entwickeln. Eine Storefront-Domain ist keine Admin-Domain aus System Domains (CSV). Sie ist eine mandantengebundene cms_public-Domain und muss an die öffentliche Site gebunden sein.

Wenn Sie die nötigen Rechte besitzen, legen Sie zuerst die Shop-Site unter CMS > Sites an und speichern den Site-Datensatz mit Name, Sprache, Status und Sales Channel. Initialisieren Sie danach das leere Site-Projekt, bevor Sie Dateien bearbeiten, Builds erwarten oder Domain-Readiness prüfen:

bash
nucli --tenant <tenant> sites list
nucli --tenant <tenant> sites init <site-id> --release

Führen Sie den Init-Call direkt nach dem Anlegen einer leeren Shop-Site aus. Er erstellt die bearbeitbare Site-Projektstruktur und die erste Default-Page. Mit --release veröffentlicht er diesen Initialstand direkt als ersten statischen Release. Lassen Sie --release weg, wenn Sie die Dateien zuerst bearbeiten und erst später veröffentlichen möchten. Rufen Sie Init nicht auf einer bestehenden Site mit Projektdateien erneut auf; der Server blockiert das mit ERR_ALREADY_INIT.

Richten Sie danach die Domain ein:

bash
nucli --tenant <tenant> web domains create shop.example.test
nucli --tenant <tenant> web domains start-verification <tenant-domain-id>

Veröffentlichen Sie danach den zurückgegebenen verificationValue als DNS-TXT-Record unter verificationName. Verifizieren und binden Sie die Domain erst, wenn DNS den TXT-Record ausliefert:

bash
nucli --tenant <tenant> web domains verify-dns <tenant-domain-id> --token <token>
nucli --tenant <tenant> web bind-domain <site-id> <tenant-domain-id>
nucli --tenant <tenant> web readiness <site-id>
nucli --tenant <tenant> web wait <site-id> --timeout 5m

web wait ist erfolgreich, wenn es operations readiness: ready meldet. Die Readiness prüft Domainbindung, DNS-Verifikation, HTTPS-Erreichbarkeit, Build-Status, Release und bei Storefront-Code die Sales-Channel-Zuordnung.

Lokale Entwicklung ohne öffentliche DNS-Zone

Für lokale Entwicklung müssen Sie zwei Dinge unterscheiden:

  • HTTP-Auflösung: Browser, curl und nucli müssen den Host zum lokalen Workspace-Server auflösen. Für Docker-Demos nutzen Sie dafür am einfachsten einen Subhost unter localhost.alvine.dev, zum Beispiel shop.localhost.alvine.dev; das vorhandene Wildcard-DNS zeigt im Browser bereits auf 127.0.0.1.
  • DNS-Verifikation: web domains verify-dns liest einen TXT-Record über den DNS-Resolver des Workspace-Servers. Eine Hosts-Datei kann keine TXT-Records liefern und ersetzt diese Verifikation nicht.

Nutzen Sie lokal deshalb eine dieser Varianten:

  • Arbeiten Sie für reine Client-Entwicklung mit dem lokal konfigurierten Workspace-Host, zum Beispiel localhost oder einer lokalen Entwicklungsdomain, und prüfen Sie Storefront-Verhalten gegen diese lokale Umgebung. Führen Sie den Tenant-Domain-Verifikationsfluss erst in einer Umgebung mit DNS-Zone aus.
  • Verwenden Sie eine echte Entwicklungsdomain, deren DNS Sie pflegen dürfen. Legen Sie dort sowohl die Host-Auflösung als auch den TXT-Record aus web domains start-verification an.
  • Betreiben Sie für vollständig lokale Host-Tests einen lokalen DNS-Resolver wie dnsmasq oder CoreDNS, der für den Workspace-Server sichtbar ist und sowohl A-/AAAA-Records als auch den TXT-Record liefert. Verwenden Sie dafür einen eigenen Storefront-Subhost wie shop.localhost.alvine.dev, nicht den nackten Host localhost und nicht localhost.alvine.dev selbst. localhost ist ein Resolver-Sonderfall, und localhost.alvine.dev bleibt der lokale Systemhost. Für die Docker-Demo zeigt Lokale Storefront-Domain mit DNS-TXT testen ein Compose-Override mit CoreDNS.

Wenn Sie nur die Browserauflösung prüfen, brauchen Sie bei *.localhost.alvine.dev keine Hosts-Datei. web domains verify-dns bleibt trotzdem blockiert, bis der TXT-Nachweis aus Sicht der Workspace-Runtime über CoreDNS oder eine echte DNS-Zone sichtbar ist.

Für web wait muss zusätzlich HTTPS stimmen: Der Shop-Host muss aus der Workspace-Runtime auf Port 443 erreichbar sein, und die Runtime muss der lokalen CA oder dem Zertifikat vertrauen. Die Docker-Demo beschreibt den Ablauf unter Lokales HTTPS für web wait inklusive lokaler CA, Serverzertifikat und Trust-Store-Import.

Prüfen Sie anschließend den öffentlichen Storefront-Kontext über den späteren Shop-Host:

bash
curl -sS -i https://shop.example.test/api/v1/public/v1/storefront/context

Die Domain ist für die Storefront nutzbar, wenn der Aufruf 200 OK liefert und die Antwort siteId, salesChannelId, locale, currency, flow und die Checkout-/Payment-Policy enthält. Wenn der Aufruf STOREFRONT_UNAVAILABLE liefert, bauen Sie keinen lokalen Host-, Tenant- oder Sales-Channel-Fallback. Geben Sie Host, Zeitpunkt, Endpoint, Status, allgemeinen Fehlercode, Site-ID, Sales-Channel-Erwartung und Readiness-Blocker an Administration oder Commerce zurück.

Wenn Sie keine Domainrechte haben, fordern Sie beim Admin-Team genau diese Ergebnisse an: verifizierte cms_public-Tenant-Domain, Site-Domain-Bindung, web readiness ohne Blocker und einen erfolgreichen Context-Aufruf über den Zielhost.

Mailflüsse lokal prüfen

Wenn Sie Checkout-Mails, Auth-Mails, Angebotsmails oder Benachrichtigungsvorlagen für den Onlineshop entwickeln, verwenden Sie in der Docker-Demo Mailpit. Die Compose-Konfiguration und die lokalen SMTP-Werte stehen unter Lokale Mails mit Mailpit testen.

Prüfen Sie bei Mailtests immer drei Stellen: die fachliche Aktion im Storefront-Flow, den Mail-Job in der Workspace-Warteschlange und die empfangene Nachricht in Mailpit. Ändern Sie Mailtexte und Platzhalter in System > Benachrichtigungsvorlagen, nicht im Storefront-Client.

Empfohlener Implementierungsablauf

  1. Laden Sie den Storefront-Kontext.
  2. Bauen Sie Produktlisten über Catalog Search und Product Summary.
  3. Öffnen Sie Produktdetailseiten über die dynamische Site-Route und lösen Sie den sichtbaren Pfad über products/by-route auf.
  4. Verwenden Sie die zurückgegebene variantId für Detaildaten, Pricing und Warenkorb.
  5. Rendern Sie Variantenauswahlen nur aus öffentlichen Detail- oder Storefront-Antworten und setzen Sie nach jeder Auswahl die aktive variantId.
  6. Rendern Sie Detailseiten-Empfehlungen aus recommendationGroups, wenn der Produktdetail-Endpunkt Gruppen liefert. Verwenden Sie die englischen type-Keys für Logik und eigene Übersetzungen für sichtbare Überschriften.
  7. Laden Sie Preise und Verfügbarkeit über Pricing.
  8. Erstellen oder lesen Sie den Warenkorb.
  9. Fügen Sie Positionen hinzu und übernehmen Sie immer die vollständige Cart-Response.
  10. Berechnen oder wählen Sie Versand.
  11. Prüfen Sie Checkout Eligibility.
  12. Bereiten Sie Checkout mit E-Mail und Adressen vor.
  13. Bieten Sie nur erlaubte Zahlarten an.
  14. Lösen Sie die Bestellung aus.
  15. Bieten Sie Angebotsanfrage an, wenn Checkout blockiert oder quote-only ist.
  16. Ergänzen Sie Kontaktformulare und Website Chat, wenn die Site diese Storefront-Erweiterungen nutzt.
  17. Laden Sie Context, Cart, Pricing und Eligibility nach Login, Logout oder Firmenwechsel neu.

Wenn eine serverseitig gerenderte Produktdetailseite 503 Service Unavailable mit Retry-After liefert, fehlt mindestens ein Required-Snippet-Artefakt für Tenant, Variante, Locale und Sales Channel. Behandeln Sie das als Betriebszustand: Starten oder prüfen Sie den Snippet-Rebuild und verfolgen Sie den zugehörigen Storefront-Telemetry-Fehler. Bauen Sie keinen Client-Fallback auf interne PIM-Daten.

Client-State

Halten Sie clientseitig nur abgeleiteten Zustand:

  • Storefront-Kontext
  • Suchparameter und Treffer-IDs
  • Product Summary und Detaildaten
  • Pricing-Antworten für konkrete Mengen
  • Cart Token und aktuelle Cart-Response
  • Checkout Eligibility
  • aktuell gewählte Zahlart
  • Login- und Firmenkontext, soweit der Server ihn bestätigt

Behandeln Sie Cart Tokens, Session-Werte und Einladungs-Tokens wie Zugangsdaten. Speichern Sie sie nicht in URLs, Logs, Analytics, Snippets oder Support-Nachrichten.

Fehler- und Review-Prinzipien

Stoppen Sie den Checkout bei:

  • reviewRequired=true
  • fehlender Steuer-Jurisdiktion
  • Repricing- oder Price-Mismatch-Hinweis
  • Shipping Review
  • fehlender E-Mail oder Adresse
  • nicht verfügbarer Zahlart
  • nicht erlaubtem Checkout

Zeigen Sie Nutzern einen verständlichen nächsten Schritt. Übergeben Sie an Betreiber nur sichere Diagnosewerte: Host, Zeitpunkt, Endpoint, Status, allgemeiner Fehlercode, Sales Channel, Locale und erwartete SKU oder Variant-ID. Übergeben Sie keine Tokens, Passwörter, rohen Kundendaten oder vollständigen Warenkorb-Payloads.

Nächste Schritte