Selling Bundles the Right Way on Magento 2
Selling Bundles the Right Way on Magento 2

Selling Bundles the Right Way on Magento 2

Published January 11, 2018 in Development
What does ROAS really mean?
What does ROAS Really Mean?
December 20, 2017
Display Configurable Product Price Ranges in Magento 2
February 12, 2018

Magento has a variety of product types to help you find the right way to sell your products. There are downloadable products for digital items (such as ebooks), virtual products for items with no tangible deliverable (such as warranties), and configurable products for variations (such as a shirt that comes in different sizes). One of the most powerful types available is bundle products. In my experience, this is the least used product type, and I believe there are several factors influencing its sparse appearance:

  • External Integrations – Whether you’re pulling product data into Magento or pushing order data out, few systems match up with Magento’s concept of bundles.
  • Labor-Intensive Product Creation – Bundle products just take more time to set up than most other product types.
  • No Need – Many merchants simply find that they don’t sell any products in a bundle format.

Now let’s take a look at the upsides of bundle products by breaking down what they are and how you can leverage them to sell more in your store.

What is a Bundle Product?

In a nutshell, bundle products are a way of selling several products together as a single package. This is really a great opportunity for merchants since it’s a form of upselling. More than that, it’s a very targeted form of upselling, and Magento gives you the flexibility to really make it worth the customer’s while.

The bundle product is just a shell, and ultimately it contains the products that you’re already selling on your Magento store. Let’s say you sell musical instruments. You’d love it if that customer would add some cymbals and drumsticks to their drum set purchase. Rather than just showing related products and upsells during their purchase experience, you can create a bundle. By doing this, you encourage the customer to increase their order total, and you also give them confidence that the products they’re buying are compatible with each other.

You can read about creating and configuring bundle products in the official user guide, but I’m going to cover the basics of how bundles are put together.

Bundle Options

The basic architecture of bundle products is their options. Options are the components that make up the bundle. Each option offers a selection of products that can fill that slot. Let’s look at our drum set bundle. It’s going to have the following options:

  • Shell Pack (the drums themselves)
  • Crash Cymbal
  • Hi Hat
  • Drum Sticks

At a basic level, those are the things included in the bundle. For each of those options, there can be multiple products to choose from depending on your preference. My product represents a bundle around a Yamaha Stage Custom shell pack, so I’m only going to offer one product for the Shell Pack option. However, the customer will be able to choose from multiple brands to fill the Crash Cymbal, Hi-Hat and Drum Sticks options.

You can make each option required or optional, set default quantities for selections, and choose whether or not the customer can define their own quantities.

For my product, most of the options are required and have an unchangeable quantity of 1. However, the drumsticks are an optional add-on, and the customer can modify the quantity. This ensures that someone new to drum purchasing doesn’t accidentally buy things they don’t need, but they can buy a few extra pairs of sticks from the same product page.

Bundle Pricing

Pricing for bundle products is flexible. All of the simple products that can end up in my bundle have their own prices in Magento, but do I want to discount them when bundled?

In this case, I do. Depending on the products selected, the sum of the items in my bundle could range from $1,204 to $1,229. To encourage customers to buy my bundle, I’m going to price it at $1,100. The Shell Pack, Crash Cymbal, and Hi-Hat selections will be included at no additional cost. For the sticks (which are optional), I’m going to price them at $5 per pair. This is still a good deal, as the simple products for the drumsticks would be $8 if added to the cart separately.

To set up this kind of pricing, I set Dynamic Price = No when creating the bundle. This allows me to set a base price for the bundle, then optionally attach prices to each option selection. This gives the products specific prices in the context of the bundle, but the pricing of the simple products has no impact on my bundle.

If I don’t want discounts for my bundle, I can set Dynamic Price = Yes. Instead of manually setting prices on my option selections, the bundle will automatically sum the simple product prices. The user won’t save any money buying the bundle, but they’ll still benefit from a more guided shopping experience.

Bundle Data Architecture

