DocumentationCommerceVideos and Tutorials

Create a bundle product

Last update: January 18, 2024
  • Topics:
  • Catalog Management
  • Admin Workspace
  • Backend Development
  • Integration
  • REST

CREATED FOR:

  • Beginner
  • Developer
  • User

A bundle product is a way to group several products under a parent product. These child products can be a defined set of products or offer a few variations that provide flexible configuration options for customers. Bundle product types do take a little longer to set up, and you must do some planning before you configure them. However, offering bundle products improves the shopping experience by making it easier for customers to customize their product selections.

For example, you can offer a product bundle called Learning to surf in your web store. The bundle is the parent product that serves as a container for the assigned child products that specify available options:

  • A standard surfboard
  • A typical surfboard leash
  • Red surfboard fins

When additional flexibility is desired, to allow for several options of child products is recommended. This requires a more complex use of options and child products. To expand on the previous example, the final options are:

  • A standard surfboard

  • A typical surfboard leash

  • Choice of fin color:

    • Red
    • Blue
    • Yellow

Whether the bundle is a static group of simple products or several products with variations, the flexible configuration options make bundle product types a unique and powerful merchandising tool for the Adobe Commerce store.

Before creating a bundle product, verify that all the simple products to include in the bundle product are available in Adobe Commerce. Create any that do not exist.

In this tutorial, learn how to create a bundle product using the REST API and the Adobe Commerce Admin.

Use the REST API to define a bundle product:

  1. Create simple products for use in the bundle product.
  2. Create a bundle product and associate the simple products.
  3. Get the bundle product and all the associated options.
  4. Delete an option from one section of the bundle products.
  5. Restore the options for a bundle product.

When creating bundle products from the Adobe Commerce Admin, you can either create the simple products first, or use the automated tool to create simple products using a wizard.

Who is this video for?

  • Website managers
  • eCommerce merchandisers
  • New Adobe Commerce developers who want to learn how to create bundle products in Adobe Commerce using the REST API

Video content

video poster

https://video.tv.adobe.com/v/3426797?learn=on

