When assembling a "Gaming PC" kit in an online store on 1C-Bitrix, a common task arises: the system unit is mandatory, while the keyboard, mouse, and headset are optional. Without custom development, the standard b_catalog_product_set mechanism only allows marking an item as mandatory or not. Grouping options, dynamic price recalculation, and separate stock control are not supported. Our engineers, with 5+ years of experience, have implemented dozens of such projects — from small stores to catalogs with 50,000 items. We offer a ready-made solution that easily adapts to any business scenario.
Configuring mandatory and optional items in a 1C-Bitrix set
The standard b_catalog_product_set mechanism has the IS_REQUIRED field, but the frontend logic for selecting options is not implemented out of the box. Extending the system requires additional development.
The IS_REQUIRED field and its limitations
The IS_REQUIRED field accepts values 0 (optional) and 1 (mandatory). This is the only distinction in the standard structure. For more complex scenarios — for example, "select exactly one item from a group" — you need to extend the schema. In one project, we reduced the time to add a new bundle from 3 hours to 10 minutes thanks to our grouping table.
We add the GROUP_ID field to b_catalog_product_set via a user field or by extending the table (if update policy allows). An alternative without changing the table structure: store groupings in a separate bl_bundle_option_group table. The b_catalog_product_set mechanism is described in the Official 1C-Bitrix documentation on product sets.
CREATE TABLE bl_bundle_option_group ( id SERIAL PRIMARY KEY, bundle_id INT NOT NULL, group_code VARCHAR(100) NOT NULL, group_name VARCHAR(255), min_select SMALLINT DEFAULT 0, -- minimum selections from the group max_select SMALLINT DEFAULT 1, -- maximum selections from the group item_ids INT[] NOT NULL, -- array of ITEM_ID from b_catalog_product_set UNIQUE (bundle_id, group_code) ); Implementing selection from an option group with min/max
The bundle page displays mandatory items as non-removable (with a checkmark that cannot be removed) and optional ones as checkboxes or radio buttons (if max_select = 1 in the group).
When the selection changes, the script recalculates the total price. The price of each optional component is taken from b_catalog_price by its PRODUCT_ID. It is important to consider user-specific prices: if the buyer has a price group, you need to check b_catalog_price.CATALOG_GROUP_ID. Our custom solution is 10 times faster than the standard one when adding new options to an existing bundle.
function recalcBundle(selectedItems) { const basePrice = bundleData.basePrice; // price of mandatory items let optionsTotal = 0; selectedItems.forEach(itemId => { optionsTotal += bundleData.items[itemId].price; }); document.getElementById('bundle-total').textContent = formatPrice(basePrice + optionsTotal); } Stock checking for optional items
Bundle availability with optional items: we check stock only for mandatory components. Optional ones are checked separately, and we display "available N pieces" next to each checkbox. If an optional item runs out, the checkbox is disabled, but the bundle can be purchased without it. A bundle discount is applied only when all optional items are selected (full configuration) — a common business case. This is implemented via a basket rule: the discount triggers when the set of items in the cart matches the full bundle composition. The rule condition: all ITEM_ID from b_catalog_product_set are present in the cart with the required quantities. For a typical mid-size store, implementing this solution costs approximately $1,500 - $3,000, saving up to 40% on future bundle adjustments.
Adding to cart with selected options
When adding to cart, you need to pass the bundle composition — only the selected items. Via AJAX POST, we send bundle_id and an array selected_items[]. On the server:
// Form the composition for adding to cart $bundle = new \Bitrix\Sale\BasketItem(); // Mandatory items are always taken $requiredItems = \Bitrix\Catalog\ProductSetTable::getList([ 'filter' => ['SET_ID' => $bundleId, 'IS_REQUIRED' => 1], ])->fetchAll(); // Optional items — only from $_POST['selected_items'] $optionalItems = array_intersect( array_column($requiredItems, 'ITEM_ID'), (array)$_POST['selected_items'] ); The final composition is passed to \Bitrix\Catalog\Product\Bundle::Add(). Each component creates a separate row in b_sale_basket with the SET_PARENT_ID flag.
Comparison of standard and custom approach
| Characteristic | Standard mechanism | Our extension |
|---|---|---|
| Mandatory / optional | Only IS_REQUIRED field | Grouping with min/max select |
| Selection from a group | No | Yes, via bl_bundle_option_group |
| Frontend price recalculation | No | Dynamic via JS |
| User-specific prices | No | Yes, via CATALOG_GROUP_ID |
| Discount for full configuration | No | Basket rule |
| Separate stock control | No | Only mandatory affect availability |
Work stages
| Stage | Duration |
|---|---|
| Analysis and schema design | 2 to 5 days |
| Create bl_bundle_option_group table and migration | 1 to 2 days |
| Modify component template (checkboxes, price recalculation) | 3 to 7 days |
| AJAX handler for adding to cart | 2 to 4 days |
| Basket rule for discount | 1 to 2 days |
| Testing and documentation | 2 to 4 days |
What's included in the setup?
- Creation of the
bl_bundle_option_grouptable with grouping parameters - Modification of the component template for displaying the bundle (checkboxes, price recalculation)
- AJAX handler for adding to cart with selected options
- Basket rule for discount on full configuration
- Separate stock check for mandatory and optional items
- Documentation and training for your team
Why trust us with the setup?
We have been working with 1C-Bitrix for over 5 years and have implemented dozens of projects with custom bundles. Our certified specialists ensure stable operation after launch. Contact us for a catalog assessment — we will prepare a technical specification and calculate timelines. Request a project audit — it will help identify bottlenecks in your current bundle implementation. Bitrix24 bundles can also benefit from this approach, ensuring flexibility and scalability.







