If two suppliers in your Shopware 6 shop stock the same product at the same price, who gets the order?
For most teams running Shopware 6, the answer is: the same supplier, every single time. The default. It is simple. It is also unfair, and it makes the whole fulfillment operation brittle. When that default supplier hits a stock shortage or falls behind on shipping, you find out late, because every order in Shopware still flows through them.
Supplier rotation is how you fix that. I built this exact system as a custom Shopware 6 plugin for a shop that needed to spread orders across multiple wholesalers and contract manufacturers. The logic is small once you strip the engineering jargon out. This is the operator-friendly version. If you run a Shopware 6 store, manage a factory floor, or coordinate orders across overlapping suppliers, this is what you actually need to know.
Why Shopware 6 does not solve this out of the box
Shopware 6 is excellent at the order itself: the cart, the checkout, the payment, the line-item math. What it does not ship with is multi-supplier order routing.
The default order workflow assumes one fulfillment path. If you sell a product that 3 suppliers all carry, Shopware 6 has no opinion about which one gets the order. Most teams paper over that by hard-coding a default supplier in their fulfillment plugin. Within a few weeks, that supplier has 90% of the volume.
Three things go wrong from there.
First, you lose visibility into the other two suppliers. Their stock data goes stale. Their reliability stays unknown until you actually need them.
Second, the favorite gets overloaded. Lead times stretch. Defects creep up. The very thing that earned them the default slot starts to slip.
Third, you have no fallback. The day your default supplier goes down for a long weekend or a customs holdup, you are scrambling to redirect orders to suppliers you have not used in months.
Shopware 6 supplier rotation prevents this. Not by removing your preference, but by giving every active supplier a fair, predictable slice of the work.
What Shopware 6 supplier rotation actually does
Each supplier has an order_quota, a number set by your ops team in the Shopware admin. Think of it as how many orders this supplier should receive per cycle. A cycle is whatever window makes sense for your shop: a day, a week, a sprint, a campaign run.
When a new order is placed in Shopware 6, the plugin looks at every supplier who can fulfill the whole order. It sorts them, picks the one furthest from their quota, and writes the assignment back to the order via a custom field.
Once every supplier in the rotation hits their quota, the counter resets and the cycle starts again.
That is the whole idea. The interesting work happens around the edges.
When rotation works in Shopware 6, and when it does not
Rotation only does something useful when there is a clear choice between equally capable suppliers. If a customer orders 4 different products in Shopware 6 and no single supplier stocks all 4 at the right quantity, rotation cannot help. The order goes to the multi-supplier fulfillment path: each supplier gets their slice, and the rotation counter does not move at all.
This is the single most common reason rotation looks like it is not working. Mixed orders bypass it entirely. You can have your Shopware 6 plugin enabled, quotas set, suppliers ready, and still see one supplier doing all the work because the order shape never gives rotation an opening.
The rule is strict. A single supplier has to stock every line item at full quantity for the rotation to engage. Otherwise, the order falls through to whatever multi-supplier logic you already have.
If your Shopware 6 catalog is mostly single-line orders (one t-shirt, one phone case, one product), rotation will fire on almost every order. If your catalog is heavily bundled or your customers buy 5+ products at once, expect rotation to kick in less often. That is not a bug. It is the cost of giving a clean answer in cases where the answer is actually clean.
How to pick the next Shopware 6 supplier without making it complicated
Say 3 suppliers can fulfill the order, all under their quota. How do you choose?
Sort them on 4 fields, in this order:
- Priority (descending). Ops can pin a supplier higher in the Shopware admin. Useful for new partnerships, exclusive deals, or seasonal pushes.
- Quota (descending). A bigger quota means more capacity. Bigger capacity goes first.
- Current count (descending). The supplier closest to their quota goes first, so you fill capacity in order rather than spreading orders thinly across everyone.
- Supplier ID (ascending). A tiebreaker so the same situation always picks the same way.
Whoever lands at the top of that sort gets the order.
The reason this works for both manufacturers and dropshippers running Shopware 6 is that those four fields cover the levers ops actually wants. A manufacturer wants to keep their main factory near full while a backup factory ramps up. A dropshipper wants to test a new wholesaler with a small slice while the proven supplier carries the bulk. Same sort, different numbers.
Notice what is not in that list. There is no machine learning model. No fancy forecasting. No moving averages. The simplest version that respects priority and capacity wins because it is the one operators trust to predict.
If you have read my Shopware 6 plugin development approach, you will recognize the pattern. Decoration over inheritance, message queue for anything heavier than a request cycle, and admin config over hardcoded values.
The edge cases that wreck Shopware 6 rotation in practice
Most rotation systems do not fail at the picking step. They fail at the boring stuff around it. Shopware 6 has its own version of each of these, and getting them wrong means a haunted plugin.
Double-clicks and duplicate order placements
Operators click “Send” twice. Networks blip. Form submissions retry. The Shopware 6 message queue retries on failure. None of that should rotate twice and fire two orders at one supplier when they only earned one.
The fix is to make the pick step idempotent. When the order placement event fires, the plugin checks whether the order already has an assigned supplier in its custom field. If it does, it returns the stored supplier and skips the increment. The counter moves once per order, full stop.
Wrap the supplier row read in a FOR UPDATE lock during the pick so two orders landing in the same millisecond cannot both grab the same slot. The Shopware 6 DAL does not give you that for free. You have to write it.
When every supplier hits their quota
What happens when all eligible suppliers in the rotation are at their quota at the same moment? If the plugin just stops, the order stalls and a customer waits.
The right behavior is to mark the pool for reset, then assign the order to the top supplier anyway. The actual zero-out only happens at dispatch confirmation, not when an operator previews an order. That detail matters. It stops the cycle from quietly resetting every time someone opens the form to look at it.
Manual overrides in the Shopware admin
Sometimes ops needs to pick a specific supplier outside the rotation. Maybe a customer asked for a specific factory, maybe one supplier is doing a quality test, maybe an account manager owes another supplier a favor.
An override should bump that supplier’s counter (so they do not also receive an automatic order right after) but should not trigger a fresh cycle. Overrides are not part of the regular rhythm. Treating them like one corrupts the math.
These three corners are where Shopware 6 rotation either feels solid or feels haunted. If your custom plugin gets them right, rotation just works. If not, you spend Tuesday afternoons figuring out why one supplier got 7 orders for a single customer’s typo.
Shopware 6 supplier rotation for manufacturers vs. dropshippers
Same Shopware plugin, different shape.
Dropshippers running Shopware 6 typically have suppliers who overlap on hundreds of SKUs. The win is reliability and supplier health. By spreading orders across suppliers, you keep all of them warm, your backup options stay tested, and no single supplier becomes the bottleneck on a Friday rush. Quotas should match each supplier’s actual fulfillment speed and quality score, not their list price.
Manufacturers usually run Shopware 6 rotation across factories, production lines, or contract partners. The win is capacity smoothing and production planning. Quotas reflect real throughput per shift. Priority handles “this factory is a backup, not a primary.” Mixed orders rarely apply because manufacturing orders tend to be SKU-specific, so rotation kicks in on almost everything.
The mental model is the same in both cases. You have multiple suppliers in Shopware 6 who can do the same job. You want fair, predictable distribution that respects capacity. You want one knob (priority, quota) per lever you actually pull, and nothing extra in the admin.
If your business is somewhere in between, like a private-label brand with 2 manufacturers and 3 fulfillment partners, the plugin handles that too. A “supplier” in Shopware 6 is just whoever you send the order to. The rotation does not care about the title on their invoice.
How to ship a Shopware 6 supplier rotation plugin without painting yourself into a corner
If you are scoping a custom Shopware 6 plugin for this, the structural decisions matter more than the rotation math.
A few rules I follow on every build:
- Decorate, do not override. The order placement service in Shopware 6 should be decorated, not replaced. Overrides break on every minor update. Decoration survives. The same rule applies to the admin components where you expose quotas and priority.
- Push heavy work to the message queue. If your rotation plugin makes external API calls (warehouse stock checks, ERP sync, supplier portal posts), do not block the order placement on it. Use the Shopware message queue. I covered the same pattern in my plugin development approach.
- Store routing decisions on the order. Use a custom field on the order entity, not a separate table joined at read time. This makes the assignment idempotent, queryable in the admin, and visible to ops without a custom screen.
- Migrations for everything. Every schema change ships with a Shopware 6 migration. The day your plugin needs a new supplier capacity column is the day you find out whether your
update()method actually works. - Configurable quotas in the admin. Operators should set quota and priority through the supplier admin module, not a
services.xmlvalue. If ops needs a developer to change a number, you will pay for it on every cycle.
I have shipped this kind of plugin alongside the patterns in my zero-touch order processing case study and during a pharmaceutical inventory sync where supplier reliability was the whole point of the project.
Why a small Shopware 6 system beats a clever one
The temptation is always to add more. Cost-based routing. Geography-based routing. SLA-based routing. Supplier-health forecasting. All of that has its place, eventually.
But the core that makes any of it useful is fair distribution with predictable behavior. If the basic Shopware 6 rotation does not work, the clever stuff on top is just more surface area to break.
Quota plus priority gives ops everything they need on day one. Bigger suppliers carry more. Pinned suppliers carry first. Override when you must. Reset when the cycle ends. The fairness math is sorting on 3 fields. That is the whole rule book.
When you eventually do need richer routing, it slots in cleanly. The seam is already there in the decorated service.
Frequently asked questions
What is supplier rotation in Shopware 6? A custom plugin pattern that splits incoming orders across two or more suppliers who can fulfill the same product. Each supplier gets a quota set in the admin, and every new order goes to whoever is furthest from theirs. Once everyone hits their target, the cycle resets.
Does Shopware 6 have built-in multi-supplier fulfillment? No. The default Shopware 6 order workflow assumes one fulfillment path. Multi-supplier routing requires a custom plugin that hooks into the order placement flow.
When does Shopware 6 rotation kick in? Only when one supplier can fulfill the entire order at the right quantity. Mixed orders bypass rotation and use a multi-supplier fulfillment path instead.
How do I pick the next supplier? Sort by priority, then quota, then current count, then supplier ID as a tiebreaker. Whoever lands on top gets the order.
How do I avoid duplicate sends? Make the pick step idempotent. Check the order’s assigned-supplier custom field before rotating. The counter must move once per order, no matter how many retries fire.
Does this work for manufacturers and dropshippers? Both. The Shopware 6 plugin is identical. Only the meaning of “supplier” changes: factory, 3PL, wholesaler, or marketplace partner.
Where to start this week
If you run a Shopware 6 shop and you suspect one supplier is carrying too much, do this before you write any code.
Pick your top 3 SKUs by volume. List every supplier who can fulfill each one, with realistic capacity. If only one supplier shows up across all 3, you do not have a rotation problem yet. You have a sourcing problem.
If 2 or more suppliers do show up, write down what you would set as their quota and priority today. Then check whether your current Shopware 6 setup can actually enforce those numbers. If it cannot, that is the gap worth fixing first, before you go deeper into routing logic.
If you want a second set of eyes on how to wire supplier rotation into your Shopware 6 stack, get in touch. I have built this plugin pattern across custom Shopware 6 builds, B2B platforms, and dropshipping operations. The hard part is rarely the code. It is making sure the rules match how your operators actually work.