B2B-Commerce mit Medusa v2: Firmenkonten, Preislisten, Angebote
Was Medusa v2 für B2B im Kern mitbringt, was der offizielle B2B Starter ergänzt und was Sie selbst bauen. Dazu vier Stolperfallen bei Preisen und Bestellzugriff, die ich im Code eines Medusa-Projekts gefunden und geschlossen habe.
B2B-Shops scheitern selten am Katalog. Sie scheitern an den Regeln dahinter: Händler A bekommt 18 % auf die Liste, ab 50 Stück gilt eine andere Staffel, Bestellungen über 5.000 € braucht die Einkaufsleitung, und das Angebot aus dem Außendienst muss irgendwie in den Checkout. Genau diese Regeln sind der Grund, warum B2B-Teams sich überhaupt ein Framework wie Medusa ansehen.
Meine Karten auf den Tisch: Einen reinen B2B-Shop betreibe ich nicht. Ich baue mit Medusa und Mercur, aktuell an einem Marktplatz-Projekt auf Medusa 2.21.2 und Mercur 2.3.6, und genau dort sitzen die Bausteine, auf denen jedes B2B-Setup steht: Preislisten, Preisregeln, individuelle Positionspreise und der Zugriff auf Bestellungen. Die vier Fallen weiter unten stammen aus diesem Code, nicht aus der Dokumentation. Alles andere ist an offiziellen Quellen geprüft, Stand 19. Oktober 2026.
Kurzfassung: Kundenpreise, Staffelpreise und getrennte B2B-Kataloge kann Medusa im Kern. Firmenkonten, Budgets, Freigaben und Angebote liefert der offizielle B2B Starter als Code, der Ihnen gehört. Rechnungskauf, Reverse Charge und E-Rechnung bauen Sie selbst oder holen Sie aus dem ERP. Und bevor Sie live gehen, prüfen Sie zwei Dinge: wer welche Bestellung lesen kann und ob Rabattcodes auf bereits verhandelte Preise greifen.
Was bringt Medusa für B2B von Haus aus mit?
Mehr, als die meisten erwarten, aber nicht alles, was die Marketingseite nahelegt. Die Trennlinie verläuft zwischen Kern, Starter und Projektarbeit:
| Anforderung | Wo es herkommt | Baustein |
|---|---|---|
| Kundenspezifische Preise | Kern | Kundengruppen + Preislisten + Preisregeln |
| Staffelpreise | Kern | min_quantity / max_quantity pro Preis |
| Eigener B2B-Katalog | Kern | Sales Channel + Publishable API Key |
| Netto-Preisanzeige | Kern | Steuer-inklusive bzw. -exklusive Preise pro Region/Währung |
| Bestellungen nachträglich ändern | Kern | Order Edits, Draft Orders |
| Firmenkonten, Mitarbeiter, Rollen | B2B Starter | Modul company |
| Budgets pro Mitarbeiter | B2B Starter | Spending Limits |
| Freigaben durch Einkaufsleitung oder Händler | B2B Starter | Modul approval |
| Angebote (RFQ) mit Verhandlung | B2B Starter | Modul quote |
| Rechnungskauf, Zahlungsziele | Projektarbeit | eigener Payment Provider |
| USt-IdNr. und Reverse Charge | Projektarbeit | eigener Tax Provider oder ERP |
| ERP-Preise und -Bestände | Projektarbeit | Workflows + Scheduled Jobs |
Medusas eigenes B2B-Rezept beschreibt den Kern-Teil genau so: ein eigener Sales Channel, damit B2B-Kunden nur B2B-Produkte sehen, eine Kundengruppe pro Firma und Preislisten mit dieser Gruppe als Bedingung. Für Firmen und Mitarbeiter empfiehlt die Dokumentation ausdrücklich ein eigenes Modul mit Modellen wie Company und Employee, verknüpft über Module Links. Das ist kein Mangel, sondern Medusas Prinzip: Der Kern modelliert Commerce, Ihre Organisationsstruktur modellieren Sie.
Was steckt im offiziellen B2B Starter?
Der B2B Starter ist eine vollständige Vorlage, kein Plugin: ein pnpm-Monorepo mit apps/backend und apps/storefront (Next.js 15), MIT-lizenziert. Im Backend liegen drei eigene Module, company, quote und approval, und am 19. Oktober 2026 steht es auf @medusajs/medusa 2.21.2, der aktuellen Version auf npm.
Der Funktionsumfang laut README: Firmenverwaltung mit eingeladenen Mitarbeitern, Ausgabelimits pro Mitarbeiter, Freigabe-Workflows (Firmen-Admins geben Warenkörbe frei, Händler geben Bestellungen vor dem Versand frei), Angebotsverwaltung mit Nachrichten zwischen Kunde und Händler, Bestellbearbeitung, Bulk-Add-to-Cart und Promotions. Den Angebotsprozess erklärt Medusa zusätzlich in einem eigenen Guide: Der Händler kann ablehnen oder ein Gegenangebot schicken, und nimmt der Kunde an, wird das Angebot zur Bestellung.
Altes Repository in vielen Tutorials
Viele Anleitungen verlinken noch auf medusajs/b2b-starter-medusa. Dieses Repository ist archiviert, als veraltet markiert und war zuletzt mit Medusa 2.4 getestet. Starten Sie mit medusajs/b2b-starter.
Lokal läuft der Starter in wenigen Minuten:
git clone https://github.com/medusajs/b2b-starter.git
cd b2b-starter && pnpm install
cp apps/backend/.env.template apps/backend/.env # DATABASE_URL setzen
cd apps/backend
pnpm medusa db:migrate
pnpm medusa user -e admin@example.com -p <passwort>
cd ../.. && pnpm dev # Admin: localhost:9000/app, Storefront: localhost:8000
Danach kopieren Sie im Admin unter Settings → Publishable API Keys den Schlüssel nach apps/storefront/.env.local. Wer Medusa noch nie aufgesetzt hat, findet die Grundlagen samt Postgres und Redis in meinem Medusa-Tutorial.
Die wichtigste Eigenschaft steht nicht im README: Der Starter ist ein Fork-Startpunkt. Sie übernehmen den Code, und ab dem ersten Commit gehört er Ihnen. Das ist gut, weil Freigabeketten in keinen zwei Firmen gleich aussehen. Es bedeutet aber auch, dass Updates des Starters nicht automatisch zu Ihnen kommen. Medusa-Updates ziehen Sie wie gewohnt über die Pakete, Verbesserungen an den Modulen company, quote und approval übernehmen Sie von Hand.
Wie bilden Sie Kundenpreise und Staffelpreise ab?
Über Preisregeln. Jeder Preis in Medusas Pricing-Modul kann Bedingungen tragen, etwa die Kundengruppe, und eine Mengenspanne. Die Dokumentation zu Preisregeln zeigt beides; zusammen ergibt das kundenspezifische Staffeln:
await pricingModuleService.addPrices({
priceSetId: "pset_schraube_m8",
prices: [
// Listenpreis für alle
{ amount: 49, currency_code: "eur" },
// Händlerpreis
{ amount: 42, currency_code: "eur", rules: { "customer.groups.id": "cusgrp_haendler" } },
// Händlerpreis ab 50 Stück
{
amount: 38,
currency_code: "eur",
min_quantity: 50,
rules: { "customer.groups.id": "cusgrp_haendler" },
},
],
})
Im Alltag legt das niemand per Code an. Preislisten pflegen Sie im Admin oder per CSV-Import, und Medusa kennt zwei Typen: sale zeigt den Listenpreis durchgestrichen daneben, override ersetzt ihn still. Für verhandelte B2B-Konditionen ist override fast immer richtig. Ein Geschäftskunde soll seinen Preis sehen, keinen Aktionsrabatt.
Wichtig für Ihre Storefront: Netto- oder Bruttoanzeige ist in Medusa eine Einstellung pro Region oder Währung (steuer-inklusive Preise), keine Frage des Templates. Ein B2B-Kanal mit Nettopreisen und ein B2C-Kanal mit Bruttopreisen im selben Backend sind damit sauber trennbar.
Welche vier Fallen sollten Sie vor dem Livegang kennen?
Keine davon ist ein Bug im engeren Sinn. Es sind Standardverhalten, die für einen B2C-Shop sinnvoll sind und im B2B-Kontext Geld oder Vertraulichkeit kosten.
Falle eins: Rabattcodes greifen auch auf verhandelte Preise. Eine Position im Warenkorb ist in Medusa standardmäßig rabattfähig, auch wenn ihr Preis aus einer Preisliste stammt. Ein Newsletter-Gutschein über 10 % landet also auf dem bereits um 18 % reduzierten Händlerpreis. Wir lösen das im Projekt mit dem MIT-lizenzierten Plugin @webbers/webbers-medusa: ein Schalter pro Preisliste, und ein eigener Add-to-Cart-Endpunkt setzt bei solchen Positionen is_discountable: false. Ob Sie ein Plugin nehmen oder es selbst bauen: Entscheiden Sie bewusst, ob Konditionen und Aktionen sich stapeln dürfen.
Falle zwei: Eine Bestellung ist für jeden lesbar, der ihre ID kennt. GET /store/orders/:id ist absichtlich ohne Anmeldung erreichbar. Medusa schreibt das direkt in den Quellcode und begründet es in einem eigenen Guide: Gastkunden haben keine Sitzung, und die Bestätigungsseite muss die Bestellung trotzdem laden. Die ID ist das Passwort. Bei einem B2C-Shop ist das ein vertretbarer Kompromiss. Im B2B wandern Bestell-IDs durch E-Mails, Tickets, ERP-Exporte und Weiterleitungen an Kollegen, und die Bestellung enthält Ihre verhandelten Preise. Der Guide empfiehlt eine Middleware, die Anmeldung und Eigentum prüft:
// src/api/middlewares.ts
import {
authenticate,
defineMiddlewares,
type AuthenticatedMedusaRequest,
type MedusaNextFunction,
type MedusaResponse,
} from "@medusajs/framework/http"
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/framework/utils"
async function ensureOrderOwner(
req: AuthenticatedMedusaRequest,
_res: MedusaResponse,
next: MedusaNextFunction
) {
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
const { data: [order] } = await query.graph({
entity: "order",
fields: ["customer_id"],
filters: { id: req.params.id },
})
if (!order || order.customer_id !== req.auth_context.actor_id) {
return next(new MedusaError(MedusaError.Types.NOT_FOUND, "Order not found"))
}
next()
}
export default defineMiddlewares({
routes: [
{
matcher: "/store/orders/:id",
method: ["GET"],
middlewares: [authenticate("customer", ["session", "bearer"]), ensureOrderOwner],
},
],
})
Zwei Details aus meinem Projekt, die im Guide nicht stehen. Erstens: Auch POST /store/orders/:id/transfer/request und .../transfer/cancel geben die vollständige Bestellung zurück und prüfen den Eigentümer nicht; wir haben sie mit derselben Regel abgesichert. Zweitens: Wer Gastbestellungen erlaubt, braucht eine Ausnahme, sonst bricht die Bestätigungsseite. Im reinen B2B-Shop mit Pflicht-Login stellt sich die Frage nicht.
Falle drei: Wer eine Preisliste besitzt, darf noch nicht jeden Preis darin setzen. Das betrifft Sie, sobald nicht nur Ihr eigenes Team Preise pflegt, sondern auch Händler, Vertriebsgesellschaften oder Marktplatz-Verkäufer. Prüfen Sie, ob Ihre Schreib-Endpunkte nur kontrollieren, dass die Preisliste dem Absender gehört, oder auch jede einzelne Preiszeile samt ihren Regeln. Preisregeln sind mächtig: Ein Preis ohne einschränkende Regel gilt für alle, ein Preis mit fremder Regel kann fremde Konditionen überschreiben. In unserem Projekt validiert deshalb eine Middleware vor jedem Schreibzugriff jede Zeile, nicht nur den Container. Wenn Sie einen B2B-Marktplatz mit Mercur planen, gehört dieser Test in die Abnahme; mehr zur Marktplatz-Seite steht in meinem Mercur-Leitfaden.
Falle vier: Individuelle Positionspreise sind eingefroren. Der B2B-Klassiker ist der Preis aus dem ERP: Die Storefront fragt beim Hinzufügen den Kundenpreis ab und setzt ihn als individuellen Positionspreis, Medusa vermarktet das als Custom line item pricing. Zwei Eigenschaften sollten Sie kennen, beide in unserem Projekt auf 2.21.2 nachgeprüft. Ein solcher Preis wird bei späterer Mengenänderung nicht neu berechnet; erhöht der Kunde von 10 auf 60 Stück, bleibt der Preis der 10er-Stufe stehen, bis Ihr Code ihn aktualisiert. Und wechselt der Warenkorb die Region, entfernt Medusas updateCartWorkflow Positionen mit is_custom_price, während normale Positionen bleiben. Beides ist lösbar, über einen Workflow-Hook bei Mengenänderung und eine klare Regel, wann Regionen wechseln dürfen. Es muss nur im Projektplan stehen.
Was fehlt für den deutschen Mittelstand?
Drei Themen, die in keinem englischen Medusa-Tutorial vorkommen und in fast jedem deutschen B2B-Projekt.
Rechnungskauf. Im deutschen B2B ist Zahlung auf Rechnung mit Zahlungsziel der Normalfall, nicht Kreditkarte. Anbieter wie Billie oder Mondu übernehmen Prüfung und Ausfallrisiko. Medusa bindet Zahlungsarten über Payment-Provider-Module an; ein offizielles, gepflegtes Plugin für Billie oder Mondu habe ich bei meiner Recherche nicht gefunden, nur Integrationsangebote von Agenturen. Planen Sie die Anbindung als eigenes Arbeitspaket. Die einfachste Variante für Bestandskunden ist oft eine Zahlungsart „Rechnung“ ohne externen Anbieter, freigeschaltet nur für bestimmte Kundengruppen, mit der Bonitätsprüfung dort, wo sie heute schon passiert: im ERP.
USt-IdNr. und Reverse Charge. Bei innergemeinschaftlichen Lieferungen an Unternehmen mit gültiger USt-IdNr. fällt keine deutsche Umsatzsteuer an. Medusas Steuermodul rechnet mit Steuersätzen pro Region und lässt sich über eigene Tax Provider erweitern; die Prüfung der USt-IdNr. (etwa gegen VIES) und die Reverse-Charge-Logik gehören nicht zum Kern. Das ist eine überschaubare Erweiterung, aber eine, die Ihr Steuerberater abnehmen sollte.
E-Rechnung. Seit dem 1. Januar 2025 müssen Unternehmen in Deutschland E-Rechnungen empfangen können. Ab 2027 müssen Unternehmen mit mehr als 800.000 € Vorjahresumsatz sie im B2B auch ausstellen, ab 2028 alle. Medusa erzeugt keine XRechnung und kein ZUGFeRD. In den meisten Mittelstandsprojekten ist das kein Problem, weil die Rechnung ohnehin im ERP entsteht und der Shop nur die Bestellung übergibt. Klären Sie diese Grenze aber am Anfang, nicht im Oktober 2026 kurz vor dem Stichtag.
Für die ERP-Anbindung selbst hat Medusa ein eigenes Rezept: Workflows für Bestellübergabe und Preisabfrage, Scheduled Jobs für Bestände und Stammdaten. Hier spielt Medusa seine Stärke aus. Eine Bestellübergabe als Workflow mit Kompensationsschritten ist robuster als das Cron-Skript, das in vielen Shopsystemen an einem Plugin-Hook hängt.
Medusa, Shopware oder Shopify Plus für B2B?
Die ehrliche Antwort hängt weniger an Funktionen als an Ihrem Team. Shopware liefert B2B-Komponenten fertig in seinen kommerziellen Plänen, und das deutsche Agenturnetz ist konkurrenzlos; die Details stehen in meinem Vergleich Medusa vs. Shopware. Shopify Plus hat ebenfalls B2B-Funktionen, rechnet sich aber über Abo und Umsatzgebühren anders; die Kostenrechnung Medusa vs. Shopify zeigt, ab wann.
Medusa gewinnt, wenn mindestens zwei dieser Punkte zutreffen:
- Ihre Freigabeketten, Budgets oder Preislogik passen in kein fertiges Modul.
- Das ERP ist die Wahrheit für Preise und Bestände, und der Shop soll sich ihm anpassen, nicht umgekehrt.
- Sie bedienen B2B und B2C aus einem Backend mit getrennten Kanälen.
- Ihr Team arbeitet in TypeScript oder Sie haben einen Partner, der es tut.
Trifft keiner zu, kaufen Sie lieber fertig. Ein Standard-B2B-Shop mit Kundenpreisen und Login braucht kein Framework.
Wie starten Sie ein B2B-Projekt mit Medusa?
Mit dem B2B Starter auf Ihrem eigenen Katalog, nicht mit Demo-Daten. Importieren Sie hundert echte Artikel, legen Sie drei echte Kundengruppen mit ihren Preislisten an und spielen Sie die eine Freigabekette durch, die in Ihrem Unternehmen am meisten Ärger macht. Danach wissen Sie, ob der Starter 70 % Ihres Bedarfs abdeckt oder 30 %. Und Sie testen die vier Fallen oben, bevor ein Kunde es tut.
Genau dafür gibt es den zweiwöchigen PoC-Sprint: Ihr Katalog, Ihre Preislogik, Ihr ERP-Anschluss als Prototyp, am Ende eine belastbare Aufwandsschätzung statt einer Hoffnung. Wenn Sie vorher sprechen wollen, buchen Sie ein Gespräch und bringen Sie Ihre komplizierteste Preisregel mit. Wo das Backend später läuft, klärt der Deployment-Vergleich, alle Artikel der Serie sammelt der Themenbereich E-Commerce, und den Systemüberblick jenseits von Medusa liefert mein Vergleich der Open-Source-Shopsysteme.

AI Agent & RAG Developer
AI Agent & RAG Developer mit über 10 Jahren Erfahrung in der Softwareentwicklung. Spezialisiert auf intelligente KI-Lösungen für Unternehmen im DACH-Raum.
Mehr über mich