AI product bundles manual.

From the first generation to the discount in the basket: build and approve sets, configure sources and limits, choose the position - and find out why a discount is not applying when in doubt.

System requirements

Shopware 6.7 with Storefront, PHP 8.2 or newer. Background runs and the scheduled run need a working message queue; the built-in admin worker is enough.

For AI scoring you need your own API key with the provider of your choice. Billing happens directly there; nothing is routed through our servers.

Installation

Upload the ZIP in the admin under Extensions, install and activate it. Then enter the licence key on the licence screen.

Ready in five steps

  • Enter and activate the licence key
  • Choose the position on the product page under Settings
  • Define set size and sets per product
  • Click "Generate bundles" in the Bundles tab
  • Review the results and approve them
Important: only approved sets appear in the shop. A freshly generated set is open at first and invisible to customers.

How the sets are built

Products per bundle defines how many products a set contains in total, the anchor product included. At three the customer gets the item being viewed plus two partners.Bundles per product defines how many different sets are created for one product. The sets do not overlap: a partner already used in one set is not reused for the next.Allow smaller bundles permits a set with fewer products when not enough fitting partners are found. Switched off the rule is: either the set is complete or it is not created at all.

Data sources

Basket analysis evaluates which products were actually ordered together - the most reliable source. A minimum number of shared orders and a look-back period control how strictly it filters.Viewed together evaluates which products visitors look at within the same visit. Per visit a rolling window of recently viewed products is kept, and the current product is paired with everything in it.Shared categories and shared properties help when order history is thin. Same manufacturer is the weakest source and meant only as a last resort.

If several sources are active, their weights add up. Genuine co-purchases count triple; "viewed together" weighs more than the catalogue sources and less than real purchases.

On privacy: "viewed together" sets no cookies and stores no visitor data - only product pairs with a counter. Bots are discarded. If AI Cross-Selling is installed, the plugin adopts its existing counters once during the update.

Limits and exclusions

The maximum partner price limits how expensive a partner may be relative to the anchor product. At 60, a product costing 100 euros only gets partners up to 60 euros. This produces sets with accessory character rather than arbitrary pairings of cheap and expensive articles. Zero disables the rule.

Only available products excludes clearance articles without stock so no sets are created that the shop immediately hides again.Exclude manufacturers and exclude categories keep products out entirely - they become neither anchor nor partner. Useful for vouchers, spare parts or shipping articles.
Two points of effect: the exclusion applies when generating new sets and when displaying them. An existing set containing an excluded product disappears completely when "hide incomplete bundles" is active, otherwise it is shown without that product. Products without a manufacturer are never affected; variants inherit the manufacturer of their parent product.

Individual products

The normal run considers the strongest products from order history and is capped by "maximum anchor products per run".

In the Individual products tab you select articles deliberately. Sets are created for them without that cap, even if they barely appear in the order history. After the run the results appear directly below the selection and can be approved, rejected, deactivated or edited there.

A selected parent product includes its variants; the data basis always comes from the purchasable products.

If a run finds nothing for a product, relax the rules helps: for that single run all data sources are used, minimum values are set to one, price ratio and minimum AI score are suspended and the period widens to two years.

What still applies: exclusions for manufacturers and categories, stock and active products remain in force - otherwise sets would be created that the shop may not display at all. The saved settings do not change; the relaxation applies to this run only.

In a relaxed run the AI no longer discards sets but only scores and names them; its assessment still appears on every set. Results of a relaxed run always go into the review pool, even with auto-approval active.

Another run for the same product does not replace the existing sets but adds further ones - identical combinations are merely updated. How many sets a product shows in the shop is controlled by "maximum bundles shown"; the default is one. A marker points out anchor products with several sets, and the filter "only products with several bundles" in the review pool shows exactly those.

The status of a set

A set is either open, approved or rejected. The available buttons follow from that:

  • Open - edit, approve, reject
  • Approved - edit and deactivate. Deactivating takes the set out of the shop and returns it to open; name, description text and discount are kept
  • Rejected - edit and approve

The coloured figures next to a set explain themselves on hover.

Creating a set by hand

In the Individual products tab a set can also be assembled without any analysis. Pick products through the search, by name or article number. The first product chosen is the anchor and carries the "anchor" marker; the arrow on another product moves the anchor at any time. The rest are the partners.

