Commerce Extensions: Eigenentwicklung, die Updates übersteht
Eigene Shop-Logik in Salesforce B2B Commerce übersteht Releases, wenn sie als Commerce Extensions gebaut ist, die den Standard ergänzen statt ihn zu ersetzen. Extensions sind Apex-Klassen, die Salesforce an benannten Erweiterungspunkten wie Preis, Bestand oder Auftragsanlage ausführt. Domain Extensions sollten zuerst den Standarddienst laufen lassen, wie Salesforce ausdrücklich empfiehlt: Dann läuft er weiter, und Ihr Code ergänzt nur, was bei Ihnen anders ist. Endpoint Extensions ändern Anfrage oder Antwort einer API. Zahlungen sind nicht erweiterbar. Die zweite Hälfte der Antwort ist Eigentum: Code, Registrierung und Mapping gehören in Ihr Repository und Ihre Pipeline, nicht in die eines Partners.
Was sind Commerce Extensions?
Salesforce beschreibt Extensions1 als Mechanismus, mit Apex die Funktionen anzupassen, die B2B- und B2C-Storefronts antreiben. Die Apex-Klasse heißt Extension Provider. Erreicht eine Käuferaktion, ein Connect-API-Aufruf oder eine andere Extension einen Erweiterungspunkt, prüft die Plattform, ob dem Namen dieses Erweiterungspunkts ein Provider zugeordnet ist, und führt ihn aus.
Das gilt für Salesforce B2B Commerce auf der Core-Plattform, das Salesforce inzwischen auch als Agentforce Commerce for B2B vermarktet. Die getrennte B2C-Commerce-Architektur nutzt stattdessen Hooks, ein Team mit B2C-Erfahrung findet dort also nicht denselben Mechanismus.
Es gibt zwei Arten:
- Domain Extensions gehören zu einem fachlichen Bereich. Ein Provider kann das Standardverhalten erweitern oder ersetzen, und eine Änderung kann mehrere Endpunkte betreffen. Beispiel: Ein Preis-Provider passt den Standardpreis auf Produktseiten und noch einmal in Warenkorb und Checkout an.
- Endpoint Extensions gehören zu einer Connect-API-Ressource. Der Provider kann die Anfrage vor und die Antwort nach dem Aufruf ändern, aber das Standardverhalten nicht ersetzen.
Erweiterungspunkte von Preis bis Auftragsanlage
Die Liste der verfügbaren Extensions2 ist kurz genug, um sie ganz zu lesen. Für einen Hersteller mit SAP oder einem anderen ERP zählen vor allem diese:
Erweiterungspunkte, die mit einem ERP zählen
Die Seite nennt auch die Standards, die Sie ersetzen: Bestand kommt aus Omnichannel Inventory, Preise aus Salesforce-Preisbüchern, Steuer aus dem Salesforce-Steuerdienst, und Versand kostet nichts, bis Sie ihn erweitern.
Welche Daten live aus dem ERP kommen und welche nach Salesforce kopiert werden, ist eine eigene Designentscheidung. Sie steht in B2B Commerce und SAP: Welche Daten fließen wohin?.
Warum sollte eine Domain Extension den Standard weiterlaufen lassen?
Salesforce schreibt, man empfehle ausdrücklich, super() aufzurufen, um die Kompatibilität mit der Plattform zu sichern. Dieser Aufruf lässt den Standarddienst innerhalb Ihres Codes laufen. In der Praxis gibt es drei Arten, einen Domain Provider zu schreiben:
- Den Standard komplett ersetzen.
- Den Standard laufen lassen und das Ergebnis anpassen, etwa einen ERP-Rabatt auf den Standardpreis anwenden.
- Etwas tun, bevor der Standard läuft, etwa die ERP-Kundennummer des Käufers lesen, und dann den Standard laufen lassen.
Variante 2 und 3 überstehen Releases besser. Ergänzt Salesforce den Standarddienst, etwa um ein neues Feld oder eine Promotion-Funktion, bekommt ein Provider, der den Standard laufen lässt, das automatisch. Ein Provider, der alles ersetzt, hat den Standard still auf dem Stand des Tages eingefroren, an dem er geschrieben wurde. Bei einem Review von Partnercode wäre ein kompletter Ersatz des Standards meine erste Frage. Manchmal ist er begründet, etwa wenn das ERP der einzige Preis-Master ist, aber dann gehört die Begründung in den Code und ins Architektur-Entscheidungslog.
Für Entwickler
Wie teste ich einen Provider, der super() aufruft?
Die Basisklassen liegen in einem Salesforce-Namespace, und der Guide zum Mocken der Basisklasse (öffnet in einem neuen Tab) erklärt, dass das Apex-Testframework nicht über Namespaces hinweg mocken kann. Das dokumentierte Muster: den Provider virtual machen, den super()-Aufruf in eine eigene @TestVisible-Methode legen und diese im Test in einer Unterklasse überschreiben.
ERP-Aufrufe werden mit HttpCalloutMock simuliert, wie im Guide zum Testen eines Extension Providers (öffnet in einem neuen Tab) beschrieben.
Liefert ein Partner Extensions ohne diese Tests, ist die Testabdeckung meist durch Aufrufe ohne echte Prüfungen erreicht.
Extensions oder die älteren Integrationen?
Vor den Extensions wurde Checkout-Logik über Integrationen angebunden: ein Apex-Interface, das einen Calculator ersetzt. Salesforce schreibt heute, Extensions seien der bevorzugte Weg, Salesforce Commerce anzupassen, und Integrationen blieben voll unterstützt. Extensions decken mehr ab, mit fünf Warenkorb-Calculators plus Preisdienst und weiteren Diensten, wo Integrationen vier Checkout-Calculators hatten.
Meine Regel: Neue Logik kommt in Extensions. Bestehende Integrationen bleiben, bis der Code sich ohnehin ändern muss, etwa weil sich die ERP-Schnittstelle ändert oder der Store von Aura auf LWR wechselt. Funktionierende Integrationen nur umzuschreiben, weil es einen neueren Mechanismus gibt, lohnt sich selten.
Zahlungen sind die Ausnahme. Salesforce schreibt: Zahlungen können derzeit nicht per Extension angepasst werden. Payment Gateways behalten ihren eigenen Adapter, siehe B2B-Checkout: Bestellnummer, Karte oder Rechnung?.
Registrierung und Mapping gehören ins Repository
Registrierung und Mapping sind zwei getrennte Schritte, und beide sind Konfiguration, die jemand in jeder Umgebung nachbauen muss. Salesforce empfiehlt, beides über die Salesforce-Kommandozeile zu erledigen, die auch in einer Pipeline läuft; die Connect API und die Administrationsoberfläche gehen ebenfalls, und dort können die Shop-Verantwortlichen Domain Extensions selbst zuordnen.
Diese letzte Möglichkeit ist das Risiko. Ein Mapping, das von Hand in Produktion geändert wurde, ist in Git unsichtbar. Angenommen, ein Partner ordnet in Produktion direkt einen neuen Preis-Provider zu, um einen dringenden Preisfehler zu beheben. Die Änderung kommt nie ins Repository, und das nächste Deployment aus der Pipeline ordnet wieder den alten Provider zu. Niemand merkt es, bis Händler sich über falsche Preise beschweren.
Für Entwickler
Klassennamen, Namen der Erweiterungspunkte und CLI-Befehle
- Domain Provider für Preise: erweitert
commercestorepricing.PricingServiceund überschreibtprocessPrice(Produktlisten und Detailseiten) undprocessTransactionalPrice(Warenkorb und Checkout). - Endpoint Provider: erweitert
ConnectApi.BaseEndpointExtension; keinsuper()-Aufruf. - Namen der Erweiterungspunkte:
Commerce_Domain_Pricing_Service,Commerce_Domain_Pricing_CartCalculator,Commerce_Domain_Inventory_Service,Commerce_Domain_Inventory_CartCalculator,Commerce_Domain_Tax_Service,Commerce_Domain_Tax_CartCalculator,Commerce_Domain_Shipping_CartCalculator,Commerce_Domain_Checkout_PlaceOrder,Commerce_Domain_Checkout_CreateOrder,Commerce_Domain_BuyerGroup_EvaluationService,Commerce_Endpoint_Catalog_Products,Commerce_Endpoint_Search_ProductSearch. - Registrierung und Mapping:
sf plugins install @salesforce/commerce, dannsf commerce:extension:registerfür die Klasse undsf commerce:extension:mapfür den Store; alternativ die ObjekteRegisteredExternalServiceundStoreIntegratedService.
Was ich in Vertrag und Pipeline festlegen würde:
- Extension-Klassen, Tests und die Befehle für Registrierung und Mapping liegen im Repository des Kunden, wie ich es in warum Kunden ihre DevOps-Tools selbst besitzen sollten begründe.
- Die Pipeline führt die CLI-Befehle pro Umgebung aus, damit Mappings reproduzierbar sind. Salesforce weist darauf hin, dass für Extensions die neueste Salesforce CLI nötig ist, also legen Sie die CLI-Version fest und heben sie bewusst an.
- Jede Änderung an einer Extension läuft durch ein Pull-Request-Review, das prüft, ob der Standard noch läuft, und Timeouts der ERP-Aufrufe und echte Prüfungen in den Tests kontrolliert.
- Manuelles Mapping in Produktion bleibt Notfällen vorbehalten, und am selben Tag folgt ein Commit.
Wie Store-Konfiguration mit den Metadaten wandert, beschreibt die DevOps-Masterclass im Kapitel Daten und Konfiguration, den Aufbau der Pipeline im Kapitel Pipeline aufbauen.
Jede eigene Logik einem Erweiterungspunkt zuordnen
Listen Sie jede eigene Logik in Ihrem Store auf und ordnen Sie sie einem Erweiterungspunkt, einer alten Integration oder einer eigenen Komponente zu. Markieren Sie jeden Domain Provider, der den Standard ersetzt, und fragen Sie nach dem Grund. Prüfen Sie dann, ob sich Registrierung und Mapping aus dem Repository in einer frischen Sandbox wieder aufbauen lassen. Klappt das nicht, haben Sie Ihre größte Abhängigkeit vom aktuellen Partner gefunden. Die ERP-Seite derselben Entscheidungen ist Teil des Kapitels ERP-Anbindung, und dieselben Extensions bedienen auch eine headless Storefront.
Quellen2
- 1Extensions (öffnet in einem neuen Tab)developer.salesforce.com
- 2Liste der verfügbaren Extensions (öffnet in einem neuen Tab)developer.salesforce.com
Häufig gestellte Fragen
Was sind Salesforce Commerce Extensions?
Apex-Klassen, sogenannte Extension Provider, die Salesforce an benannten Erweiterungspunkten von B2B Commerce ausführt. Sie ändern, wie Preise, Bestand, Steuer, Versand, Checkout oder einzelne Connect-API-Endpunkte arbeiten, ohne den Store zu ersetzen.
Was unterscheidet eine Domain Extension von einer Endpoint Extension?
Eine Domain Extension arbeitet auf einem fachlichen Bereich wie Preisen und kann den Standarddienst erweitern oder ersetzen, was mehrere API-Endpunkte betreffen kann. Eine Endpoint Extension ändert Anfrage oder Antwort eines einzelnen Connect-API-Endpunkts und kann dessen Standardverhalten nicht ersetzen.
Wie werden Commerce Extensions registriert?
Salesforce empfiehlt die Salesforce CLI mit dem Commerce-Plug-in: sf commerce:extension:register registriert die Apex-Klasse, sf commerce:extension:map ordnet sie einem Store zu. Alternativ gehen die Objekte RegisteredExternalService und StoreIntegratedService oder die Connect API.
Kann man Zahlungen mit einer Commerce Extension anpassen?
Nein. Salesforce schreibt, dass Zahlungen derzeit nicht per Extension angepasst werden können. Payment Gateways werden stattdessen über eine eigene Zahlungsintegration angebunden.
Sollten wir alte Checkout-Integrationen auf Extensions umbauen?
Salesforce nennt Extensions den bevorzugten Weg und schreibt, dass Integrationen voll unterstützt bleiben. Ich würde umbauen, wenn der Code ohnehin geändert werden muss, nicht als eigenes Projekt.