Login, Gastkauf und B2B

Unterstützen Sie anonyme Besucher, Gastkauf, Registrierung, Login und Firmenzugang ohne lokale Freischaltungslogik. Diese Seite passt, wenn Ihr B2B-Onlineshop Firmenpreise, Rechnungskauf, Kundengruppen, Ansprechpartner, Passwortwechsel oder freigegebene Lieferadressen abbilden soll. Der Server entscheidet, welcher kommerzielle Kontext gilt.

Nach der Umsetzung lädt der Client nach Login, Logout und Firmenwechsel die serverseitigen Kontexte neu und zeigt nur Preise, Zahlarten und Checkout-Wege, die Workspace für den aktuellen Besucher freigibt.

Die fachliche Einrichtung eines bestehenden Unternehmens, seiner Mitarbeiter, Preise, Firmenrollen und Lieferadressen beschreibt Quickstart: Firmenkunden für den Onlineshop freischalten. Diese Seite bleibt beim technischen Storefront-Vertrag.

Voraussetzungen

Klären Sie vor Login-, Gastkauf- oder Firmenzugangsflows:

Die fachliche Einordnung von Kundengruppen, Commerce-Profilen und Zahlungsbedingungen steht in Handel- und Commerce-Fähigkeiten.

Grundregel

Anonyme Besucher nutzen den öffentlichen Standardkontext des Sales Channels. Nach Login oder Firmenwechsel können sich Preise, Steueranzeige, Verfügbarkeit, Checkout-Fähigkeit, Zahlarten und Angebotsfähigkeit ändern.

Laden Sie nach diesen Ereignissen neu:

Gastkauf

Gastkauf ist nur verfügbar, wenn der Storefront Context oder Checkout Eligibility ihn erlaubt.

Für Gastkauf senden Sie im Checkout:

  • customerEmail
  • billingAddress
  • shippingAddress

Diese Daten sind transaktionale Cart- und Order-Snapshots. Der Client legt daraus keine CRM-Person, kein CRM-Unternehmen und keine CRM-Adresse an.

Wenn Gastkauf nicht erlaubt ist, führen Sie Nutzer zu Login, Registrierung oder Angebotsanfrage.

Registrierung

Registrierung erzeugt zunächst einen normalen Account-Kontext. Sie schaltet keine vorhandenen Firmenpreise, keine Rechnung und keine B2B-Steuerlogik frei.

http
POST /api/v1/public/v1/auth/register
Content-Type: application/json

Senden Sie email und password im JSON-Body. Das Passwort muss mindestens acht Zeichen lang sein.

Nach erfolgreicher Registrierung:

  1. Laden Sie Storefront Context neu.
  2. Laden Sie Cart neu.
  3. Lösen Sie Pricing für sichtbare Produkte neu auf.
  4. Prüfen Sie Checkout Eligibility neu.

Wenn der Nutzer Firmenzugang benötigt, starten Sie eine Firmenzugangs-Anfrage. Leiten Sie aus Firmenname, E-Mail-Domain, Kundennummer oder USt-ID keine automatische Freischaltung ab.

Login, Logout und Passwort

Für Browser-Storefronts nutzen Sie die allgemeinen Auth-Endpunkte. Die öffentlichen Account-Endpunkte unter /api/v1/public/v1/account/... verwenden danach die aktive Browser-Sitzung.

http
POST /api/v1/auth/login
Content-Type: application/json

Senden Sie email und password im JSON-Body. Login erwartet E-Mail und Passwort. Logout beendet die aktuelle Sitzung.

http
POST /api/v1/auth/logout
Content-Type: application/json

{}

Passwort-Wiederherstellung startet mit dem Endpunkt forgot-password.

http
POST /api/v1/auth/forgot-password
Content-Type: application/json

{
  "mail": "kunde@example.test"
}

Der zugesandte Code wird über login-digits geprüft:

http
POST /api/v1/auth/login-digits
Content-Type: application/json

{
  "digits": "123456"
}

