Der Shopware-6-Rule-Builder deckt den Versand der meisten Shops ohne eine Zeile Code ab. Gewichtsbasierte Preise, Bestellwertgrenzen, Länderbeschränkungen, Gratisversand ab einem bestimmten Betrag. Für geradlinige Logistik ist das tatsächlich alles, was Sie brauchen.
Kürzlich habe ich ein Plugin für einen Kunden gebaut, dessen Produkte von 1-Liter-Behältern bis 65-Liter-Fässern reichten, verteilt auf 5 verschiedene Verpackungstypen mit jeweils eigener Kostenstruktur. Ihr Versand wurde von physischem Raum getrieben, und das lässt sich in keiner Konfigurationsoberfläche abbilden. Dieser Beitrag zeigt, wie eine individuelle Versandkostenberechnung in produktivem Shopware 6 tatsächlich aussieht und wie Sie erkennen, ob Sie eine brauchen.
Was Shopware standardmässig bietet
Ehre, wem Ehre gebührt: Das Versandsystem von Shopware ist flexibel. Der Rule Builder erlaubt Bedingungen über Gewicht, Warenkorbpreis, Artikelanzahl, Kundengruppe, Lieferland und mehr. Preismatrizen übersetzen diese Bedingungen in Versandkosten. Sie können mehrere Versandarten mit jeweils eigenen Regeln konfigurieren.
Die Einschränkung ist architektonisch. Diese Werkzeuge modellieren Versand als Lookup-Problem: Bedingungen abgleichen, Preis zurückgeben. Sie können Versand nicht als Optimierungsproblem modellieren: gegeben N Artikel mit unterschiedlichen Grössen, finde die günstigste Verpackungskombination.
Sobald Ihre Produkte radikal unterschiedliche physische Dimensionen haben und auf mehrere Verpackungstypen verteilt werden müssen, haben Sie das Territorium der Konfiguration verlassen und das Territorium der Algorithmen betreten.
Das Versand-Problem, das die Regeln brach
Der Kunde verkaufte physische Waren in Behältern von 1 bis 65 Litern, einige Produkte in übergrossen Varianten desselben Volumens. Versendet wurde über 5 Verpackungstypen: Paket, Halbe Palette, Europalette, Industriepalette und XXL-Palette. Jeder Typ mit eigenen Transportkosten.
Die Einschränkungen waren physisch. Ein 50-Liter-Behälter passt physisch nicht in ein Paket. Ein Kunde, der drei 1-Liter-Flaschen bestellt, sollte seine Lieferung nicht auf einer Europalette bekommen. Gemischte Warenkörbe mit kleinen und grossen Artikeln brauchen eine optimale Verteilung über die Verpackungstypen, um die Gesamtversandkosten zu minimieren.
Geografie kam als eigene Schicht dazu. Deutschland, Österreich und internationale Ziele hatten jeweils unterschiedliche Preisregeln. Deutsche Inselpostleitzahlen waren komplett gesperrt, weil Spediteure keine Paletten dorthin ausliefern. Gratisversand war auf Inlandsbestellungen beschränkt.
Keine Rule-Builder-Konfiguration kann ausdrücken: “Packe diese 14 Artikel in möglichst wenige Verpackungen aus 5 Typen, respektiere physische Grenzen und minimiere die Gesamtkosten.”
Raumverbrauch als Prozent-Problem
Der Schritt im Denken war, Produkte nicht mehr nach Gewicht oder festen Kategorien zu modellieren, sondern nach dem Prozentsatz, den sie von jedem Verpackungstyp einnehmen.
Ein 1-Liter-Behälter belegt 6,67 % eines Pakets, aber nur 0,83 % einer Europalette. Ein 50-Liter-Behälter belegt 0 % eines Pakets (passt gar nicht hinein), 100 % einer Halben Palette und 50 % einer Europalette. Jede der 17 Produktgrössen hat einen spezifischen Raumverbrauchs-Prozentsatz über alle 5 Verpackungstypen.
Damit wird die Versandkostenberechnung zu einer klaren Optimierung: füllen Sie Verpackungen bis 100 % Kapazität mit der günstigsten Kombination von Verpackungstypen.
Die übergrossen Varianten fügten eine weitere Dimension hinzu. Zwei Produkte mit gleichem Volumen, aber unterschiedlichem physischem Footprint verbrauchen unterschiedlich viel Raum. Ein Standard-15-Liter-Behälter und seine übergrosse Variante fassen beide 15 Liter, aber die übergrosse Version braucht deutlich mehr Platz in jedem Verpackungstyp.
Das ist ein Bin-Packing-Problem. Im allgemeinen Fall NP-schwer, aber mit einer begrenzten Anzahl Verpackungstypen und einer gierigen Heuristik erhalten Sie optimal genug innerhalb von Millisekunden.
Der Bin-Packing-Algorithmus in Shopwares Cart-Pipeline
Die Berechnung läuft bei jeder Warenkorb-Aktualisierung und folgt einer gierigen Strategie.
- Sortiere Produkte grösste zuerst. Die grössten Artikel sind am schwersten unterzubringen, deshalb platzieren wir sie zuerst, um verschwendeten Raum in späteren Runden zu minimieren.
- Prüfe bestehende Verpackungen, bevor neue geöffnet werden. Hat eine angefangene Europalette noch 50 % Platz und der nächste Artikel braucht 12,5 %, dann kommt er dort hinein, statt eine neue zu öffnen.
- Wähle den Verpackungstyp, der die Gesamtzahl minimiert. Für jeden Produktbatch bewertet der Algorithmus alle 5 Verpackungstypen und wählt den, der am wenigsten Verpackungen benötigt.
- Automatische Eskalation. Wenn die Paket-Anzahl 10 überschreitet, wechselt der Algorithmus auf Paletten. Dieser Schwellwert spiegelt eine reale Kosten-Schwelle: 10+ Einzelpakete kosten mehr als eine einzige Palettensendung.
- Verfolge verbleibende Kapazität in Prozent. Jede Verpackung hält ihren Füllstand, und nachfolgende Artikel werden in bestehenden Raum eingefügt, bevor neue Verpackungen alloziert werden.
Das Plugin implementiert Shopwares CartProcessorInterface und klinkt sich in die Cart-Pipeline ein, nachdem Produkte aufgelöst sind, und bevor die Bestellung finalisiert wird. Die Registrierung ist ein einzelner Service-Tag im DI-Container:
<service id="MyPlugin\Core\Cart\ShippingProcessor">
<argument type="service" id="MyPlugin\Service\DeliveryCalculationService"/>
<argument type="service" id="monolog.logger"/>
<tag name="shopware.cart.processor" priority="4500"/>
</service>
Die berechneten Kosten werden als manuelle Versandkosten-Override auf der Cart-Delivery gesetzt und ersetzen Shopwares native Berechnung vollständig. Die komplette Verpackungsaufstellung (wie viele von welchem Typ) wird als Cart-Extension gespeichert, damit sie in den Bestelldatensatz übergeht. Das Lagerteam weiss dadurch genau, welche Verpackungen vorzubereiten sind.
Länderregeln und Sonderfälle
Versandlogik ist nie nur Verpackung. Geografie fügt eine eigene Komplexitätsschicht hinzu.
Deutsche Inselpostleitzahlen werden zur Berechnungszeit aus einem kuratierten Datensatz geladen. Stimmt die Lieferadresse mit einer dieser Postleitzahlen überein, wird die Bestellung mit klarer Fehlermeldung blockiert. Spediteure liefern schlicht keine Paletten auf Inseln wie Sylt oder Helgoland, und ein Versuch würde zu fehlgeschlagenen Zustellungen und Retourenkosten führen.
Internationale Bestellungen werden auf Paket-Only-Modus gezwungen und fallen auf Shopwares native Versandpreis-Konfiguration zurück. Die Raumoptimierung läuft nur für innerdeutsche Sendungen, wo die volle Bandbreite an Verpackungstypen verfügbar ist.
Gratisversand-Aktionen sind auf Inlandsbestellungen beschränkt. Produkte mit Gratisversand-Flag zählen weiterhin in die Verpackungsberechnung (das Lager muss sie trotzdem packen und versenden), aber ihre Kosten fliessen nicht in die Gesamtkosten ein. Der Versuch, Gratisversand-Produkte international zu bestellen, löst einen blockierenden Fehler aus, damit die Aktion die Marge nicht still auffressen kann.
Jedes Versand-Plugin, das ich gebaut habe, hat mindestens eine Regel, die absurd klingt, bis man die Logistik dahinter versteht.
Wann man eine individuelle Versandlogik baut
Nicht jeder Shop braucht eine individuelle Versandlogik. So entscheide ich.
- Wenn Ihre Versandlogik als “wenn Bedingung, dann Preis” ausdrückbar ist, nutzen Sie den Rule Builder. Genau dafür ist er gebaut, und Konfiguration zu pflegen ist günstiger als Code zu pflegen.
- Wenn Ihre Logik Optimierung (minimiere Verpackungen), physische Einschränkungen (Artikel X passt nicht in Behälter Y) oder algorithmische Entscheidungen (eskaliere bei Schwellwert) beinhaltet, brauchen Sie individuellen Code.
Die gute Nachricht: Shopwares Architektur unterstützt das sauber. CartProcessorInterface existiert genau zu diesem Zweck. Eigene Entities für Verpackungstypen und deren Kosten erlauben dem Kunden, Preise über das Admin-Panel anzupassen, ohne Code zu ändern. Sie erweitern das Framework genau an der Stelle, wo Konfiguration an ihre Grenzen stösst.
Häufig gestellte Fragen
Wann brauche ich ein individuelles Versand-Plugin in Shopware 6? Wenn Ihre Versandlogik Optimierung (minimiere Verpackungen), physische Einschränkungen (Artikel X passt nicht in Behälter Y) oder algorithmische Entscheidungen (eskaliere bei Schwellwert) beinhaltet. Wenn sich alles als “wenn Bedingung, dann Preis” ausdrücken lässt, ist der Rule Builder das richtige Werkzeug.
Was ist CartProcessorInterface in Shopware 6? Es ist der Erweiterungspunkt in der Cart-Pipeline von Shopware 6 für eigene Warenkorb-Logik. Er läuft, nachdem Line Items aufgelöst sind, und bevor die Bestellung finalisiert wird, und ist damit der richtige Ort für individuelle Versandkostenberechnung, individuelle Rabatte oder virtuelle Line Items.
Kann Shopware 6 Versandkosten nach Volumen berechnen? Standardmässig nein. Shopwares Rule Builder modelliert Versand als Lookup: Bedingungen abgleichen, Preis zurückgeben. Volumenbasierter Versand erfordert einen eigenen CartProcessor, der Produkte als prozentualen Raumverbrauch über Verpackungstypen modelliert und einen Bin-Packing-Algorithmus laufen lässt.
Ist Bin-Packing wirklich NP-schwer für Versandberechnungen? Das allgemeine Bin-Packing-Problem ist NP-schwer. In der Praxis liefert eine Implementierung mit begrenzten Verpackungstypen und einer gierigen “grösste zuerst”-Heuristik optimal-genug-Ergebnisse in Millisekunden, und das ist, was produktive Versandberechnungen brauchen.
Wie blockiere ich den Versand an deutsche Inselpostleitzahlen in Shopware 6? Der Rule Builder kann eine Versandart nach Postleitzahl sperren, aber die komplette Liste deutscher Inselpostleitzahlen dort zu pflegen, ist fragil. Die Liste aus einem kuratierten Datensatz innerhalb eines eigenen CartProcessors zu laden, und die Bestellung mit einer klaren Fehlermeldung zu blockieren, ist wartbarer und lässt sich einfacher aktualisieren, wenn sich die Spediteur-Abdeckung ändert.
Über die breiteren Architekturregeln, denen ich folge, habe ich in meinem Shopware-Plugin-Entwicklungsansatz geschrieben. Dieselbe Engine treibt die automatisierte Dropshipping-Pipeline an, die ich für denselben Kunden gebaut habe, wo die Verpackungsaufstellung direkt in die Lieferanten-Routing-Logik einfliesst. Weitere Beispiele in den Fallstudien.
Wenn Ihre Versandlogik aus dem Admin-Panel herausgewachsen ist, nehmen Sie Kontakt auf.