Transcript
Creating a bundled product with Adobe Commerce. For this, we’re gonna be showing you two different methods. One is using the REST APIs. The other will be using the Commerce Admin. For the REST APIs, I am using the method of a bearer token, which is definitely not recommended. The recommended approach is using OAuth. A backup would be using an admin user’s credentials. The use of a bearer token has been deprecated. You can still do it, but it’s not recommended. And the only reason I’m using it for this demonstration is that it makes the code samples a lot shorter, and you can get the concept a lot quicker. So to start off, we’re gonna create several simple products. And these simple products are then gonna be used to be a part of our bundle product. And for this, we’re gonna be creating a first time surfing bundle. So for that, we need a surfboard. We need a leash, which connects the surfboard to your ankle. So that way, when you fall off, because you will, you don’t lose your surfboard. And then for some variations, we’re gonna give you the options for red, blue, and yellow for the fins for your surfboard. And then I’ll show you what this looks like on the front end. And then when we’re done, we’ll go ahead and create a different type of product. It’s still a bundle, but something slightly different using the Commerce Admin. So let’s get started with the APIs. All of these are gonna be using the same method, the REST default V1 products URL using post method. All of these will have a very similar payload. For that, it’s going to be a SKU, a name, an attribute set ID, and then some price for the type ID, that’s always gonna be simple for these. And then some extension attributes, which helps the application realize that there is some quantity and that it is in stock. For the attributes that ID, I get that value from the Commerce Admin. So if you go to stores, attribute sets, and you find an attribute set that you’ve created, or if you haven’t, it will come with a default one. For simplicity sake, you can use the default one. And then when you click on it, look up here in the URL, this ID number is what you would use in your payload. So for this one, it’s ID four. So let me go ahead and go back to my postman. And that’s how I defined this attribute set ID of four. And all of these will carry through using the same value. So let’s create our simple products. And we do this first because then it’s easier to assign them to your bundled product when we’re all done. We’re gonna go ahead and create the surfboard first. And as long as our response comes back with some sort of data instead of an error message, we know we’re good. And that looks great. We have an ID number with a whole bunch of product attributes, which is great. We’re gonna go ahead and create the eight foot leash to go with it. And that also looks good. We’re gonna do the red fin colors. Once again, looks good. The blue fin colors, and those look great. And then the yellow fin colors. So now it’s time to create the bundle. And the bundle will vary slightly from the payload for creating the simple products. One key element would be the type ID equaling bundle instead of simple. And then under the section for bundle product options, this is an array. This is where we would define our different options. So we’re gonna have three different types of options. We’re gonna have one option for your surfboards. We’re only gonna give them one choice. It’s just gonna be a 10 foot surfboard. We could give them 10, 12 and 14 foot. But once again, for keeping this as simple as possible, we’re just gonna give them one option for the surfboard. For the surfboard leash, we’re also just gonna give them one option. We could make this complicated and give them different lengths and different colors. But once again, we’re just keeping this short. So we’re gonna give them one choice for this, which is an eight foot leash. But then for the color of the fins, we’re gonna give them the ability to pick, because it’s a radio button, one of red, blue or yellow fins. These other values that you see here help with orientation. They help with which option that it’s associated to, just so that way, when you’re going to produce these via some sort of a script, you will have a mechanism to know that you’re doing it programmatically correct. You can also define prices and some other things. These are just placeholders, once again, just to get this up and running for this demo purpose. So that’s what the payload will look like. We’re gonna go ahead and hit send for this and just make sure that we get a good response back. And we did. And it looks like our bundle options are gonna be option ID of 33, which is our 10 foot surfboard, option ID 34, which is our leash. And then 35 is the colors for the fins, which are red, blue and yellow. So everything looks great. So we’re gonna go ahead and fetch this bundled product using a get request. And it should look very similar to what we just got back from the post creating it. And it does, the payload looks virtually identical, which is expected, that’s great. But now we’re gonna go ahead and get rid of one of the options, the blue fin color option. But first let’s go see what this product looks like on the front end. So to do that, I’m going to go ahead and grab the product. I’m just gonna look at the backend first. Mainly just to double check that what I did worked as I thought it would. And two, to grab the URL key. So this is what the product would look like in the admin. And this is our first section, our surfboard with one option. This is our second option. The leash. And then our third option has fins colors. So that’s organized the way I expected it. So now we’re gonna go to search engine optimization. We’re gonna grab this URL key. And we’re gonna go here. And I probably have to get, I do have to re index. Every once in a while you have to re index, depending on your configuration. Mine’s not set to re index automatically on save because that’s not recommended. So now we can go to the front end and it will show it’s ready to be used. Yep, there it is. So now if we go to our customization and we view this product on the front end, you’re gonna see here’s our single option for surfboards, our single option for the leash, but then the radio buttons for our colors. So this is actually working exactly as I expected. At least it’s configured the way I expected. And you do notice that if you change the options, these are all happened to be $15, but as you change these around, this price will change and reflect appropriately. So that’s great. And it seems that the product that we created via the APIs is working. But once again, we wanna get rid of this blue fin option. So we’re gonna tab back to our APIs. And the way we do that is by using this URL. So it’s a rest default V1, bundle products slash, and then the SKU of the bundle product. And in our case, that is going to be a beginner surfboard. And I know that because when I created the bundle, that’s what I chose for my SKU. Then you need the keyword for options. And then the option, the number after this is the ID for the option that we’re trying to manipulate or get rid of. So we’re gonna go ahead and go back up here. And I believe it was 35. Yes, 35. So I’m gonna change my option ID here to being 35. And then there’s a keyword children. And then the last thing is the child SKU that you’re trying to get rid of. So if you remember, if we go back to this get, we know that this, we’re trying to get rid of the blue fins and blugs. So this would be the SKU that we would add to here. This is the child SKU that we’re trying to get rid of as a child option. So when we hit send, as long as it comes back Boolean true, that means we’re fine. Otherwise anything else, there’d be some sort of error or something didn’t happen the way we wanted. Just to be safe, we’ll go ahead and re-index. And now we’ll go back to the front end. And when we refresh, our blue option should disappear. And there we go. We have a surfboard, we just have a leash and we have red and yellow fins. So now the next question is how do you add back an option? Well, right now there is no way to add back a single option. So what you would do is you would add back all of the options for that section that you’re trying to update. So for this one, we’re gonna change this to 35 cause that’s our ID number. We’ll change this one to 35. Change this one to 35. And then we’ll change this one to 35. So what you would do is if you’re adding a different option or making any changes at all, whatever you put in this payload is what’s gonna end up there. Since we got rid of blue, but we wanna add it back, the method would be to just add all three of our options back. And this does give us the last opportunity to maybe change the position numbers or anything else that we wanted to. So let’s go ahead and hit send. And we got our ID number back, which is great. That means there was no errors, no problems. Just for safety sake, we’re gonna go ahead and re-index real quick. Now let’s go to the front end and see what it looks like. And we should get all three of our options back. And there we go. We have all three of our options back. So we’ve successfully added our simple products. We successfully created our bundle product. We successfully got rid of an option and then we successfully added them all back. Now it’s time to see the same overall process from the commerce admin perspective. So the way you would do that is you would go to catalog, products, and on your add product choices, you’re gonna choose a bundle product. And once again, this is where you get the opportunity to make some other choices. We’re just gonna use the default attribute set. We’re gonna do this one and we’re gonna call this a new homeowners bundle. And what we’re gonna do here is we’re gonna add the opportunity to get some forks and some spoons and some plates and some bowls and some glassware. So we’re gonna go ahead and add a category just to make it easier to find. And this is where we would add our bundle options. So we are gonna ahead and click add option and we’ll just give this option, we’re gonna call this glassware. We’re gonna make this a, dropdown is fine. Now we’re gonna add our products. So let’s go ahead and find our, let’s see here, glassware. So we can do a drinking glass. That’ll be fine. Go ahead and add products. Now we’re gonna do another option and this one’s gonna be silverware. Dropdown, let’s do, we’ll do radio buttons. And now we’re gonna add some products. So we’ll do spoons and forks. Add selected products. And then we’ll do another option. We’ll just say, cooking. And for this, we’ll add a mixing bowl and a measuring cup. And for this one, we’ll make it a, we’ll do a multi-select. That way we can see some differences. So now you can tell we have different options for our bundle product. We can hit save and close. I’m gonna go ahead and re-index. And then let’s see what this looks like on the front end. So we’re gonna go to housewares. Okay, here’s our new homeowners bundle. And now you can see we have a single item for glassware. So you don’t have any choices. For this, we made it a radio button so you can choose one spoon or one fork, but you’ll notice that the quantity is disabled. We’ll go over that in a second. And once again, if you have a single option, you don’t have any choices, it kind of makes the assumption for you, which is actually kind of nice. If all of your products are non-adjustable, then they can simply add to cart and be done. But let’s go ahead and make a small adjustment just so you can see what it looks like when a customer needs to make a quantity change. So for quantity change, you would change this to be user defined. So for this, we definitely want the option that the customer can choose multiple, they can enter as many as they want. We’ll also do the same thing for the forks and knives, but instead of a radio button, which doesn’t make a lot of sense, let’s do a checkbox. And then for this one, we will, well, we can, now we’ll change out the checkbox as well. Now we’ll hit save. And we’ll see what that looks like. So now you’ll notice that we can change this to being four, for example, and you’ll notice the price changes as well. So that’s how you add a bundled product. This is how you make some simple configurations. You can see that some of the choices that you make in the admin will reflect differently on the front end. So this is definitely an opportunity to continue to learn about this special product type and make your commerce experience as awesome as possible. Awesome as possible for your customers. I hope you have a good time learning about bundled products today. Continue your research and education and experience league and Aloha and have a great day.