Speichern Sie Wiederherstellungscodes nicht in Logs, Analytics oder Support-Nachrichten.

Nach Login kann der Server einen anderen Kontext auflösen:

Nach Logout gilt wieder der öffentliche oder normale anonyme Kontext. Verwerfen oder aktualisieren Sie alle preis- und checkoutrelevanten Client-Daten.

Passwortwechsel ist ein angemeldeter Browser-Session-Vertrag, kein anonymer Storefront-Endpunkt:

http
POST /api/v1/profile/password
Content-Type: application/json

Senden Sie das aktuelle Passwort im Feld currentPassword und das neue im Feld password. Der Endpunkt benötigt eine aktive Browser-Sitzung und akzeptiert ein neues Passwort mit mindestens acht Zeichen. Ein falsches aktuelles Passwort liefert 403 ERR_PASSWORD_CURRENT_INVALID und zählt gegen dasselbe Versuchsbudget wie der Login; ein unverändertes Passwort liefert 400 ERR_PASSWORD_UNCHANGED, ein erschöpftes Budget 429 ERR_RATE_LIMIT. Nach dem Wechsel sind alle anderen Sitzungen dieser Identität abgemeldet, auch auf anderen Geräten; die aktuelle Sitzung bleibt bestehen. Nach einem reinen Passwortwechsel bleibt der kaufmännische Kontext gleich. Laden Sie Preise, Cart und Checkout Eligibility trotzdem neu, wenn der Flow gleichzeitig Login, Logout, Tenant-Auswahl oder Firmenkontext ändert.

Firmenzugang anfragen

Wenn ein Nutzer B2B-Zugang benötigt, senden Sie eine Firmenzugangs-Anfrage:

http
POST /api/v1/public/v1/account/company-access/request
Content-Type: application/json

{
  "companyName": "Beispiel GmbH",
  "contactEmail": "einkauf@beispiel.test",
  "customerNumber": "100123",
  "vatId": "DE123456789",
  "message": "Bitte Zugang prüfen.",
  "pageUrl": "https://shop.example.test/firmenzugang",
  "honeypot": "",
  "filledSeconds": 12
}

Beispielantwort:

json
{
  "state": "requested",
  "requestId": "uuid",
  "status": "pending_review",
  "nextAction": "await_approval"
}

Die Anfrage ist Review-Kontext. Sie wird intern als Firmenzugangs-Eingang und CRM-Lead gespeichert, ist aber keine Marketing- oder Consent-Einwilligung. Sie schaltet keine Preisliste, keine Rechnung und keine Steuerbefreiung frei. Der Server begrenzt zu viele Anfragen und bewertet einfache Spam-Signale wie gefüllte Honeypot-Felder, unrealistisch kurze Füllzeiten und URL-Muster. Senden Sie filledSeconds immer mit; fehlende oder zu niedrige Werte können als zu schnelle Submission gelten. Der Request-Body darf das konfigurierte Limit public.storefront.submission.max_bytes nicht überschreiten.

Freigegebene Firmen laden

Laden Sie verfügbare Firmenkontexte:

http
GET /api/v1/public/v1/account/companies

Beispielantwort:

json
{
  "items": [
    {
      "companyId": "uuid",
      "name": "Beispiel GmbH",
      "displayName": "Beispiel",
      "role": "buyer",
      "storefrontAddressScope": "selected",
      "storefrontAddressIds": ["uuid"]
    }
  ]
}

Wenn keine Firma verfügbar ist, bleibt der Nutzer im normalen Account-Kontext. Rollen steuern, was der Nutzer im Firmenkontext darf:

RolleBedeutung
viewerDarf freigegebene Firmenbestellungen sehen, aber nicht im Firmenkontext einkaufen.
buyerDarf Firmenbestellungen sehen und im Firmenkontext einkaufen.
adminDarf einkaufen und zusätzlich Änderungsanfragen für Firmenstammdaten erfassen.