Mutual assignment, name and discount can be set right away. The set goes into the review pool without analysis and without AI.

Two things to note: partners have to be purchasable - with variant articles pick the variant, not the parent product. And a combination rejected earlier does not block a manually created set.

In the review pool it carries the source "created manually" and can be found through the source filter; right after creation it also appears in the result list below the selection.

Filters and bulk actions

The review pool can be filtered by source, category, property and manufacturer. The filters sit behind a toggle with a counter; active ones appear as removable chips below the bar.

The "select all" checkbox above the list reveals the bulk actions. "Approve selection" opens a window with the same fields as editing a single set: discount, mutual assignment, layout and collapsed state. The values apply to every selected set, which are then approved.

On resetting: "Global setting" resets the value on the set so it follows the plugin configuration again. Any other value is stored on the set itself. If the discount field stays empty, the discount is left unchanged.

"Clean up rejected" sits next to the Rejected figure and removes the rejected sets in one go.

Position on the product page

Four positions are available: at the top of the buy box, directly above the price; below the complete buy box; above the tab bar, meaning above description and reviews; or below the entire tab area.

"Do not display" hides the box without deleting the generated sets.

Show heading and show description text switch the two text lines of the box on or off. The texts themselves are maintained per set through "Edit".
On multilingual shops: the default texts are translated through snippets. A text set on an individual bundle, by contrast, appears identically in every language. If the heading stays empty the default applies; for the description text the AI reasoning comes first, then the default. Both survive another generation run.

How it looks in the shop

A set is always bought as a whole. Individual products cannot be deselected, so the discount clearly belongs to the complete set.

Show article number displays the article number under every product in the box and additionally behind the product names in the review pool. The search there then finds sets by article number too.

The set button text can be adapted: either one text for all languages or one per language. Empty fields fall back to the general text first, then to the translated default.

With assign bundles both ways a set appears not only on the anchor product but also on the product pages of the partners it contains. The anchor product is shown there as an equal member of the set.

Two independent routes: the setting applies globally; in addition, the mutual assignment can be set for individual sets in the review pool through "Edit". A set with its own tick therefore appears both ways even when the global setting is off.

Link products controls whether the product name in the box leads to the product page. Switched off the name stays plain text and the customer stays where they are.

Click on a product defines what happens when a product in the box is tapped. The choices are quick info in a modal with image, article number, price and short description, product page in a new tab, product page in the same tab and nothing. The anchor product is never linked, since the visitor is already on its page.

Show unit price puts the unit price below the price, for example 12.90 € / 1 l. The value comes from Shopware and only appears for products that carry a content declaration. Strike price in red shows the crossed out original price in red; when off it stays grey.

The product layout determines the arrangement in the box. Wrap into rows shows four products per row, two on tablets, one on phones. Slider keeps all products in one swipeable row; on desktop arrows appear that disable themselves at the ends. List gives every product its own row across the full width.

Rule of thumb: with more than four products in a set, slider or list is usually the better choice - wrapping gets tall quickly.

AI scoring

With AI scoring active, every set is sent to the chosen provider. The AI decides whether the products belong together, assigns a score and, on request, writes a short sales headline. Sets below the minimum score are discarded and never reach the review pool.

Names, description texts and discount reasoning are produced by the AI in the default language of the shop.

On the key: the API key is stored server side and never delivered to the browser. "Test connection" verifies access directly.

Sales channel and language

At the top of the settings you choose the level: sales channel and language. Only storefront channels are offered, and only the languages assigned to the chosen channel.

  • Chain icon per field - closed means inherited, open means a value of its own. A click switches it.
  • Differences only - saving on a channel stores only what differs from the general state.
  • Discard - a button resets all of a channel's own values.

Texts of the box

Headline, description and button text are available per level and language. Empty fields inherit in this order: channel and language, general and language, the language-independent field, and finally the shop's own snippet.

The language selector starts with All languages (default) - that is where the language-independent texts live.

Quantity per product

With this setting active, customers enter a quantity per product in the box. The total, the struck price and the saving recalculate at once.

The saving can be shown as a money amount instead of a percentage.

Set discount

Switched off by default. When active, the discount applies as soon as all products of an approved set are in the basket. It appears there as its own line item and is determined afresh on every recalculation: if a product of the set leaves the basket, the discount disappears automatically.

