Learn to Programmatically Create Bundled Product In Magento 2
Magento 2 Bundle Product is simply “build your own” customizable product.
There are six product types in Magento 2:
- Simple Product
- Configurable Product
- Grouped Product
- Virtual Product
- Bundle Product
- Downloadable Product
Each item in a bundle can be either a simple product or a grouped product and thus, can be bought individually or as a combo. The perfect example of a bundle product is a corporate menswear combo including a shirt, formal pants, tie, blazer, etc.
On click of “Customize” or “Add to Cart” button, the option for the selection is displayed. The bundle can consist of varied products and hence, the SKU, price, and weight is set to either dynamic or fixed value.
Here’s the code to programmatically create bundled product in Magento 2 store easily!
Method to programmatically create bundled product in Magento 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
try { $bundleProduct = \Magento\Framework\App\ObjectManager::getInstance() ->create(\Magento\Catalog\Api\Data\ProductInterface::class); $bundleProduct ->setStoreId(0)//you can set data in store scope ->setWebsiteIds(array(1))//website ID the product is assigned to, as an array ->setAttributeSetId(4)//ID of a attribute set named 'default' ->setTypeId('bundle')//product type ->setCreatedAt(strtotime('now'))//product creation time // ->setUpdatedAt(strtotime('now')) //product update time ->setSkuType(0)//SKU type (0 - dynamic, 1 - fixed) ->setSku('bundlet1')//SKU ->setName('Test Bundle Product1')//product name ->setWeightType(0)//weight type (0 - dynamic, 1 - fixed) // ->setWeight(4.0000) ->setShipmentType(0)//shipment type (0 - together, 1 - separately) ->setStatus(1)//product status (1 - enabled, 2 - disabled) ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)//catalog and search visibility ->setManufacturer(83)//manufacturer id ->setColor(24) ->setNewsFromDate('01/01/2020')//product set as new from ->setNewsToDate('12/31/2020')//product set as new to ->setCountryOfManufacture('IN')//country of manufacture (2-letter country code) ->setPriceType(0)//price type (0 - dynamic, 1 - fixed) ->setPriceView(0)//price view (0 - price range, 1 - as low as) ->setSpecialPrice(50.00)//special price in form 11.22 special price in percentage of original price ->setSpecialFromDate('01/01/2020')//special price from (MM-DD-YYYY) ->setSpecialToDate('12/31/2020')//special price to (MM-DD-YYYY) //only available if price type is 'fixed'/ // ->setPrice(11.22) //price, works only if price type is fixed // ->setCost(22.33) //price in form 11.22 // ->setMsrpEnabled(1) //enable MAP // ->setMsrpDisplayActualPriceType(1) //display actual price (1 - on gesture, 2 - in cart, 3 - before order confirmation, 4 - use config) // ->setMsrp(99.99) //Manufacturer's Suggested Retail Price // ->setTaxClassId(4) //tax class (0 - none, 1 - default, 2 - taxable, 4 - shipping) //only available if price type is 'fixed'/ ->setMetaTitle('test meta title 2') ->setMetaKeyword('test meta keyword 2') ->setMetaDescription('test meta description 2') ->setDescription('This is a long description') ->setShortDescription('This is a short description') ->setMediaGallery(array('images' => array(), 'values' => array()))//media gallery initialization ->setStockData(array( 'use_config_manage_stock' => 1, //'Use config settings' checkbox 'manage_stock' => 1, //manage stock 'is_in_stock' => 1, //Stock Availability ) ) ->setCategoryIds(array(4, 10)); //assign product to categories // Set bundle product items $bundleProduct->setBundleOptionsData( [ [ 'title' => 'Bundle Test Items 1', 'default_title' => 'Bundle Test Items 1', 'type' => 'select', 'required' => 1, 'delete' => '', ], [ 'title' => 'Bundle Test Items 2', 'default_title' => 'Bundle Test Items 2', 'type' => 'select', 'required' => 1, 'delete' => '', ] ] )->setBundleSelectionsData( [ [ ['product_id' => 1, 'selection_qty' => 1, 'selection_can_change_qty' => 1, 'delete' => ''], ['product_id' => 3, 'selection_qty' => 1, 'selection_can_change_qty' => 1, 'delete' => ''], ], [ ['product_id' => 2, 'selection_qty' => 1, 'selection_can_change_qty' => 1, 'delete' => ''], ['product_id' => 4, 'selection_qty' => 1, 'selection_can_change_qty' => 1, 'delete' => ''], ], ] ); if ($bundleProduct->getBundleOptionsData()) { $options = []; foreach ($bundleProduct->getBundleOptionsData() as $key => $optionData) { if (!(bool) $optionData['delete']) { $option = $objectManager->create('Magento\Bundle\Api\Data\OptionInterface'); $option->setData($optionData); $option->setSku($bundleProduct->getSku()); $option->setOptionId(null); $links = []; $bundleLinks = $bundleProduct->getBundleSelectionsData(); if (!empty($bundleLinks[$key])) { foreach ($bundleLinks[$key] as $linkData) { if (!(bool) $linkData['delete']) { /** @var \Magento\Bundle\Api\Data\LinkInterface$link */ $link = $objectManager->create('Magento\Bundle\Api\Data\LinkInterface'); $link->setData($linkData); $linkProduct = $objectManager->get('\Magento\Catalog\Api\ProductRepositoryInterface')->getById($linkData['product_id']); $link->setSku($linkProduct->getSku()); $link->setQty($linkData['selection_qty']); if (isset($linkData['selection_can_change_qty'])) { $link->setCanChangeQuantity($linkData['selection_can_change_qty']); } $links[] = $link; } } $option->setProductLinks($links); $options[] = $option; } } } $extension = $bundleProduct->getExtensionAttributes(); $extension->setBundleProductOptions($options); $bundleProduct->setExtensionAttributes($extension); } $bundleProduct->save(); echo 'success'; } catch (\Exception $e) { \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info($e->getMessage()); echo $e->getMessage(); } |
That’s it.
Any doubts in the code to create Magento 2 bundled products? If so, please mention them in the Comments section below. I’d be glad to be of any help.
Do share the post with Magento peeps via social media.
Thank you.
Sanjay Jethva
Sanjay is the co-founder and CTO of Meetanshi with hands-on expertise with Magento since 2011. He specializes in complex development, integrations, extensions, and customizations. Sanjay is one the top 50 contributor to the Magento community and is recognized by Adobe.
His passion for Magento 2 and Shopify solutions has made him a trusted source for businesses seeking to optimize their online stores. He loves sharing technical solutions related to Magento 2 & Shopify.
4 Comments
Hi there Sanjay,
Its very nice your tutorials, and this snippet helped me a lot.. But I have a doubt and maybe you can help me..
I’ve created a bundle product successfully with your example here, but in my situation, I have to give to customer the option to select more products to be inserted in frontend, for example, I have my bundle products with my options selected, and the customer can add more products from a different list, and this bundle product will be inserted with more products than originally was created in admin panel, is that possible using an observer event like: controller_action_catalog_product_save_entity_after
I will really appreciate your help
You’ll have to develop a custom code for your requirements.
Thank you.
Hi
I am running this code in controller. I am getting an error like 1 exception(s):
Exception #0 (Magento\Framework\Exception\RuntimeException): Type Error occurred when creating object: Vendor\Import\Controller\Index\Bundle\Interceptor
Hello Upendra Kumar,
The error is caused due to the changes in the constructor argument.
You either need to run the command or delete the file from the generator.
Thank you.