storefrontAddressScope=all erlaubt alle Lieferadressen der Firma. storefrontAddressScope=selected erlaubt nur die IDs aus storefrontAddressIds. Verwenden Sie diese Felder nur zur Anzeige und Vorauswahl. Der Checkout validiert die Berechtigung serverseitig erneut.

Firmenkontext wählen

http
POST /api/v1/public/v1/account/company-context
<Cart-Token-Header>: opaque-cart-token
Content-Type: application/json

{
  "companyId": "uuid"
}

Beispielantwort:

json
{
  "companyId": "uuid",
  "state": "selected",
  "reviewRequired": true
}

Nach erfolgreicher Auswahl:

  1. Laden Sie Cart neu.
  2. Laden Sie Storefront Context neu.
  3. Lösen Sie Pricing neu auf.
  4. Prüfen Sie Checkout Eligibility neu.
  5. Zeigen Sie Review an, wenn reviewRequired=true.

Bei einer Browser-Session setzt Workspace außerdem den nicht per JavaScript lesbaren Host-Cookie nucleus-storefront-company. Damit können dynamische Produktdetailseiten den autorisierten Firmenpreis bereits im initialen HTML rendern. Der Cookie ist nur ein Selektor. Bei jedem Seitenaufruf prüft Workspace Identity, Tenant, Person, Beschäftigung, Company und Käuferrolle erneut. Ein manipulierter oder widerrufener Wert gewährt keinen Firmenzugriff.

Senden Sie für B2B-Kontext nur den vom Server bestätigten Firmenkontext. Erfinden Sie keine companyId und verwenden Sie keine Kundennummer als Firmenkontext. Bei Same-Origin-Aufrufen sendet eine verifizierte Browser-Session den Cookie automatisch; Pricing und Standard-Warenkorb bleiben damit auch nach einer Seitennavigation im gewählten Kontext. Die Firmen-ID übergeben Headless-Clients weiterhin im konfigurierten Firmenkontext-Header.

Für POST und DELETE gilt bei einer ausgewählten Session derselbe Schreibschutz: Browser müssen einen gültigen Same-Origin-Kontext senden. Ein nativer Session-Client ohne Browserheader sendet stattdessen exakt <code>X-Nuc&#108;eus-CSRF: 1</code>; dieser Marker überstimmt keine vorhandenen Browserheader. Ein autoritativer Bearer-Client benötigt den Marker nicht.

Firmenkontext löschen

http
DELETE /api/v1/public/v1/account/company-context
<Cart-Token-Header>: opaque-cart-token

Beispielantwort:

json
{
  "state": "cleared",
  "reviewRequired": true
}

Der Endpunkt löscht den Firmenkontext-Cookie und bindet den übergebenen Warenkorb wieder an den persönlichen Käuferkontext. Laden Sie danach Cart, Storefront Context, Pricing und Checkout Eligibility neu. Beim Logout löscht Workspace Session- und Firmenkontext-Cookie gemeinsam.

Eine Identity mit aktivem Firmenzugang wird im Checkout als Firmen-Identity behandelt. Privater Einkauf mit Personenadressen ist für diese Identity nicht vorgesehen und kann mit COMPANY_CONTEXT_REQUIRED abgelehnt werden. Legen Sie für privaten Einkauf eine getrennte Identity ohne aktiven Firmenzugang an.

Einladung für Ansprechpartner annehmen

Ein Ansprechpartner bekommt eine eigene Identity. Es gibt keinen gemeinsamen Firmenlogin.

http
POST /api/v1/public/v1/account/company-invitations/accept
Content-Type: application/json

Senden Sie Einladungs-Token, E-Mail-Adresse und neues Passwort im JSON-Body. Das Passwort muss mindestens acht Zeichen lang sein.

Beispielantwort:

json
{
  "state": "accepted",
  "identityId": "uuid",
  "tenantId": "uuid"
}

Speichern Sie Einladungs-Tokens nicht in Logs oder Analytics. Akzeptieren Sie Einladungen nur mit dem dafür vorgesehenen Formular und der serverseitigen Prüfung.