The percentage from the settings applies to all sets. Through "Edit" a deviating value can be set per set, which then takes precedence.

Zero is the deciding value: a set with zero always follows the global rate - a later change there takes effect on all such sets immediately. Only an AI suggestion or a manually entered value binds an individual rate to the set.
Each product counts towards one set only. If two sets overlap, the discount is not granted twice.

The minimum set value prevents discounts on very small orders.

With bundle name as discount name the discount line carries the name of the set, such as "Garden set (-25 %)". The customer then sees in the basket which set triggered it.

With discount amount in cart set to Hide the discount line stays visible in the storefront, only the amount is not shown: in the cart, offcanvas cart, checkout, finish page and the orders in the customer account. The discount is still deducted, the totals stay the same. Order mail, invoice and admin keep showing the amount. Through "Edit" discount amount in cart can be set to Hide or Show per set, "General setting" follows the switch.

With image of the discount row you store an image in the settings that is used in the cart for the discount row of every set. Through "Edit" an own image can be chosen per set, which takes precedence over the general setting. Without a selection the Shopware placeholder stays.

Instead of a percentage, a discount as an amount can be stored per set: a fixed deduction in the shop currency, for example 5 for five euros. A value above zero wins over the percentage and never exceeds the set total. A zero means the percentage still applies.

The box in the shop shows the exact rate from the administration, including intermediate values such as 2.5 percent. The discount amount in the basket is rounded commercially to the decimal places of the currency.

Inherit to variants

Whether a set also appears on the variants of the anchor product is controlled globally in the settings and additionally per set through "Edit". Set to off, the set stays with the exact product it was created for, which is how a set for a single variant works.

AI suggests the discount

With this setting the AI assigns a discount suggestion to every set during generation. The basis is how well the products fit - very coherent sets need only a small incentive, loosely fitting ones a larger one - and the price level of the set, because with expensive sets a few percent already carry weight.

The maximum AI discount caps the suggestion hard; the AI can never exceed it. The value lands as a percentage on the set, is visible in the review pool and can be changed through Edit at any time. Existing sets keep their value.

The discount is still only granted when the set discount is switched on overall.

Discount diagnosis

The discount diagnosis in the settings checks whether a combination of article numbers would trigger a discount. It runs server side through exactly the same logic as the basket calculation.

If no discount applies, it names the concrete reason: switch off, unknown article number, no approved set, missing set product or a percentage of zero.

Cache

Changes to sets take effect in the shop immediately. On approval, rejection, deactivation, editing or deletion the affected product pages are removed from the cache specifically - the page of the anchor product and those of all partners it contains, variants included.

No manual clearing any more: clearing the whole shop cache is no longer necessary for changes to sets.

Automation

Auto-approve releases sets from a configured total score without manual review. Scheduled run produces new sets regularly through the scheduled task.

When generating from the administration a window shows the progress: anchor products processed, sets created and sets discarded by the AI. Continue in the background hands the run to the message queue - the admin is immediately usable again, a slim bar shows the state, and the run continues even with the browser closed.

The run is protected against interruptions: if a segment fails, the admin retries with growing pauses, and after reloading the page a running generation is picked up automatically. It works in segments and can be cancelled at any time - sets already created are kept.

On the console: bin/console staw:product-bundles:generate --size=3 --per-product=2

Check the display

If no set appears on a product page although one should, the "check display" tool answers that in one go: enter an article number and it names the sets that appear on that page - and for the rest, the reason why not.

The check uses exactly the same matching as the storefront, including variants and mutual assignment. What it shows is therefore precisely what the customer sees.

Troubleshooting

No sets are created: usually order history is missing. Lower the minimum number of shared orders or additionally enable the shared categories source.
The box does not appear in the shop: check that the sets are approved, that storefront display is active and that the position is not set to "do not display". The quickest route is "check display" with the article number. Clearing the cache is not necessary; the plugin handles that itself.
A set suddenly disappeared: with "hide incomplete bundles" active, a set vanishes as soon as one of its products is no longer available or no longer visible in the sales channel.
The discount does not apply: the discount diagnosis names the reason in one go - that saves trial and error.

Support

Questions and requests come straight to us - support is from the developer, not from a queue. You can also request a feature through the Plugin Suite in the admin.