You may be thinking that bundles sound great in theory, but how do they work out with other eCommerce elements? How does shipping calculation work? What does the data look like when orders are exported to an external system?

There’s some flexibility around the data. From a shipping perspective, bundles offer a Dynamic Weight option. If set to Yes, the weight of the bundle product in the cart will be the sum of all simple product weights in the bundle. This ensures that the final weight will be accurate for the purpose of getting shipping rates. If set to No, you can assign a static weight to the bundle that will be unaffected by the customer’s selections.

There’s also an option for Dynamic SKU. When set to Yes, the final SKU of the item will be a combination of the bundle product SKU and those of all the simple products included.

The final order data contains quite a bit of information about the bundle. It contains the bundle itself as well as a row for each product that ended up in the bundle. Those rows contain the SKU and quantity of the simple products. This is nice if you have an external integration consuming order data for things like inventory tracking, as it allows you to examine the tangible products that were sold.

Challenges with Bundles

Bundles are a complex concept, and every merchant will leverage them a little differently. I completely respect the logic that the Magento core uses with bundles, but it’s definitely not a “one size fits all” scenario. I’d like to look at some of the specific challenges I’ve seen merchants run into, and the solutions we implemented to get the logic just right.

The “Primary Product” Dilemma

Bundles work really well out of the box to sell several related products together. However, they don’t work as well to represent a primary product with add-ons. Last year, I had a merchant who sells espresso machines. They often include items with these machines, such as a bag of espresso beans or an extended warranty. They needed these freebies to be clearly represented on the product and cart pages, and they also needed them to be individual items in the order data for the sake of inventory updates. The problem was that they really didn’t want to offer the “Customize and Buy” interface that Magento provides out of the box. There was really nothing for the customer to configure. All options were required and only offered one selection. They really just needed the customer to see what’s included and have an add to cart button.

We were able to work around this with a few layout changes and some strategic CSS adjustments. Within the bundle configuration, we hid the option labels and form elements, leaving only the names of the selections and the prices. We also moved the master quantity input and the add to cart button above the bundle configuration. The end result was a product page that’s nearly as basic as a simple product. Here’s the same treatment on our drum set bundle if it only had one selection for each option:

Native Display:

Customized Display:

Note that this removes all configuration mechanisms from the page, so it’s really only a good fit for bundles with static selections.

Shopping Cart Price Rules

When using shopping cart price rules, it’s important to be aware of the native behavior with bundle product children. Any conditions in a price rule will be triggered by the items in the bundle once it’s added to the customer’s cart. If this isn’t your intention with your price rules, you could get a nasty surprise when orders start coming in.

Let’s take our drum set bundle as an example. I have some surplus stock of Vic Firth drumsticks, so I want to offer a 50% off sale. I create a shopping cart price rule that takes 50% off of products where Brand is Vic Firth. This works great when customers go to the drumsticks category and purchase a matching simple product, but it’s less ideal when they add the drum set bundle to the cart. When configured to include the optional Vic Firth drumsticks, the 50% discount is applied to the entire bundle. In an effort to move some drumsticks, we’re suddenly giving away a $1,100 drum set for $550.

Unfortunately, there’s no configuration to change this behavior, but you can alter it with a small code change if necessary. The model responsible for this particular rule validation is \Magento\SalesRule\Model\Rule\Condition\Product\Combine, and the relevant method is validate (defined in the superclass).

If we create a plugin for \Magento\SalesRule\Model\Rule\Condition\Product\Combine, we can make sure that no bundle children are valid for shopping cart price rules.

Layered Navigation

Similar to the dilemma of shopping cart price rules, bundle children can also trigger unintended layered navigation behavior. Let’s say we put our drum set bundle in a Drum Sets category. Since the set is built around a Yamaha shell pack, we’ve set the brand on the bundle product itself as Yamaha. In layered navigation, we want the set to show up when Yamaha is set as the brand filter. Since we don’t expect customers to choose a bundle based on which drum sticks are included, we’d prefer that the bundle doesn’t show up when results are filtered to match a Brand value of Vic Firth.

