B2B Onlineshop auf Solidus: Preislisten, Angebote, Zahlungsziele und Umsatzsteuer
Kurz gesagt
Niveau: Fortgeschritten
Ein Shop für Geschäftskunden ist kein Endkundenshop mit Rabatt. Mach die Firma zum Kunden, mit Nutzern, Rollen und Adressen darunter. Leg Vertragspreise in ausdrückliche Preislisten über den Price Selector von Solidus, nie in Promotions, die sich stapeln. Behandle ein Angebot als Bestellung vor dem Checkout mit eingefrorenen Preisen und Ablaufdatum. Bau Kauf auf Rechnung als Zahlungsart mit Kreditprüfung gegen Salden aus dem ERP. Entscheide die Umsatzsteuer pro Bestellung nach der Lieferadresse, mit VIES Prüfung und Zusammenfassender Meldung. Speichere Rechnungen als strukturierte Daten, denn die E Rechnung wird bis 2028 für alle Pflicht.
Großhandel funktioniert anders als Einzelhandel: Firmen mit mehreren Einkäufern, verhandelte Preise, Angebote, Rechnungen mit 30 oder 60 Tagen Ziel und eine Umsatzsteuer, die vom Lieferziel abhängt. In diesem Artikel bilde ich all das an einem erfundenen Hamburger Großhändler auf Solidus ab, zeige, was Solidus heute mitbringt und was eigener Code ist, gehe durch Verzug nach BGB, innergemeinschaftliche Lieferungen und die Übergangsfristen der E Rechnung und ende mit Reihenfolge, Kosten und den Fehlern, an denen B2B Shops scheitern.
Großhandel ist kein Einzelhandel mit Rabatt
Frag die großen Shopsysteme nach B2B, und du bekommst meist eine von zwei Antworten. Entweder ist es eine App, die einem Endkundenshop eine Login Sperre und einen Prozentrabatt verpasst und das Großhandel nennt. Oder es ist der obere Tarif, in dem die Funktionen zwar existieren, der Preis aber mit ihnen wächst.
Beides passt nicht zu einem Großhändler mit ein paar hundert Geschäftskunden. Was so ein Betrieb braucht, ist ein Shop, der fünf Dinge versteht: Eine Firma ist keine Person, ein Preis ist das Ergebnis einer Verhandlung, eine Bestellung beginnt oft als Angebot, die meisten Kunden zahlen auf Rechnung, und die Umsatzsteuer hängt davon ab, wohin die Ware tatsächlich geht.
Damit es greifbar wird, ein erfundenes Beispiel. Elbküche Großhandel (elbkueche.example) ist ein Hamburger Großhändler für Gastronomiebedarf und Kleingeräte mit rund 400 Geschäftskunden: Restaurants, eine Kölner Hotelgruppe mit zwölf Häusern, Schulcaterer in Leipzig und ein paar Kunden in Österreich und den Niederlanden. Heute arbeitet der Vertrieb mit Telefon, PDF und einer Tabelle. Elbküche begleitet uns durch den ganzen Artikel.
Vorab eine Warnung. Solidus, das quelloffene Rails Framework für Onlineshops, hat keinen "B2B Modus". Aktuell ist die Versionsreihe 4.8, Version 4.8.1 erschien am 5. November 2026.1 Was Solidus hat, sind schlichte Modelle für Bestellungen, Preise, Nutzer, Zahlungen und Steuern und eine Architektur, die erwartet, dass du sie erweiterst. Jede Funktion in diesem Artikel baut auf diesen Modellen auf. Das ist mehr Arbeit als ein Häkchen bei "Großhandel aktivieren". Es ist aber auch der Grund, warum das Ergebnis zu dem passt, wie deine Kunden wirklich einkaufen. Falls du meinen Shopsystemvergleich noch nicht kennst: Kurz gesagt ist Solidus die Plattform, die dir ganz gehört, und im B2B zahlt sich das am schnellsten aus.
Wie Geschäftskunden anders einkaufen
Schreib auf, was der Vertrieb von Elbküche an einem Tag macht, und der Abstand zum Endkundenshop wird sofort sichtbar.
Ein Kunde ist eine Firma mit mehreren Personen. Der Koch, der bestellt, ist nicht die Betriebsleiterin, die freigibt, und keiner von beiden bezahlt die Rechnung. Die Hotelgruppe hat die Regel, dass alles über 5.000 € eine zweite Unterschrift braucht.
Preise sind verhandelt. Ein Restaurant zahlt Liste minus 12 %. Die Hotelgruppe zahlt Liste minus 20 % auf Einwegartikel und Liste auf Geräte, weil das vor drei Jahren so vereinbart wurde. Der Schulcaterer hat feste Stückpreise für ein Jahr aus einem Rahmenvertrag.
Bestellungen beginnen oft als Angebot. Die Hotelgruppe fragt nach einem Preis für zwei Paletten Verpackungen frei Haus Köln, ein Außendienstler rechnet die Fracht, schickt ein Angebot, die Gruppe holt die Freigabe, und drei Wochen später wird daraus eine Bestellung. Die Angebotsnummer steht auf der Bestellung des Kunden, und die Rechnung muss beide nennen.
Fast niemand zahlt an der Kasse. Bezahlt wird auf Rechnung, 30 oder 60 Tage, gegen ein Kreditlimit, das jemand in der Buchhaltung vor Jahren gesetzt hat.
Wiederholungskäufe dominieren. Dieselben fünfzig Artikel alle zwei Wochen, in Kartons fester Größe, eingetippt nach Artikelnummer statt durchgeklickt.
Geliefert wird an viele Standorte. Ein Kundenkonto, zwölf Küchen, jede mit eigener Adresse und eigenem Lieferfenster.
Die Umsatzsteuer hängt am Ziel. Eine Lieferung nach Leipzig trägt deutsche Umsatzsteuer. Eine Lieferung nach Linz an einen Betrieb mit gültiger USt IdNr. kann eine steuerfreie innergemeinschaftliche Lieferung sein. Eine Lieferung in die Schweiz ist eine Ausfuhr. Falsch gemacht, ist die Rechnung falsch.
Und alles muss mit einem ERP oder der Buchhaltung sprechen, denn dort leben Bestand, Preise und offene Posten. Der Shop ist ein Fenster darauf.
Das Konto ist der Kunde, nicht der Nutzer
Die erste Modellierungsentscheidung trägt alles Weitere, und genau hier liegen Endkundensysteme von Haus aus daneben. Im Endkundenshop ist der Nutzer der Kunde. Im B2B ist die Firma der Kunde, und die Nutzer gehören zu ihr.
In Solidus modelliere ich das als Kundenkonto (manche Betriebe sagen Firma oder Kundengruppe), und jeder Nutzer gehört zu genau einem Konto mit einer Rolle: Einkäufer, Freigeber, Admin, manchmal eine Leserolle für jemanden, der die Bestellhistorie sehen, aber nicht bestellen soll. Adressen gehören zum Konto, sodass ein neuer Einkäufer in einer Filiale sofort die richtigen Lieferorte sieht. Bestellungen gehören zum Konto, mit dem Nutzer als Besteller. Preisliste, Kreditlimit, Zahlungsziel, USt IdNr. und der zuständige Außendienst liegen am Konto.
Das klingt selbstverständlich. Es ist der eine Punkt, auf dem ich bestehe, bevor irgendein anderer Code entsteht, denn das nachträglich in einen Shop einzubauen, in dem Nutzer die Kunden sind, heißt später jede Bestellung, jede Adresse und jede Preisabfrage anzufassen. Dieser Umbau kostet mehr als das Kontomodell am ersten Tag.
Freigabeketten leben ebenfalls hier. Die einfachste nützliche Form ist eine Schwelle am Konto: Bestellungen über einem Betrag warten auf Freigabe, und die Freigeberin bekommt eine Nachricht. Limits pro Einkäufer oder Freigaben pro Warengruppe sind möglich, aber ich würde sie erst bauen, wenn ein Kunde zweimal danach gefragt hat. Die meisten Geschäftskunden brauchen die Schwelle und sonst nichts.
Preislisten, und warum Promotions das falsche Werkzeug sind
Preise sind in Solidus ausdrückliche Datensätze. Jede Variante hat Preise, und jeder Preis trägt eine Währung und optional ein Land.2 Braucht der Shop einen Preis, wählt ein Price Selector den passenden aus, anhand eines kleinen Pricing Options Objekts, das standardmäßig die Währung und das Land der Steueradresse enthält. Beide Klassen sind konfigurierbar: Die Einstellung variant_price_selector_class bestimmt den Selector, und der Selector bestimmt seine Pricing Options Klasse.3 Das ist der Ansatzpunkt. Du gibst den Pricing Options ein drittes Merkmal, die Preisliste des Kontos, und bringst dem Selector bei, einen Preis aus dieser Liste vorzuziehen. Jede Preisabfrage im Warenkorb, im Admin und in der API liefert dann den Vertragspreis, ohne weiteren Aufwand.
Eine Preisliste ist also eine benannte Menge ausdrücklicher Preise pro Variante und Währung. Vertragsstufe A bekommt eine, Stufe B eine andere, und der Listenpreis ist einfach der Preis ohne Liste, den ein nicht angemeldeter Besucher sieht.
Gibt es eine Erweiterung, die das erledigt? Ich habe im November 2026 die Solidus Organisation und die Community Erweiterungen auf GitHub geprüft. Eine gepflegte Preislisten Erweiterung gibt es nicht. Am nächsten kommt solidus_volume_pricing, das Preise nach Mengenstaffel pro Variante setzt und Solidus 4 unterstützt.4 Vertragspreislisten sind eigener Code, grob ein paar hundert Zeilen mit Tests.
Die Alternative, die du in vielen Shops siehst, die B2B nur spielen: Listenpreis lassen und für die Kundengruppe eine Promotion anwenden. Lass das. Promotions sind gebaut, um befristet, bedingt, stapelbar und als Rabatt sichtbar zu sein. Vertragspreise sind nichts davon. Ein Koch will nicht "Liste 84,00 €, dein Rabatt 12 %" sehen. Er will 73,92 € sehen, auf der Produktseite, in der Suche, im Export, im Angebot und auf der Rechnung, jedes Mal dieselbe Zahl.
Promotions stapeln sich außerdem. Solidus liefert inzwischen ein überarbeitetes Promotion System als empfohlenes aus, sauberer aufgebaut als das alte, aber das Zusammenspiel von Vertragsrabatt und echter Aktion bleibt eine Geschäftsregel, die niemand aufgeschrieben hat.5 So sieht die Rechnung aus, wenn es schiefgeht. Zwei Prozentrabatte nacheinander multiplizieren sich, siehe Prozente in den Grundlagen:
Dabei ist der Preis, den der Kunde zahlt, der Listenpreis, der Vertragsrabatt und der Aktionsrabatt, beide als Anteil.
Für einen Artikel mit 84,00 € Listenpreis, 12 % Vertragsrabatt und einem Gratisversand Wochenende, das das Marketing als 10 % auf alles angelegt hat:
Der Kunde zahlt 66,53 €, also : ein effektiver Rabatt von 20,8 %, den niemand freigegeben hat, und die Buchhaltung muss erklären, warum die Rechnung nicht zum Vertrag passt.
Preislisten versteht auch das ERP. Jedes ernsthafte ERP kennt kundenspezifische Preise oder Preisgruppen, und die auf Solidus Preislisten abzubilden ist ein geradliniger Abgleich. Sie auf Promotion Regeln abzubilden ist es nicht.
Eine Gestaltungsregel: Halte die Zahl der Listen klein. Eine pro Vertragsstufe, nicht eine pro Kunde. Vierhundert Kunden mit vierhundert Listen sind nicht wartbar und machen den ERP Abgleich zum Engpass. Fünf bis zehn Stufen plus einige Abweichungen am Konto für einzelne Varianten reichen den meisten Großhändlern.
Verpackungseinheiten, Mindestmengen und was das Lager braucht
Geschäftskunden kaufen in Einheiten, die das Lager kommissionieren kann: Kartons mit 500 Bechern, Gebinde mit sechs Pfannen, ein Mindestbestellwert pro Lieferung. In Solidus sind das Merkmale der Variante und Prüfungen im Warenkorb. Die Variante kennt ihre Verpackungseinheit und Mindestmenge, der Warenkorb rundet auf oder lehnt unpassende Mengen ab, und die Produktseite sagt, was eine Einheit enthält. Der Mindestbestellwert pro Lieferung ist eine Regel am Konto oder an der Bestellung, die den Checkout sperrt. Mengenstaffeln, bei denen 100 Kartons pro Stück weniger kosten als 10, erledigt solidus_volume_pricing bereits.4
Nichts davon ist schwer. Es ist ein Tag Arbeit mit Tests, der dem Lager jeden Tag eine Stunde spart, und es fehlt fast immer in der ersten Spezifikation.
Ein Angebot ist eine Bestellung, die noch nicht aufgegeben ist
Der übliche Weg für Angebote ist die Mail. Der Einkäufer fragt, der Außendienst antwortet mit einem PDF, der Einkäufer sagt ja, jemand tippt die Bestellung von Hand ab. Das geht gut, bis der Außendienstler im Urlaub ist, PDF und Bestellung nicht übereinstimmen oder der Kunde bestreitet, was angeboten wurde.
Eine Solidus Bestellung hat eine Zustandsmaschine. Ihr Checkout läuft vom Warenkorb über Adresse, Versand, Zahlung (nur wenn eine Zahlung nötig ist) und Bestätigung bis zum Abschluss, und dieser Ablauf ist in einem einzigen Block des Bestellmodells definiert, den ein Shop ändern kann.6 Ein Angebot ist also eine Bestellung, die vor dem Checkout gehalten wird, mit einem Angebotsdatensatz daneben: Angebotsnummer, Ablaufdatum, die zum Angebotszeitpunkt eingefrorenen Preise, die berechnete Fracht und wer das Angebot erstellt hat. Der Einkäufer sieht es in seinem Konto. Nimmt er an, läuft es in den normalen Checkout mit allem vorausgefüllt, oder er bittet um Änderungen und es geht zurück an den Außendienst. Bei Abschluss verweist die Bestellung auf die Angebotsnummer, und beide stehen auf der Rechnung.
Angebote entstehen im Admin: Konto wählen, Positionen hinzufügen, einen Preis mit Begründung überschreiben, Fracht ergänzen, Ablaufdatum setzen, senden. Dieser Angebotseditor ist das größte Einzelstück eines B2B Projekts, und die Zeit ist gut investiert, weil der Vertrieb darin lebt.
Zwei Details zählen. Eingefrorene Preise: Das Angebot speichert seine eigenen Preise, damit eine Preislistenänderung vor der Annahme nichts am Versprochenen ändert. Ablauf: Angebote verfallen automatisch, mit einer Erinnerung ein paar Tage vorher, denn ein altes Angebot zu alten Preisen ist der Weg, auf dem Marge leise verschwindet.
Zahlungsziele sind eine Zahlungsart mit Kreditlimit dahinter
An der Kasse tippt ein Geschäftskunde keine Karte ein. Er wählt "Rechnung, 30 Tage" und erwartet, dass die Bestellung durchgeht. In Solidus ist eine Zahlungsart eine Klasse mit festgelegter Schnittstelle. Der Kern liefert sogar eine minimale für Schecks mit, die keine Karte und keine andere Zahlungsquelle braucht und Einzug, Storno und Gutschrift einfach als erfolgreich verbucht.7 Eine Zahlungsart für Kauf auf Rechnung beginnt mit dieser Idee und ergänzt das, was der Scheckmethode fehlt: eine Kreditprüfung.
Das Konto trägt Kreditlimit und Zahlungsziel, 30 oder 60 Tage, bei Neukunden manchmal 14. Die Zahlungsart vergleicht offene Posten plus diese Bestellung mit dem Limit. Passt es, wird die Zahlung autorisiert und die Bestellung abgeschlossen. Passt es nicht, wird die Bestellung gehalten und die Buchhaltung benachrichtigt. Der Kunde sieht einen höflichen Hinweis, keine Ablehnung.
Solidus bringt außerdem Guthaben als eigene Zahlungsart mit.8 Das hilft bei Gutschriften und Vorauszahlungen: Eine Erstattung als Guthaben wird beim nächsten Checkout verrechnet, ohne dass jemand sie von Hand bucht.
Offene Posten heißt, der Shop muss wissen, was berechnet und was bezahlt ist. Das verlässliche Muster: ERP oder Buchhaltung sind die Quelle der Wahrheit für Salden, und der Shop gleicht sie nach Zeitplan und noch einmal im Checkout ab. Den Shop zum Hauptbuch zu machen ist ein Fehler. Er ist keine Buchhaltung.
Das Mahnwesen gehört ebenfalls in die Buchhaltung. Der Shop braucht nur das Ergebnis: Ein Konto, das wegen überfälliger Rechnungen gesperrt ist, kann nicht auf Ziel bestellen, bis es frei ist. Das ist ein Merkmal am Konto und eine Prüfung in der Zahlungsart.
Wie Endkunden in Deutschland und Österreich bezahlen wollen, inklusive Kauf auf Rechnung, steht in meinem Artikel zu Zahlungsarten in Solidus.
Was das BGB dir bei verspäteter Zahlung gibt
Zahlungsziele sind nur die halbe Geschichte. Die andere Hälfte ist, was passiert, wenn sie nicht eingehalten werden. Ein Schuldner, der kein Verbraucher ist, kommt spätestens in Verzug, wenn er nicht innerhalb von 30 Tagen nach Fälligkeit und Zugang einer Rechnung zahlt (§ 286 Abs. 3 BGB).9 Eine Vereinbarung, nach der du die Zahlung erst nach mehr als 60 Tagen verlangen kannst, ist nur wirksam, wenn sie ausdrücklich getroffen wurde und für dich nicht grob unbillig ist (§ 271a BGB).10
Im Verzug beträgt der Zinssatz zwischen Unternehmen neun Prozentpunkte über dem Basiszinssatz, und dazu kommt eine Pauschale von 40 € (§ 288 Abs. 2 und Abs. 5 BGB).11 Verzugszinsen sind einfache Zinsen, ein Satz anteilig auf die Tage gerechnet (siehe Verhältnisse und Raten):
Dabei ist der Zinsbetrag, die offene Forderung, der Basiszinssatz als Anteil und die Zahl der Verzugstage.
Die Hotelgruppe schuldet Elbküche 12.400 € und zahlt 45 Tage zu spät. Bei einem angenommenen Basiszinssatz von 2 %:
Also sind gleich 168,16 € Zinsen, dazu die Pauschale von 40 €. Ob Elbküche das bei einem Kunden mit zwölf Häusern wirklich fordert, ist eine kaufmännische Entscheidung. Aufgabe des Shops ist, das Zahlungsziel auf jede Rechnung zu schreiben, damit die Möglichkeit besteht.
Umsatzsteuer, entschieden durch das Lieferziel
Jetzt der Teil, bei dem Steuerberater nervös werden. Die folgenden Regeln sind die allgemeine Lage für einen deutschen Unternehmer, der Waren liefert. Lass sie für deine Produkte vor dem Start von deiner Steuerberatung bestätigen.
Im Inland. Lieferungen an deutsche Unternehmen tragen den Regelsteuersatz von 19 % (§ 12 Abs. 1 UStG).12 Die USt IdNr. des Kunden ändert daran nichts.
An Unternehmen in anderen EU Staaten. Eine innergemeinschaftliche Lieferung ist steuerfrei (§ 4 Nr. 1 Buchst. b UStG), wenn die Voraussetzungen des § 6a UStG erfüllt sind: Die Ware gelangt in einen anderen Mitgliedstaat, der Abnehmer ist dort für Umsatzsteuerzwecke erfasst, und er verwendet dir gegenüber eine gültige USt IdNr. eines anderen Mitgliedstaats.13 Dazu kommt eine Bedingung, die viele übersehen: Die Befreiung gilt nicht, wenn du die Zusammenfassende Meldung für diese Lieferung nicht, falsch oder unvollständig abgegeben hast.14 Die Meldung geht bis zum 25. Tag nach Ablauf jedes Monats an das Bundeszentralamt für Steuern, vierteljährlich nur, solange die innergemeinschaftlichen Lieferungen weder im laufenden noch in einem der vier vorangegangenen Quartale mehr als 50.000 € betragen (§ 18a UStG).15
Die gültige USt IdNr. prüfst du über VIES, das Bestätigungssystem der EU Kommission.16 VIES ist langsam und fällt gelegentlich aus. Prüfe deshalb bei der Kontoanlage und danach regelmäßig, nicht bei jedem Checkout, und speichere Ergebnis und Zeitpunkt als Nachweis.
In die Schweiz oder nach Großbritannien. Das ist eine Ausfuhrlieferung, steuerfrei nach § 4 Nr. 1 Buchst. a in Verbindung mit § 6 UStG, wenn der Ausfuhrnachweis vorliegt.17 Einfuhrumsatzsteuer und Zoll trägt im Normalfall der Kunde in seinem Land.
Und § 13b? Die Formulierung "Steuerschuldnerschaft des Leistungsempfängers" gehört nicht auf die Rechnung einer innergemeinschaftlichen Warenlieferung. Sie gilt, wenn die Steuer in einem anderen Mitgliedstaat vom Leistungsempfänger geschuldet wird, typischerweise bei Dienstleistungen an Unternehmen dort (§ 14a Abs. 1 UStG), und bei den Inlandsfällen des § 13b UStG. Verkauft Elbküche zur Ware eine Montage an den Kunden in Linz, braucht genau diese Position den Hinweis.
Daraus folgt die Shoplogik. Die Steuer wird pro Bestellung über die Lieferadresse entschieden, nie über das Land am Konto. Lässt sich der österreichische Kunde an seine Filiale in Köln liefern, verlässt die Ware Deutschland nicht, und es gilt deutsche Umsatzsteuer.
In Solidus kommt die Steuer aus Steuersätzen, die an Zonen (Mengen von Ländern oder Regionen) und Steuerkategorien hängen, und die Klasse, die Steuern auf eine Bestellung anwendet, ist über die Einstellung tax_adjuster_class austauschbar.3 Mein Muster: eine Inlandszone mit den normalen Sätzen, eine EU Zone, deren Nullsatz nur greift, wenn das Konto eine geprüfte USt IdNr. aus dem Lieferland hat, und eine Drittlandszone für Ausfuhren. Jeder Fall ist eine ausführbare Spezifikation mit Tests, damit die Inhaberin in klarem Deutsch lesen kann, welche Bestellung wie behandelt wird.
Rechnungen, die eine Buchhaltung annimmt
Ein Endkundenshop kommt mit einer Bestellbestätigung durch. Ein B2B Shop nicht. § 14 Abs. 4 UStG zählt die Pflichtangaben auf, darunter eine fortlaufende, einmalige Rechnungsnummer, Name und Anschrift beider Seiten, deine Steuernummer oder USt IdNr., Liefer und Rechnungsdatum, Menge und Bezeichnung, die Entgelte nach Steuersätzen, den Steuerbetrag und bei einer Steuerbefreiung einen Hinweis darauf.18 Für eine innergemeinschaftliche Lieferung gehören zusätzlich die USt IdNr. beider Seiten auf die Rechnung, und sie muss bis zum 15. Tag des Folgemonats ausgestellt sein (§ 14a Abs. 3 UStG).19 Fehlt etwas, bekommt der Kunde Probleme mit dem Vorsteuerabzug, und eine Rechnung, aus der er keine Vorsteuer ziehen kann, schickt er zurück.
Fortlaufende Nummern heißen, der Shop kann nicht die Bestellnummer verwenden, weil Bestellungen storniert werden und Nummern fehlen. Rechnungen sind ein eigenes Modell mit eigener Nummernfolge, erzeugt beim Versand, danach nie geändert. Korrekturen laufen über Rechnungskorrekturen mit eigener Folge.
Dann die E Rechnung. Seit dem 1. Januar 2025 ist eine elektronische Rechnung in Deutschland nur noch eine Rechnung in einem strukturierten elektronischen Format, und inländische Unternehmen müssen solche Rechnungen empfangen können.20 Beim Ausstellen gelten Übergangsfristen: Für Umsätze bis Ende 2026 sind Papier und, mit Zustimmung des Empfängers, andere elektronische Formate noch erlaubt. Für Umsätze im Jahr 2027 gilt das nur noch, wenn dein Gesamtumsatz im Vorjahr höchstens 800.000 € betrug, sowie für EDI Verfahren (§ 27 Abs. 38 UStG).21 Ab 2028 stellt also jeder deutsche Großhändler seinen inländischen Geschäftskunden strukturierte Rechnungen aus, als XRechnung oder ZUGFeRD.
Die praktische Folge: Speichere die Rechnung vom ersten Tag an als strukturierte Daten, mit jeder Pflichtangabe ausdrücklich abgelegt, damit PDF, ZUGFeRD oder reine XRechnung eine Frage der Darstellung sind und kein Umbau. Erzeugt das ERP bereits Rechnungen, soll der Shop keine zweite Reihe anlegen. Er übergibt die abgeschlossene Bestellung ans ERP und zeigt dem Kunden die Rechnung des ERP. Zwei Nummernkreise für denselben Betrieb sind ein Durcheinander.
Schnellbestellung, Datei Upload und Nachbestellung
Geschäftskunden stöbern nicht. Drei Funktionen decken fast alles ab, was sie tun.
Eine Schnellbestellung: ein Raster, in das der Einkäufer Artikelnummern und Mengen tippt oder einfügt, der Shop prüft jede Zeile gegen Sortiment und Preisliste, markiert Unbekanntes oder nicht Lieferbares und legt alles auf einmal in den Warenkorb. Sie gehört auf die erste Seite nach dem Login.
Datei Upload: dasselbe aus einer CSV Datei, weil manche Einkäufer ihren Bedarf aus dem eigenen System exportieren. Nimm auch die Artikelnummern des Kunden an, mit einer Zuordnungstabelle am Konto, denn große Kunden nummerieren für dich nicht um.
Nachbestellung: ein Klick legt die Positionen einer früheren Bestellung zu heutigen Preisen in den Warenkorb, mit klarem Hinweis auf alles, was sich bei Preis oder Verfügbarkeit geändert hat. Zusammen mit gespeicherten Listen ist das fast alles, was ein Kunde im Zweiwochentakt im Shop macht.
Alle drei sind gewöhnliche Rails Funktionen auf dem Solidus Warenkorb. Keine kommt fertig mit, und alle drei gehören in die erste Phase.
Außendienst bestellt im Auftrag des Kunden
Ein B2B Shop ersetzt den Vertrieb nicht. Er gibt ihm ein besseres Werkzeug. Der Außendienst muss seine Konten sehen, Angebote erstellen, für einen Kunden bestellen, der angerufen hat, und sehen, was offen ist. Das ist eine Admin Rolle, beschränkt auf die zugeordneten Konten, mit einer Funktion "im Namen von", die festhält, wer welche Bestellung aufgegeben hat.
Die Nachvollziehbarkeit zählt. Bestellt der Außendienst für einen Kunden, hält die Bestellung fest, wer bestellt hat, welche Kontaktperson beim Kunden das veranlasst hat und wie (Anruf, Nachricht mit Referenz). Wird die Rechnung sechs Wochen später bestritten, entscheidet dieser Eintrag.
Sichtbarkeit des Sortiments, und der teuerste SEO Fehler
Der teuerste Fehler in B2B Shops ist eine Grundsatzentscheidung, keine technische: das ganze Sortiment hinter einen Login zu stellen.
Die Begründung ist nachvollziehbar. Händlerpreise sind vertraulich, und Endkunden sollen nicht bestellen. Also verschwindet der ganze Shop hinter dem Login und wird unsichtbar für Suchmaschinen, für Interessenten und für die Einkäuferin einer neuen Restaurantgruppe, die abends um neun Lieferanten recherchiert.
Die Lösung trennt Sichtbarkeit und Preis. Das Sortiment ist öffentlich: Produkte, Datenblätter, Bilder, Verfügbarkeit, alles, was ein Interessent für die Entscheidung braucht, dass sich ein Anruf lohnt. Preise sehen nur angemeldete Konten, oder ein Listenpreis ist öffentlich mit dem Hinweis, dass Händlerpreise auf Anfrage gelten. Bestellen braucht ein Konto. Jede Produktseite bleibt indexierbar, die Anfragen kommen weiter, und verhandelte Preise bleiben privat.
Kontospezifische Einschränkungen, bei denen ein Kunde nur die Warengruppen aus seinem Vertrag sieht, sind eine eigene, legitime Funktion: eine Sichtbarkeitsregel pro Konto auf einem öffentlichen Sortiment, kein Grund, alles zu verstecken. Was ich zum B2B Vertrieb in Deutschland geschrieben habe, dass der Einkauf seine Hausaufgaben vor dem ersten Gespräch macht, gilt für Gastronomiebedarf genauso wie für Software.
ERP Anbindung und wem welche Daten gehören
Die Anbindung an ERP oder Buchhaltung ist oft der größte Einzelteil eines B2B Projekts. Was sie beherrschbar hält, ist die Entscheidung, welches System für welche Daten die Quelle der Wahrheit ist.
Produkte und Bestand: das ERP, fast immer. Der Shop übernimmt Sortiment und Bestand nach Zeitplan und per Webhook, wo das ERP es kann, und bearbeitet sie nie.
Preise: das ERP, wenn es kundenspezifische Preise kennt. Der Shop übernimmt die Preislisten. Ist die Preislogik des ERP zu grob, führt der Shop die Preise und schreibt sie zurück, was mehr Sorgfalt braucht.
Kundenkonten: meist das ERP für Stammsatz, Kreditlimit und Zahlungsziel, der Shop für Nutzer, Rollen und Adressen, die das ERP nicht abbildet.
Bestellungen: entstehen im Shop, gehen bei Abschluss ans ERP, und die Auftragsnummer des ERP wird zurückgeschrieben. Lieferungen, Rechnungen und Zahlungen fließen zur Anzeige zurück.
Die Anbindung selbst sind gewöhnliche Rails Hintergrundjobs: idempotent, protokolliert, mit einer Admin Seite, die jeden Fehler zeigt und einen neuen Versuch erlaubt. Über diese Art von Infrastruktur habe ich in meinem Artikel zu Background Workers geschrieben. Ob das ERP eine moderne API hat oder nachts eine CSV Datei auf einen Server legt, das Muster ist dasselbe, nur der Transport unterscheidet sich.
Punchout, bei dem das Beschaffungssystem eines Großkunden deinen Shop in sich öffnet und den Warenkorb als Bestellanforderung zurückholt, kommt bei Konzernkunden auf. Es nutzt festgelegte Protokolle (im deutschsprachigen Raum meist OCI, sonst cXML) und ist eine gut abgegrenzte Funktion, die du ergänzt, wenn ein Kunde danach fragt. Bau sie nicht auf Verdacht.
Was zuerst gebaut wird
Für einen Großhändler wie Elbküche ist das die Reihenfolge.
Phase eins, das Fundament: Kontomodell mit Nutzern, Rollen und Adressen, öffentliches Sortiment mit Preisen hinter dem Login, Preislisten, Verpackungseinheiten und Mindestmengen, Schnellbestellung und Nachbestellung, Kauf auf Rechnung mit Kreditprüfung, USt IdNr. Prüfung und die Steuerzonen, strukturierte Rechnungen und ein einseitiger ERP Abgleich für Produkte, Bestand und Preislisten, mit Bestellungen in die andere Richtung. Auf diesen Shop können die bestehenden Kunden umziehen.
Phase zwei, der Vertrieb: Angebotseditor und Weg vom Angebot zur Bestellung, Außendienstansichten mit "im Namen von", Freigabeschwellen, gespeicherte Listen, Datei Upload mit Kundenartikelnummern und der Abgleich erweitert um Rechnungen und Salden.
Phase drei, wenn Kunden fragen: kontospezifische Sortimente, Mengenstaffeln, Punchout, XRechnung und ZUGFeRD aus dem Shop, falls das ERP es nicht schon kann, weitere Währungen, und was die ersten sechs Monate echter Bestellungen zeigen.
Phase eins ist der Teil, den man sorgfältig baut und gründlich testet, weil er mit Geld und Steuer umgeht. Jede Regel darin bekommt eine ausführbare Spezifikation, die die Inhaberin lesen kann. Phase drei bleibt bewusst offen, weil echte Kunden sie bestimmen sollen.
Was es kostet
Mein veröffentlichter Stundensatz für Entwicklung liegt bei 195 €.22 Was ein B2B Projekt kostet, hängt vom Umfang ab: wie viele Preislisten es gibt und wie sie abgeglichen werden, ob Angebote schon in die erste Phase gehören, wie Zahlungsziele und Kreditprüfung an das ERP angebunden sind und welche Umsatzsteuerfälle der Shop abdecken muss. Ein unordentliches ERP treibt jeden Teil nach oben. Deshalb nenne ich keine Pauschale. Ich kläre den Umfang mit dir und biete ihn zu diesem Stundensatz an, und genau dafür sind der kostenlose Workshop und die ersten zwei Wochen Arbeit da.
Vergleich das ehrlich mit den Alternativen. Shopify bietet B2B inzwischen auch in den Tarifen Basic, Grow und Advanced an, mit Zahlungszielen und Mengenregeln in allen. Diese Tarife erlauben aber höchstens drei aktive Kataloge über alle B2B Märkte, und einen Katalog direkt einer bestimmten Firma zuzuweisen, was Vertragspreise brauchen, geht nur in Plus.23 Plus beginnt in Euro bei 2.100 € im Monat, über fünf Jahre also 126.000 €, bevor irgendetwas gebaut ist.24 Shopware legt seine B2B Komponenten wie Angebote und Bestellfreigaben in den Tarif Evolve, ab 2.400 € im Monat zuzüglich Umsatzsteuer.25
Das Geld fließt bei Solidus in deine eigenen Funktionen, getestet und dokumentiert, auf Infrastruktur, die du kontrollierst, und der individuelle Code, den ich schreibe, gehört dir nach vollständiger Bezahlung. Im ersten Jahr ist das selten die niedrigste Zahl. Im dritten Jahr oft schon, und es ist die Variante, bei der der Angebotseditor so arbeitet wie dein Vertrieb.
Ein Wort zu Demos: Ich baue gerade eine Reihe von Solidus Demo Shops, und eine für Großhandel ist geplant. Sie sind noch in Arbeit und nicht für Besucher geöffnet.
Die Fehler, gesammelt
Das ganze Sortiment hinter einem Login. Es kostet Sichtbarkeit in der Suche und eingehende Anfragen.
Eine Preisliste pro Kunde. Nicht wartbar. Nimm Stufen und Abweichungen am Konto.
Vertragspreise als Promotions. Sie stapeln sich mit echten Aktionen, verwirren die Rechnung und brechen den ERP Abgleich.
Angebote per Mail. Niemand findet sie, Preise driften, Streit lässt sich nicht klären.
Umsatzsteuer nach dem Land am Konto statt nach der Lieferadresse. Das ergibt falsche Rechnungen, sobald ein Kunde einen Standort in einem anderen Land hat.
Die Zusammenfassende Meldung vergessen. Ohne richtige Meldung entfällt die Steuerbefreiung der innergemeinschaftlichen Lieferung.
Rechnungsnummern aus Bestellnummern. Lücken in der Folge, sobald Bestellungen storniert werden.
Rechnungen als PDF Vorlagen statt als strukturierte Daten. Spätestens mit der Pflicht zur E Rechnung beginnt der Umbau.
Der Shop als Hauptbuch. Salden und Mahnungen leben in der Buchhaltung, der Shop liest sie.
Punchout, Mengenstaffeln und aufwendige Freigaben bauen, bevor jemand fragt. Spekulative B2B Funktionen liegen in den Details meist daneben, und die Details sind der ganze Punkt.
Nur Kartenzahlung. Der Einkäufer hat keine Firmenkarte. Er hat einen Beschaffungsprozess mit einer Rechnung darin.
Warum Solidus zu dieser Arbeit passt
All das lässt sich auf jedem Framework bauen. Solidus passt zu B2B, weil es nicht gegen dich arbeitet. Der Checkout ist darauf ausgelegt, geändert zu werden. Der Price Selector ist ein benannter Erweiterungspunkt. Zahlungsarten sind Klassen mit festgelegter Schnittstelle. Die Steueranwendung ist eine austauschbare Klasse. Nutzer, Rollen und Rechte sind gewöhnliches Rails. Jede Funktion in diesem Artikel passt an eine Stelle, die das Framework dafür freigelassen hat, mit Tests, ohne um die Annahmen eines Anbieters herumzuarbeiten, wie Menschen einkaufen.
Das heißt eine eigene Plattform in der Praxis: Der Shop passt sich dem Betrieb an, nicht der Betrieb dem Shop. Im B2B, wo jeder Kunde eigene Konditionen hat und jede Bestellung eine kleine Verhandlung ist, ist das der Unterschied zwischen einem Shop, den der Vertrieb nutzt, und einem, um den er herumarbeitet.
Wenn du deine Preislisten, Zahlungsziele und Rechnungen mit mir durchgehen willst: Ich biete einen kostenlosen Workshop an, und die ersten zwei Wochen Arbeit gehen auf mich.