All settings

Every setting of the plugin with its default value and explanation, in the same order as in the administration. The texts come straight from the plugin (version 1.7.26).

Placement in the shop

Show in storefrontDefault: on

Turns the bundle box in the shop on or off entirely.

Position on the product pageDefault: Below the buy container

Defines where the bundle box appears.

Insert via JavaScriptDefault: off

For themes that replaced the default templates so the box never appears. The box is then rendered at the end of the page and moved to the given place. It only kicks in when the regular position did not render.

Target in the themeDefault: empty

CSS selector of the element the box should appear at, for example .product-detail-description.

InsertDefault: After the element

Where the box sits relative to the chosen element.

Show on variantsDefault: on

Also shows the main product bundles on all of its variants.

Variant displayDefault: Show on all variants

Defines on which variants a bundle appears. Only the contained variant: box and discount apply only to the variant chosen as anchor in the bundle, for example when quantities in the set depend on the variant. For older bundles pick the variant as anchor in the edit dialog and save.

Assign bundles reciprocallyDefault: off

A bundle then also appears on the pages of its partner products, not only on the anchor product. Can additionally be set per bundle in the edit dialog.

Bundles per product pageDefault: 1

How many bundle boxes appear on a product page at most. Allowed range: 1 to 6.

Box layout

Maximum width of the boxDefault: 0

Limits the width in pixels and centres the box. 0 means no limit, then it follows the theme container. It has no effect in the buy widget, where the narrow column sets the width. Allowed range: 0 to 2400.

Product layoutDefault: Wrap into rows

Wrap shows four products per row, two on tablets and one on phones. Slider keeps everything in one swipeable row, with arrows on desktop. List puts every product on its own row - the calmest option with many products.

Layout on mobileDefault: Same as above

Separate arrangement below 768 pixels. This allows a list on the desktop and a slider on mobile. The slider arrows do not appear there, swiping is used instead.

Show box collapsedDefault: off

The bundle box shows only its heading at first, a click expands it. Requires the heading to be shown.

Show headlineDefault: on

Shows or hides the headline of the bundle box. The text is maintained per bundle via "Edit".

Show description textDefault: on

Shows or hides the line below the headline. The text is maintained per bundle via "Edit".

Hide incomplete bundlesDefault: on

Hides a bundle as soon as one product is no longer available or visible.

Products in the box

RRP as the basisDefault: off

Uses the sum of the recommended retail prices as the struck through price where products carry one. The discount then looks larger. Without an RRP the regular total stays the basis.

Image of the discount rowDefault: empty

Used in the cart for the discount row of every bundle. An image on the individual bundle takes precedence. Without a selection the Shopware placeholder stays.

Strike price in redDefault: on

Shows the crossed out original price in red. When off it stays grey.

Quantity per productDefault: off

Customers can enter a quantity per product in the box. The total updates immediately. When off every product is added once.

Variants to choose fromDefault: off

If a product of the set is a variant, a dropdown with its sibling variants appears. Price and cart follow the selection, and the discount still applies when another variant was chosen.

Show unit priceDefault: off

Shows the unit price below the price, for example 12.90 € / 1 l. The value comes from Shopware and only appears for products that carry a content declaration.

Show product numberDefault: on

Shows the product number under every product of the bundle box and in the review pool.

Click on a productDefault: Quick info in a modal

What happens when a customer taps a product in the box. The anchor product is never linked, since the visitor is already on its page.

Bundle composition

Products per bundleDefault: 3 products

How many products a bundle contains in total, including the anchor product.

Bundles per productDefault: 2

How many different bundles are created for one product. The sets do not overlap.

Allow smaller bundlesDefault: on

Allows bundles with fewer products when not enough matching partners are found.

Maximum anchor products per runDefault: 500

Limits the runtime on large catalogs.

Only products without a bundleDefault: off

Skips products that already have a bundle.

Data sources

Market basket analysisDefault: on

Products bought together in the order history. The strongest source.

Minimum shared ordersDefault: 3

How often two products must have been bought together.

Lookback period in daysDefault: 365

How far back the order history is evaluated.

Viewed togetherDefault: on

Products that visitors looked at within the same visit. Needs the tracking switched on and some time to collect data.

View trackingDefault: on