Create products with REST

The following commands create all the products required to define the bundle product in this example: five simple products, and one bundle product that has three options.

Before submitting the request, update the example with values for your environment.

  • Change "attribute-set": 4 to replace 4 with the attribute set ID from your environment.
curl --location '{{your.url.here}}/rest/default/V1/products' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "product": {
    "sku": "10-ft-beginner-surfboard",
    "name": "10 Foot Beginner surfboard",
    "attribute_set_id": 4,
    "price": 100,
    "type_id": "simple",
    "extension_attributes": {
      "stock_item": {
        "qty": 100,
        "is_in_stock":true
      }
    }
  }
}
'
curl --location '{{your.url.here}}/rest/default/V1/products' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "product": {
    "sku": "8-ft-surboard-leash",
    "name": "8 Foot surboard leash",
    "attribute_set_id": 4,
    "price": 50,
    "type_id": "simple",
    "extension_attributes": {
      "stock_item": {
        "qty": 100,
        "is_in_stock":true
      }
    }
  }
}
'
curl --location '{{your.url.here}}/rest/default/V1/products' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "product": {
    "sku": "red-fins-and-fin-plugs",
    "name": "Red fins and fin plugs",
    "attribute_set_id": 4,
    "price": 15,
    "type_id": "simple",
    "extension_attributes": {
      "stock_item": {
        "qty": 100,
        "is_in_stock":true
      }
    }
  }
}
'
curl --location '{{your.url.here}}/rest/default/V1/products' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "product": {
    "sku": "blue-fins-and-fin-plugs",
    "name": "Blue fins and fin plugs",
    "attribute_set_id": 4,
    "price": 15,
    "type_id": "simple",
    "extension_attributes": {
      "stock_item": {
        "qty": 100,
        "is_in_stock":true
      }
    }
  }
}
'
curl --location '{{your.url.here}}/rest/default/V1/products' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "product": {
    "sku": "yellow-fins-and-fin-plugs",
    "name": "Yellow fins and fin plugs",
    "attribute_set_id": 4,
    "price": 15,
    "type_id": "simple",
    "extension_attributes": {
      "stock_item": {
        "qty": 100,
        "is_in_stock":true
      }
    }
  }
}
'