Rechnung

invoice ist nur verfügbar, wenn der Server sie in Checkout Eligibility oder Storefront Context erlaubt.

Rechnung setzt typischerweise voraus:

Schalten Sie Rechnung nie lokal frei. Wenn invoice nicht erlaubt ist, zeigen Sie erlaubte Zahlarten wie Vorauskasse, PayPal, Kreditkarte oder Angebotsanfrage.

Kundenkonto

Angemeldete Nutzer können Bestellungen und eigene Profildaten über Public Account APIs lesen und pflegen:

http
GET /api/v1/public/v1/account/orders
GET /api/v1/public/v1/account/orders/{orderId}
POST /api/v1/public/v1/account/orders/{orderId}/reorder
GET /api/v1/public/v1/account/subscriptions
GET /api/v1/public/v1/account/subscriptions/renewal-readiness
GET /api/v1/public/v1/account/subscriptions/{subscriptionId}
POST /api/v1/public/v1/account/subscriptions/{subscriptionId}/cancel
POST /api/v1/public/v1/account/subscriptions/{subscriptionId}/reactivate
PATCH /api/v1/public/v1/account/subscriptions/{subscriptionId}/payment-method
POST /api/v1/public/v1/account/subscriptions/{subscriptionId}/change-requests
GET /api/v1/public/v1/account/payment-methods
POST /api/v1/public/v1/account/payment-methods
GET /api/v1/public/v1/account/products/purchased
GET /api/v1/public/v1/account/product-lists
POST /api/v1/public/v1/account/product-lists
GET /api/v1/public/v1/account/product-lists/{listId}
PATCH /api/v1/public/v1/account/product-lists/{listId}
DELETE /api/v1/public/v1/account/product-lists/{listId}
POST /api/v1/public/v1/account/product-lists/{listId}/items
PATCH /api/v1/public/v1/account/product-lists/{listId}/items/{itemId}
DELETE /api/v1/public/v1/account/product-lists/{listId}/items/{itemId}
GET /api/v1/public/v1/account/profile/contact
PATCH /api/v1/public/v1/account/profile/contact
GET /api/v1/public/v1/account/profile/addresses
POST /api/v1/public/v1/account/profile/addresses
PATCH /api/v1/public/v1/account/profile/addresses/{addressId}
DELETE /api/v1/public/v1/account/profile/addresses/{addressId}
POST /api/v1/public/v1/account/company-change-requests

Nutzen Sie account/products/purchased für den Bereich "Gekaufte Produkte". Der Server leitet diese Liste aus Bestellungen ab und speichert dafür keinen zweiten Historienbestand.

Nutzen Sie account/subscriptions für den Bereich "Meine Abonnements". Die Antwort enthält nur kundentaugliche Felder wie Produkt, Status, Intervall, aktuelle Periode, nächste Abrechnung, Kündigungsdaten, Preis und eine maskierte Zahlungsmittel-Zusammenfassung. Interne Felder wie tenantId, identityId, Provider-Token, Retry-Zähler und letzte technische Fehler werden nicht ausgegeben.

Kunden können eigene Abonnements kündigen und reaktivieren. Eine Kündigung deaktiviert die automatische Verlängerung und beendet das Abonnement zum Periodenende. Eine Reaktivierung ist nur möglich, solange das gekündigte Abonnement noch nicht abgelaufen ist und ein eigenes gespeichertes Zahlungsmittel zugeordnet ist. Die Site kann bereits tokenisierte Provider-Zahlungsmittel über POST account/payment-methods speichern. Der Server gibt Provider-Tokens nie zurück; Responses enthalten nur maskierte Felder wie Typ, Marke, letzte vier Stellen und Ablaufdatum.