Here’s the native handling of the bundle. Notice how every brand that’s available in our drum set bundle is present in the layered navigation:

Fortunately, we can exclude bundle child attributes from being considered in layered navigation with some minor code changes. The bundle child indexing occurs in \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\AbstractEav in the _prepareRelationIndexSelect method. Here’s the original code:

The query uses the catalog_product_relation table to identify parent / child product relationships, then joins the attribute index table on by child id.
This allows it to query the attribute values of child products of relevant parents. It also uses a left join to include the parent product.
It groups by the parent id, and the result is a list of parents that have children matching the filter criteria.

If we replace the method code with the following, we can instead limit the parent product join to products that aren’t bundles.
This will exclude bundle children from the query logic, producing layered navigation with no consideration of bundle child product attributes.

Note that this method is in the abstract, so you’ll have to implement a di preference for each subclass that implements this method that you want to behave differently. When I implemented these changes, I included the following:

  • Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\Decimal
  • Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\Source
  • Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\Source

Here’s the resulting behavior:

Make a Bundle and Make a Bundle

Whether you’re looking to help customers identify compatible products, or just looking to increase your order totals, I think there’s a use case for almost every merchant to use bundle products. Even if you don’t want to create a lot of them, they can be a great promotional tool. So what are you waiting for? Get started with those bundle products. If you happen to need some customizations to get them just right, give us a call.


  1. Adrian Chirita says:

    Hello there and thank you for this useful article!
    Is it possible to give more details about the “few layout changes and some strategic CSS adjustments” to totally eliminate the configuration part of the bundle? I would like to do the same for my bundles.
    Thank you in advance!

  2. Damon Moats says:

    Thanks, You have explained very nicely, and there’s another easier to follow tutorial for creating bundle products in magento 2 on magenticians. I found it very useful. I hope others will like it too.

  3. Alex Morco says:

    Thanks for sharing this awesome tutorial, I was working to set catalog price rules in my Magento store, Your article and this post helped me a lot,

  4. ankur says:

    i have seen that post and try to make same layout with my bundle product so can you tell me how we can achieve because i cant see code to make layout like other screenshots.

  5. Mat says:

    hello guys, thanks for the article.

    In the drumset example, it looks like you’re using the same image twice (, so we can’t really see the difference you’re trying to show. Any chance you could update the article ? 🙂

  6. jayesh says:

    I want to add bundle products with quantity dynamically into cart.
    I am able to add products but quantity is not updated. it is always 1.
    Is there any way to solve this issue.

    below code i am using for that.

    $product = $this->_productRepository->getById(89,false, null, true);

    $bundle_option = [ 1 => array(2,8,18) ]; // 2,8,18 are selection ids, 1 is option id
    $bundle_qty = [ 1 => array(2,3,4) ]; // 2,3,4 are quantity, 1 is option id

    $params = [
    ‘form_key’ => $this->formKey->getFormKey(),
    ‘product’ => 89,
    ‘bundle_option’ => $bundle_option, // it is working fine
    ‘bundle_option_qty’ => $bundle_qty, // logically it will work but in my case it is not working.
    ‘qty’ => $totalqty

    $this->cart->addProduct($product, $params);

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Most Recent PostsView all
September 15, 2021

Classy Llama Awarded #3 Best Place to Work by Biz417

Springfield, MO — Classy Llama has been awarded the number 3 spot on the Biz417 Best Places to Work Top 20 for 2021.  “This e-commerce agency […]
September 13, 2021

2021 Instagram Changes: What you need to know for eCommerce Marketing

What’s Going On With Instagram in 2021? The Head of Instagram, Adam Mosseri, announced in summer 2021 that big changes are coming to the platform sometime […]
September 9, 2021

Signifyd Protects a Timeless Brand

Overview Signifyd Customer Since: 2019 Solution: Revenue Protection, specifically Guaranteed Fraud Protection Customer Synopsis: Precious Moments is known around the world for their carefully curated gifts […]