Create a bundle product and assign the simple products as options

Create a bundle product by sending the following POST request.

Before submitting the request, update the example with values for your environment.

  • Change "attribute_set_id": 4, and replace 4 with the attribute set id from your environment.
curl --location '{{your.url.here}}/rest/default/V1/products' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "product": {
    "sku": "beginner-surfboard",
    "name": "Beginner Surfboard",
    "attribute_set_id": 4,
    "status": 1,
    "visibility": 4,
    "type_id": "bundle",
    "extension_attributes": {
      "stock_item": {
        "qty": 100,
        "is_in_stock":true
      },
      "bundle_product_options": [
        {
          "option_id": 0,
          "position": 1,
          "sku": "surfboard-essentials",
          "title": "Beginners 10ft Surfboard",
          "type": "checkbox",
          "required": true,
          "product_links": [
            {
              "sku": "10-ft-beginner-surfboard",
              "option_id": 1,
              "qty": 1,
              "position": 1,
              "is_default": false,
              "price": 100,
              "price_type": 0,
              "can_change_quantity": 0
            }
          ]
        },
        {
          "option_id": 1,
          "position": 2,
          "sku": "surboard-leash",
          "title": "Surfboard leash",
          "type": "checkbox",
          "required": true,
          "product_links": [
            {
              "sku": "8-ft-surboard-leash",
              "option_id": 2,
              "qty": 1,
              "position": 1,
              "is_default": false,
              "price": 50,
              "price_type": 0,
              "can_change_quantity": 0
            }
          ]
        },
        {
          "option_id": 3,
          "position": 2,
          "sku": "surfboard-color",
          "title": "Choose a color for the fins and fin plugs",
          "type": "radio",
          "required": true,
          "product_links": [
            {
              "sku": "red-fins-and-fin-plugs",
              "option_id": 2,
              "qty": 1,
              "position": 1,
              "is_default": false,
              "price": 0,
              "price_type": 0,
              "can_change_quantity": 0
            },
            {
              "sku": "blue-fins-and-fin-plugs",
              "option_id": 2,
              "qty": 1,
              "position": 2,
              "is_default": false,
              "price": 0,
              "price_type": 0,
              "can_change_quantity": 0
            },
            {
              "sku": "yellow-fins-and-fin-plugs",
              "option_id": 3,
              "qty": 1,
              "position": 3,
              "is_default": false,
              "price": 0,
              "price_type": 0,
              "can_change_quantity": 0
            }
          ]
        }
      ]
    },
    "custom_attributes": [
      {
        "attribute_code": "price_view",
        "value": "0"
      }
    ]
  },
  "saveOptions": true
}
'

