shopwaree-commercephpversandlogistik

Individuelle Shopware Versandkostenberechnung: Wenn Regeln nicht mehr reichen

| 6 Min. Lesezeit | Huzaifa Mustafa

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.

Doch kürzlich habe ich ein Plugin für einen Kunden gebaut, dessen Produkte von 1-Liter-Behältern bis zu 65-Liter-Fässern reichten, verteilt auf fünf verschiedene Verpackungstypen mit jeweils eigener Kostenstruktur. Ihr Versand drehte sich nicht um Gewicht oder Warenkorbwert. Es ging um physischen Raum, und das lässt sich in keiner Konfigurationsoberfläche abbilden. Dieser Beitrag zeigt, wie eine individuelle Versandkostenberechnung in produktivem Shopware 6 tatsächlich aussieht.

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, kein fehlendes Feature. 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 Shopware 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 fünf Verpackungstypen: Paket, Halbe Palette, Europalette, Industriepalette und XXL-Palette. Jeder Typ mit eigenen Transportkosten.

Die Einschränkungen waren physisch, nicht kommerziell. 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.

Dazu kam: 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 Schlüssel war, Produkte nicht länger nach Gewicht oder festen Kategorien zu denken, 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 fünf Verpackungstypen.

Damit wird die Versandkostenberechnung zu einer klaren Optimierung: Fülle 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 fünf Verpackungstypen und wählt den, der am wenigsten Verpackungen benötigt.
  • Automatische Eskalation. Wenn die Paket-Anzahl 10 überschreitet, wechselt der Algorithmus auf Paletten. Kein willkürlicher Schwellwert, sondern eine reale Spediteurs-Beschränkung: 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, aber 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. Der Spediteur liefert 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, statt stillschweigend eine Aktion anzuwenden, die die Marge auffrisst.

Jedes Versand-Plugin, das ich gebaut habe, hat mindestens eine Regel, die absurd klingt, bis man die Logistik dahinter versteht.

Wann man eine individuelle Shopware 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 bedeuten, dass der Kunde Preise über das Admin-Panel anpassen kann, ohne Code zu ändern. Das Framework kämpft nicht gegen Sie. Sie erweitern es nur genau an der Stelle, wo Konfiguration an ihre Grenzen stösst.

Über die breiteren Architekturregeln, denen ich folge, habe ich in meinem vorherigen Beitrag zur Shopware Plugin-Entwicklung 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 dieser Art in meinen Fallstudien.

Die besten Shopware-Plugins ersetzen das Framework nicht. Sie erweitern es genau dort, wo Konfiguration an ihre Grenzen stösst. Wenn Ihre Versandlogik aus dem Admin-Panel herausgewachsen ist, lassen Sie uns sprechen.

Artikel teilen

Fanden Sie das hilfreich? Teilen Sie es mit Ihrem Netzwerk

Huzaifa Mustafa

Huzaifa Mustafa

Shopware 6 zertifizierter Entwickler mit 162+ individuellen Plugins und 95+ Kunden in der DACH-Region. Ich schreibe über Shopware-Architektur, E-Commerce-Performance und Erfahrungen aus realen Projekten.

Brauchen Sie Hilfe mit Shopware?

Lassen Sie uns besprechen, wie ich bei Ihrem E-Commerce-Projekt helfen kann.