Skip to content
intermediate Phase 42 · Product Types

Configurable Products

Configurable products including configurable attributes, variations, pricing, and stock management

1h
0 problems
Topic Progress 0%

Configurable Product Overview

Configurable vs Simple

Simple Product:
  TSHIRT-BLUE-L → Single SKU, one variant

Configurable Product:
  TSHIRT → Parent product (no stock)
    ├── TSHIRT-BLUE-L → Child (simple product)
    ├── TSHIRT-BLUE-M → Child (simple product)
    ├── TSHIRT-RED-L  → Child (simple product)
    └── TSHIRT-RED-M  → Child (simple product)

Configurable Product Structure

-- Parent configurable product
SELECT entity_id, sku, type_id
FROM catalog_product_entity
WHERE entity_id = 100;
+-----------+--------+--------------+
| entity_id | sku    | type_id      |
+-----------+--------+--------------+
|       100 | TSHIRT | configurable |
+-----------+--------+--------------+

-- Child simple products
SELECT entity_id, sku, type_id
FROM catalog_product_entity
WHERE entity_id IN (101, 102, 103, 104);
+-----------+---------------+--------+
| entity_id | sku           | type_id|
+-----------+---------------+--------+
|       101 | TSHIRT-BLUE-L | simple |
|       102 | TSHIRT-BLUE-M | simple |
|       103 | TSHIRT-RED-L  | simple |
|       104 | TSHIRT-RED-M  | simple |
+-----------+---------------+--------+

Link Table

-- catalog_product_super_attribute (configurable attributes)
SELECT * FROM catalog_product_super_attribute WHERE product_id = 100;
+----------+------------+---------------+------------+
| product_id | attribute_id | position    | label      |
+----------+------------+---------------+------------+
|      100 |         92 |             1 | Color      |
|      100 |        136 |             2 | Size       |
+----------+------------+---------------+------------+

-- catalog_product_super_link (parent-child)
SELECT * FROM catalog_product_super_link WHERE parent_id = 100;
+----------+------------+
| parent_id | product_id |
+----------+------------+
|      100 |        101 |
|      100 |        102 |
|      100 |        103 |
|      100 |        104 |
+----------+------------+

Configurable Attributes

Creating Configurable Product

// Create configurable product
$configurableProduct = $objectManager->get(
    \Magento\Catalog\Model\ProductFactory::class
)->create();

$configurableProduct->setName('T-Shirt')
    ->setSku('TSHIRT')
    ->setPrice(29.99)
    ->setStatus(1)
    ->setVisibility(4)
    ->setAttributeSetId(4)
    ->setTypeId('configurable')
    ->save();

// Create configurable attributes
$configurableProduct = $objectManager->get(
    \Magento\Catalog\Model\Product\Configurable\Factory::class
)->create();

$configurableOptions = [
    [
        'attribute_id' => 92,  // color attribute
        'code' => 'color',
        'label' => 'Color',
        'position' => 1,
        'values' => [
            ['value_index' => 10, 'label' => 'Blue'],
            ['value_index' => 14, 'label' => 'Red'],
        ]
    ],
    [
        'attribute_id' => 136, // size attribute
        'code' => 'size',
        'label' => 'Size',
        'position' => 2,
        'values' => [
            ['value_index' => 166, 'label' => 'L'],
            ['value_index' => 167, 'label' => 'M'],
        ]
    ]
];

$configurableProduct->setConfigurableOptions($configurableOptions);
$configurableProduct->save();

Add Child Products

// Create child products
$childProducts = [
    ['sku' => 'TSHIRT-BLUE-L', 'color' => 10, 'size' => 166],
    ['sku' => 'TSHIRT-BLUE-M', 'color' => 10, 'size' => 167],
    ['sku' => 'TSHIRT-RED-L', 'color' => 14, 'size' => 166],
    ['sku' => 'TSHIRT-RED-M', 'color' => 14, 'size' => 167],
];

foreach ($childProducts as $childData) {
    $child = $objectManager->get(
        \Magento\Catalog\Model\ProductFactory::class
    )->create();

    $child->setName('T-Shirt ' . $childData['color'] . ' ' . $childData['size'])
        ->setSku($childData['sku'])
        ->setPrice(29.99)
        ->setStatus(1)
        ->setVisibility(1) // Not visible individually
        ->setAttributeSetId(4)
        ->setTypeId('simple')
        ->setStockData(['qty' => 50, 'is_in_stock' => 1])
        ->save();

    // Link to parent
    $link = $objectManager->get(
        \Magento\ConfigurableProduct\Model\LinkFactory::class
    )->create();
    $link->setProductId($child->getId())
        ->setParentId($configurableProduct->getId())
        ->setPosition(0)
        ->save();
}

Pricing for Configurables

Price Configuration

// Configurable product price (base)
$configurableProduct->setPrice(29.99);

// Child product prices (can differ)
$child->setPrice(29.99); // Same as parent
// Or different:
$child->setPrice(34.99); // Premium variant