Records on product pages which products are viewed in the same visit. No cookies, session only, bots are discarded.

Memory window per visitDefault: 6

How many recently viewed products per visit are paired with the current product. Allowed range: 2 to 20.

Minimum shared viewsDefault: 3

How often two products must have been viewed together before the pair counts.

Keep view counters (days)Default: 365

Older counters are deleted during generation and by the scheduled task. Allowed range: 30 to 3650.

Effectiveness trackingDefault: on

Counts per bundle how often it was seen, added to the cart and ordered. The numbers appear on every bundle in the review pool. When off nothing is counted any more, existing numbers are kept.

Delete rejected bundles after (days)Default: 0

Cleans up the review pool automatically. 0 keeps rejected bundles forever. Allowed range: 0 to 3650.

Shared categoriesDefault: on

Products from the same categories. Helps when there is little order history.

Shared propertiesDefault: off

Products with the same property values.

Same manufacturerDefault: off

Products of the same manufacturer. Only useful as a last resort.

Only active productsDefault: on

Ignores disabled products during creation.

Maximum partner price (% of anchor)Default: 0

A partner may cost at most this share of the anchor price. 60 means: for a 100 euro product only partners up to 60 euro qualify. 0 disables the rule. Allowed range: 0 to 1000.

Skip rejected suggestionsDefault: on

Combinations rejected once are not suggested again, not even after the review pool was cleared.

Only products in stockDefault: off

Excludes products sold as closeout without stock. Prevents bundles that vanish from the shop right away.

Bundle discount

Bundle discount activeDefault: off

Grants the discount once every product of a bundle is in the cart. Off by default.

Discount in percentDefault: 5.0

Applies to all bundles. A value set on a bundle takes precedence, 0 means use this value. Allowed range: 0 to 90.

Bundle name as discount nameDefault: on

The discount line in the cart carries the name of the bundle, e.g. "Garden set (-25 %)". The customer immediately sees which set earned the discount. When off, the label below is used.

Label in the cartDefault: empty

Leave empty to use the bundle name.

Discount on differing quantitiesDefault: Only the stored quantity

How the discount reacts to quantities differing from the one stored in the bundle. Only the stored quantity: less is not possible, more is not discounted. More allowed: the stored quantity is required, every further unit counts fully. Any quantity: one unit per position is enough. Only takes effect with a changeable quantity.

Saving as an amountDefault: off

Shows the saving as a sum of money instead of a percentage. With a fixed amount or the RRP basis this applies anyway.

Minimum set value for discount (euro)Default: 0

Below this set value no discount is granted. 0 disables the limit.

AI scoring

AI scoring activeDefault: off

Lets the AI check and name every set. Without AI only the data sources count.

AI providerDefault: OpenAI (ChatGPT)

The selected provider is used for scoring.

Minimum AI scoreDefault: 50

Sets below this value are discarded. Allowed range: 0 to 100.

Bundle names from the AIDefault: on

Lets the AI write a short sales headline for the set.

AI suggests a discountDefault: off

During generation the AI suggests a discount rate per bundle - based on how well the products fit together and the price level of the set. The suggestion is stored as the percentage on the bundle and can be changed in the review pool at any time. Only takes effect while the bundle discount is switched on.

Maximum AI calls per runDefault: 0

Cost brake for large catalogues. Once the limit is reached the remaining bundles are created without AI. 0 means no limit.

Maximum AI discount (%)Default: 15

Upper limit for the suggestion. The AI can never assign more than this value. Allowed range: 1 to 50.

Automation

Approve automaticallyDefault: off

Approves bundles from the configured score without a manual review.

Score for automatic approvalDefault: 70

Only bundles from this total score are approved automatically. Allowed range: 0 to 100.

Scheduled runDefault: off

Regularly creates new bundles via the scheduled task.

Availability

Directly from Stone & Water

Available now

Monthly19,99 €
Best valueYearly189,99 €21 % cheaper

All prices net, plus VAT.

You buy the licence directly from us and receive an invoice from us. Installation by upload in the admin without SSH, updates through our licence platform, support straight from the developer.

Get in touch+49 2555 9997342

Shopware Store

In preparation

The plugin will be listed in the official Shopware Community Store. Installation and automatic updates then run through the plugin manager in the backend, billing through your Shopware account. We will link it here as soon as it is available.