Delete an option from a bundle product

Remove a child product from a bundle product without deleting the product from the catalog by sending the following DELETE request using cURL.

curl --location --request DELETE '{{your.url.here}}/rest/default/V1/bundle-products/beginner-surfboard/options/35/children/blue-fins-and-fin-plugs' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3'

Restore product options

When updating bundle product options, make sure to include all the options you want to associate with this product. If your original set of options contained three products and one was removed, include all three options in the POST request to ensure that the product bundle specifies all the options. If you included only the option you removed, then the updated product bundle includes only that option.

Locate the option ID by reviewing the response from creation for the bundle product. In the that response, the option_id is 35.

...
,
            {
                "option_id": 35,
                "title": "added back color options for fins and fin plugs",
                "required": true,
                "type": "radio",
                "position": 2,
                "sku": "beginner-surfboard",
                "product_links": [
                    {
                        "id": "77",
                        "sku": "red-fins-and-fin-plugs",
                        "option_id": 35,
                        "qty": 1,
                        "position": 1,
                        "is_default": false,
                        "price": 15,
                        "price_type": null,
                        "can_change_quantity": 0
                    },
                    {
                        "id": "78",
                        "sku": "blue-fins-and-fin-plugs",
                        "option_id": 35,
                        "qty": 1,
                        "position": 2,
                        "is_default": false,
                        "price": 15,
                        "price_type": null,
                        "can_change_quantity": 0
                    },
                    {
                        "id": "79",
                        "sku": "yellow-fins-and-fin-plugs",
                        "option_id": 35,
                        "qty": 1,
                        "position": 3,
                        "is_default": false,
                        "price": 15,
                        "price_type": null,
                        "can_change_quantity": 0
                    }
                ]
            }
...

Update the product bundle to add the option you removed by submitting the following POST request.

curl --location '{{your.url.here}}/rest/default/V1/bundle-products/options/add' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{Your Bearer Token}}' \
--header 'Cookie: private_content_version=41d94540f5bd8b691017a850bc3b82b3' \
--data '{
  "option": {
    "option_id": 35,
    "title": "Choose a color for the fins and fin plugs",
    "required": true,
    "type": "radio",
    "position": 2,
    "sku": "beginner-surfboard",
    "product_links": [
      {
        "sku": "red-fins-and-fin-plugs",
        "option_id": 35,
        "qty": 1,
        "position": 1,
        "is_default": false,
        "price": 0,
        "price_type": null,
        "can_change_quantity": 0,
        "extension_attributes": {}
      },
      {
        "sku": "blue-fins-and-fin-plugs",
        "option_id": 35,
        "qty": 1,
        "position": 2,
        "is_default": false,
        "price": 0,
        "price_type": null,
        "can_change_quantity": 0,
        "extension_attributes": {}
      },
      {
        "sku": "yellow-fins-and-fin-plugs",
        "option_id": 35,
        "qty": 1,
        "position": 3,
        "is_default": false,
        "price": 0,
        "price_type": null,
        "can_change_quantity": 0,
        "extension_attributes": {}
      }
    ],
    "extension_attributes": {}
  }
}'

Additional resources

  • Create a bundle product tutorial
  • Bundle Product
  • Adobe Developer REST tutorials
  • Adobe Commerce REST ReDoc
recommendation-more-help
3a5f7e19-f383-4af8-8983-d01154c1402f