// Special price on parent
$configurableProduct->setSpecialPrice(24.99);

// Special price on child
$child->setSpecialPrice(27.99);

Price Index

-- Price index includes all combinations
SELECT * FROM catalog_product_index_price 
WHERE entity_id IN (100, 101, 102, 103, 104) 
AND customer_group_id = 0 AND website_id = 1;
+-----------+-------------------+-----------+-------+-------+--------+
| entity_id | customer_group_id | website_id | price | final_price | min_price |
+-----------+-------------------+-----------+-------+-------+--------+
|       100 |                 0 |         1 | 29.99 |    29.99 |    29.99 |
|       101 |                 0 |         1 | 29.99 |    29.99 |    29.99 |
|       102 |                 0 |         1 | 29.99 |    29.99 |    29.99 |
|       103 |                 0 |         1 | 34.99 |    34.99 |    34.99 |
|       104 |                 0 |         1 | 34.99 |    34.99 |    34.99 |
+-----------+-------------------+-----------+-------+-------+--------+

Price Display

// Get configurable product price range
$priceInfo = $configurableProduct->getPriceInfo();
$minPrice = $priceInfo->getPrice('final_price')->getMinimalPrice();
$maxPrice = $priceInfo->getPrice('final_price')->getMaximalPrice();

// Get price for specific option
$optionPrice = $priceInfo->getPrice('final_price')->getValue();

// Display price range on frontend
// $29.99 - $34.99

Stock Management

Stock Configuration

// Configurable product stock (not tracked)
$configurableProduct->setStockData([
    'use_config_manage_stock' => 1,
    'is_in_stock' => 1,  // Based on children
    'manage_stock' => 0, // Don't manage parent stock
]);

// Child product stock (tracked)
$child->setStockData([
    'qty' => 50,
    'is_in_stock' => 1,
    'manage_stock' => 1,
]);

Stock Status Logic

Configurable product is in stock if:
  ✓ At least ONE child product is in stock

Configurable product is out of stock if:
  ✗ ALL child products are out of stock

Example:
  TSHIRT-BLUE-L: qty=50 (in stock)
  TSHIRT-BLUE-M: qty=0 (out of stock)
  TSHIRT-RED-L: qty=0 (out of stock)
  TSHIRT-RED-M: qty=25 (in stock)

  → TSHIRT (configurable) is IN STOCK

Stock Index

-- Check stock status for configurable
SELECT entity_id, is_salable
FROM cataloginventory_stock_status
WHERE product_id = 100;
+-----------+-----------+
| product_id | is_salable |
+-----------+-----------+
|       100 |         1 |
+-----------+-----------+

-- Check child stock
SELECT product_id, qty, is_salable
FROM cataloginventory_stock_status
WHERE product_id IN (101, 102, 103, 104);
+-----------+------+-----------+
| product_id | qty  | is_salable |
+-----------+------+-----------+
|       101 |   50 |         1 |
|       102 |    0 |         0 |
|       103 |    0 |         0 |
|       104 |   25 |         1 |
+-----------+------+-----------+

Best Practices

1. Create simple products first, then configurable
2. Set child visibility to 1 (not visible individually)
3. Use meaningful SKUs for variants
4. Manage stock on child products
5. Set appropriate prices per variant
6. Test all option combinations
7. Use swatch attributes for visual selection

Quiz

1. What is a configurable product?

Question 1 options

2. What visibility should child products have?

Question 2 options

3. When is a configurable product in stock?

Question 3 options

Flashcards

Question

What is a configurable product?

Answer

Parent product with child simple products as variants (size, color, etc.)

Question

What is child product visibility?

Answer

1 (Not Visible Individually) - only configurable shows

Question

How is stock managed?

Answer

On child products - configurable is in stock if any child is in stock

Question

What are configurable attributes?

Answer

Attributes defining variants (color, size, material)

Question

How to link children to parent?

Answer

catalog_product_super_link table with parent_id and product_id

Revision Notes

Key Takeaways

  • 1. Configurable products are parents with child simple products as variants
  • 2. Child products have visibility=1 (not visible individually)
  • 3. Stock managed on children - configurable in stock if any child is
  • 4. Configurable attributes define variant options (color, size)
  • 5. Price can differ between parent and children

Interview Tips

  • Explain the relationship between configurable and simple products
  • Discuss stock management logic for configurables
  • Describe how price ranges work for configurable products

Cheat Sheet

Configurable Product:
  type_id = 'configurable'
  Parent with child variants

Tables:
  catalog_product_super_attribute → Configurable attributes
  catalog_product_super_link → Parent-child links

Child Products:
  type_id = 'simple'
  visibility = 1 (not visible)
  SKU = variant-specific

Stock:
  Parent: manage_stock=0
  Child: manage_stock=1, qty tracked
  In stock if ANY child is in stock

Price:
  Parent: base price
  Child: can differ per variant
  Display: price range