Ohne Firmenkontext liefern account/subscriptions, account/subscriptions/{subscriptionId}, account/payment-methods und account/subscriptions/renewal-readiness nur persönliche Abonnements und Zahlungsmittel des angemeldeten Accounts. Mit dem konfigurierten Firmenkontext-Header liefern sie den Firmenbestand. viewer, buyer und admin dürfen Firmenabonnements lesen. buyer und admin dürfen firmenbezogene Zahlungsmittel anlegen, ein vorhandenes persönliches oder firmenbezogenes Zahlungsmittel zuordnen und Vertragsänderungen als Review-Request einreichen. Nur admin darf ein Firmenabonnement kündigen oder reaktivieren.

account/subscriptions/renewal-readiness meldet für den angemeldeten Account, ob automatisch verlängernde Abonnements noch ein gespeichertes Zahlungsmittel benötigen. Der Endpunkt liefert stabile Schlüssel wie renewal_payment_method_missing; die Site übersetzt diese Schlüssel selbst.

Senden Sie Vertragsänderungen nicht als direkte Subscription-Mutation. Nutzen Sie für Firmenabonnements POST account/subscriptions/{subscriptionId}/change-requests mit einem kontrollierten requestType wie quantity_change, variant_change, pause oder cancel_at_period_end. Der Server speichert eine offene Änderungsanfrage mit Subscription- und Billing-Subject-Bezug. Automatische Proration oder Tarifwechsel-Ausführung ist kein Public-Account-Verhalten.

Ohne Firmenkontext liefert der Endpunkt nur persönliche Bestellungen der aktuellen Person, bei denen keine companyId gesetzt ist. Mit dem konfigurierten Firmenkontext-Header liefert er ausschließlich Bestellungen dieser Firma. Der Account braucht dafür die Firmenrolle viewer, buyer oder admin.

Produktlisten bilden die Merkliste und B2B-Standardartikel ab. Persönliche Listen gehören der aktuellen Person. Firmenlisten gehören zur ausgewählten Firma:

  • viewer, buyer und admin dürfen Firmenlisten lesen.
  • Nur admin darf Firmenlisten erstellen, ändern oder löschen.
  • Persönliche Listen darf nur der Besitzer lesen und bearbeiten.

Listeneinträge speichern operative Kundendaten wie eigene Artikelnummer, Notiz, Standardmenge, eigenen Bestand und Zielbestand. Speichern Sie aktuelle Preise und Verfügbarkeit nicht lokal in der Liste. Laden Sie diese Werte bei Bedarf über den Pricing-Endpunkt:

http
POST /api/v1/public/v1/pricing/resolve

Nicht mehr öffentliche Produkte bleiben in gekauften Produkten und Listen auffindbar. Die API liefert dann productState=unavailable und nur gespeicherte Bestell- oder Public-Snapshots. Leiten Sie keine Daten aus internen PIM-, Commerce- oder Admin-Endpunkten ab.

Bereich "Meine Produkte" bauen

Bauen Sie den Kundenkonto-Bereich als Arbeitsansicht, nicht als Marketingseite. Eine robuste Struktur ist:

  • Gekauft: automatisch aus Bestellungen abgeleitete Produkte.
  • Listen: persönliche Listen und, bei aktivem Firmenkontext, Firmenlisten.
  • Listendetail: Tabelle mit gespeicherten Mengen, eigener Artikelnummer, Notiz, eigenem Bestand, Zielbestand und Warenkorb-Aktion.

Laden Sie zuerst den Account-Kontext:

http
GET /api/v1/public/v1/account/companies

Wenn der Nutzer eine Firma auswählt, setzen Sie den Firmenkontext im Shop und senden Sie danach bei Account-Produktlisten den konfigurierten Firmenkontext-Header:

http
<company-context-header>: <companyId>

Laden Sie danach die gekauften Produkte:

http
GET /api/v1/public/v1/account/products/purchased

Nutzen Sie die Antwort für eine tabellarische Ansicht. Wichtige Felder sind:

  • scope: personal oder company
  • companyId: gesetzt bei Firmenkontext
  • variantId
  • pricingTargetType
  • unitOfMeasure
  • sku
  • name
  • productState: public oder unavailable
  • lastOrderedAt
  • lastQuantity
  • totalQuantity
  • orderCount

Laden Sie Produktlisten separat:

http
GET /api/v1/public/v1/account/product-lists

Die Antwort liefert pro Liste visibility, type, name, itemsCount und canEdit. Blenden Sie Bearbeiten-Aktionen nur ein, wenn canEdit=true ist. Bei canEdit=false kann der Nutzer die Liste lesen, aber nicht ändern.

Listen anlegen und pflegen

Erstellen Sie eine persönliche Liste ohne Firmenkontext:

http
POST /api/v1/public/v1/account/product-lists
json
{
  "name": "Essen",
  "type": "wishlist"
}

Erstellen Sie eine Firmenliste mit Firmenkontext:

http
POST /api/v1/public/v1/account/product-lists
<company-context-header>: <companyId>
json
{
  "name": "Standardware",
  "type": "standard",
  "visibility": "company"
}

Nutzen Sie den Listennamen für operative Gruppierungen wie Getränke, Essen, Werkstatt, Filiale München oder Projekt Müller. Dafür brauchen Sie keine Produktkategorien und keine eigenen Produktattribute.

Fügen Sie ein Produkt zu einer Liste hinzu:

http
POST /api/v1/public/v1/account/product-lists/{listId}/items
json
{
  "variantId": "uuid",
  "pricingTargetType": "variant",
  "unitOfMeasure": "PC",
  "defaultQuantity": "6.0000",
  "customerStockQuantity": "12.0000",
  "targetStockQuantity": "24.0000",
  "customerSku": "KUNDE-4711",
  "note": "Standard für Standort München",
  "sortOrder": 10
}

Ändern Sie operative Daten eines Listeneintrags:

http
PATCH /api/v1/public/v1/account/product-lists/{listId}/items/{itemId}
json
{
  "defaultQuantity": "8.0000",
  "customerStockQuantity": "5.0000",
  "targetStockQuantity": "20.0000",
  "note": "Nur für Servicefahrzeuge verwenden"
}

Die API speichert Listeneinträge pro Liste. Dasselbe Produkt darf deshalb in mehreren Listen vorkommen. Innerhalb derselben Liste aktualisiert POST /items den vorhandenen aktiven Eintrag für dieselbe Variante, Pricing-Zielart und Einheit.

Preise, Verfügbarkeit und Warenkorb

Laden Sie Preise und Verfügbarkeit live, wenn Sie Listen anzeigen oder Mengen ändern:

http
POST /api/v1/public/v1/pricing/resolve
json
{
  "items": [
    {
      "variantId": "uuid",
      "pricingTargetType": "variant",
      "quantity": "6.0000",
      "unitOfMeasure": "PC"
    }
  ]
}

Legen Sie ein Produkt aus einer Liste über den normalen Cart-Vertrag in den Warenkorb:

http
POST /api/v1/public/v1/cart/items
json
{
  "variantId": "uuid",
  "pricingTargetType": "variant",
  "quantity": "6.0000",
  "unitOfMeasure": "PC"
}

Der Warenkorb prüft Preis, Verfügbarkeit, Steuer, Versand und Checkout erneut. Die Produktliste gibt dafür keine Freigabe und keinen Preis-Snapshot.

Layout-Idee

Nutzen Sie im Desktop eine dichte Tabellenansicht:

SpalteQuelle
Artikelname, sku, productState
KundenartikelnummercustomerSku
Letzter KauflastOrderedAt aus gekauften Produkten
BestellmengelastQuantity oder defaultQuantity
Eigener BestandcustomerStockQuantity
ZielbestandtargetStockQuantity
Preis / Verfügbarkeitpricing/resolve
AktionWarenkorb, Merken, Entfernen

Auf Mobilgeräten eignet sich eine kompakte Listenzeile pro Artikel:

  • erste Zeile: Artikelname und Verfügbarkeitsstatus
  • zweite Zeile: SKU und Kundenartikelnummer
  • dritte Zeile: Menge, eigener Bestand, Zielbestand
  • Aktionen: Menge ändern, in den Warenkorb legen, aus Liste entfernen

Zeigen Sie leere Zustände handlungsorientiert:

  • Gekauft: "Noch keine gekauften Produkte" mit Link zur Bestellhistorie oder zum Katalog.
  • Listen: "Noch keine Liste" mit Aktion "Liste anlegen".
  • Liste ohne Einträge: "Diese Liste enthält noch keine Produkte" mit Suche oder Kataloglink.

Behandeln Sie productState=unavailable als eigenen Zustand. Zeigen Sie den gespeicherten Namen und die SKU, aber deaktivieren Sie direkte Warenkorb-Aktion oder führen Sie den Nutzer zu einer Anfrage beziehungsweise Ersatzartikelsuche.

Nachbestellung erzeugt immer einen neuen Warenkorb. Der Server übernimmt keine historischen Preise, Rabatte oder Checkout-Entscheidungen, sondern berechnet Preis, Steuer, Verfügbarkeit und Eligibility neu.

Eigene Kontakt- und Adressendpunkte ändern nur die mit der Identity verknüpfte Person. Sie ändern keine Company und keine CompanyAddress. Firmenänderungen laufen über company-change-requests und benötigen die Rolle admin. Abonnement-Vertragsänderungen laufen über account/subscriptions/{subscriptionId}/change-requests im bestätigten Firmenkontext; buyer und admin dürfen diese Anfragen erstellen.

Wenn der Tenant den Review-Prozess aktiviert hat, erzeugt jede angenommene Änderungsanfrage zusammen mit dem Antrag genau einen Vorgang. Die Antwort enthält dann requestId, caseId, status und reused. Senden Sie für diese Schreibaufrufe immer einen stabilen Idempotency-Key; der weiterhin akzeptierte Header X-Idempotency-Key muss denselben Wert tragen, falls beide gesetzt sind. Derselbe Schlüssel mit abweichendem Inhalt wird abgewiesen.

Ein 503 ACCOUNT_CHANGE_REVIEW_UNAVAILABLE bedeutet, dass der Tenant den Prozess zwar aktiviert hat, aber Vorgangstyp, Workflow oder zuständige Gruppe noch nicht vollständig bereitstehen. Speichern Sie die Anfrage in diesem Fall nicht in einem zweiten Client-System und stellen Sie keinen erfolgreichen Abschluss dar. Die tatsächliche Änderung von Firmen- oder Abonnementdaten bleibt auch nach der Prüfung den jeweiligen Fachendpunkten vorbehalten.

USt-ID und Reverse Charge

USt-ID, Kundennummer und Firmenname sind Eingaben für Review und Firmenkontext. Der Browser entscheidet nicht über Reverse Charge, Steuerfreiheit, B2B-Preise oder Rechnung.

Für EU-B2B gilt:

  • Steuerlogik kommt aus dem Serverkontext.
  • USt-ID-Status muss serverseitig gültig oder akzeptiert sein, bevor eine abweichende Steuerlogik gilt.
  • Nicht verfügbare oder unbekannte Prüfung führt nicht automatisch zu Steuerfreiheit.
  • Der Client zeigt nur die serverseitig berechneten Steuer- und Gesamtwerte.

Sicherheitsregeln

  • Kein automatisches Matching auf Firmenname allein.
  • Kein automatisches Matching auf E-Mail-Domain allein.
  • Kein Preislistenwechsel ohne bestätigten Firmenkontext.
  • Kein Rechnungskauf ohne Serverfreigabe.
  • Keine CRM-Trefferlisten in öffentlichen Antworten anzeigen.
  • Keine gemeinsamen Firmenlogins verwenden.
  • Firmen-Rechnungsadresse nicht mit privaten oder fremden Lieferadressen mischen.
  • Keine internen Prüfgründe oder Rohdaten in Fehlermeldungen ausgeben.