There are scenarios where you might want to include unique options for certain products in the cart, such as attaching a warranty, adding a gift item, or offering text or dropdown customizations.

Programmatically adding products with custom options is a robust feature that allows you to customize the shopping experience to meet specific customer needs.

Earlier we showed you How to create a custom price for a specific product and customer in Magento 2

But what if you want to know how to add product to cart programmatically with custom options in Magento 2? 

So, here’s the step-by-step guide and learn how to enhance your cart functionality with custom options!

Before We Begin…

Know that this solution can be beneficial for implementing an automatic “Add to cart” functionality for configurable products with custom options. For instance, the store might include a free product with a specific item, attach a warranty, or add a gift product, or add a custom option like text or with a dropdown option. 

How To Create A Module To Add Custom Options With Products Into The Cart? 

Let’s create a module to add some custom options with products into the cart.

Step 1: Create the Module Registration File

You need to register your custom module using registration.php.Path: app/code/Klizer/AdditionalOption/registration.php

<?php

/**
 * Klizer
 *
 * @category  Klizer
 * @package   Klizer_AdditionalOption
 * @copyright Copyright © 2025 Klizer. All rights reserved.
 * @author    Klizer - info@klizer.com
 */

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Klizer_AdditionalOption',
    __DIR__
);

Step 2: Define the Module in module.xml

Now define the module using the below path.

Path: app/code/Klizer/AdditionalOption/etc/module.xml

<?xml version="1.0"?>
<!--
/**
 * Klizer
 *
 * @category  Klizer
 * @package   Klizer_AdditionalOption
 * @copyright Copyright © 2025 Klizer. All rights reserved.
 * @author    Klizer - info@klizer.com
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Klizer_AdditionalOption" setup_version="1.0.0">
    </module>
</config>

Step 3: Create layout file : catalog_product_view.xml

Path : app/code/Klizer/AdditionalOption/view/frontend/layout/catalog_product_view.xml

<?xml version="1.0"?>
<!--
/**
 * Klizer
 *
 * @category  Klizer
 * @package   Klizer_AdditionalOption
 * @copyright Copyright © 2025 Klizer. All rights reserved.
 * @author    Klizer - info@klizer.com
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.addtocart">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Klizer_AdditionalOption::product/view/addtocart.phtml</argument>
            </action>
        </referenceBlock>
        <referenceBlock name="product.info.addtocart.additional">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Klizer_AdditionalOption::product/view/addtocart.phtml</argument>
            </action>
        </referenceBlock>      
    </body>
</page>

Step 4: Create phtml file : addtocart.phtml

Path : app/code/Klizer/AdditionalOption/view/frontend/templates/product/view/addtocart.phtml

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/** @var $block \Magento\Catalog\Block\Product\View */
?>
<?php $_product = $block->getProduct(); ?>
<?php $buttonTitle = __('Add to Cart'); ?>
<?php if ($_product->isSaleable()) :?>
<!-- Custom Input Field Start-->

<div>
    <label for="notes">
        <?= __('Notes:'); ?>
    </label>
    <input type="text" name="notes" id="notes" maxlength="255" placeholder="Notes"/>
</div>
<!-- Custom Input Field End-->
<div class="box-tocart">
    <div class="fieldset">
        <?php if ($block->shouldRenderQuantity()) :?>
        <div class="field qty">
            <label class="label" for="qty"><span><?= $block->escapeHtml(__('Qty')) ?></span></label>
            <div class="control">
                <input type="number"
                       name="qty"
                       id="qty"
                       min="0"
                       value="<?= $block->getProductDefaultQty() * 1 ?>"
                       title="<?= $block->escapeHtmlAttr(__('Qty')) ?>"
                       class="input-text qty"
                       data-validate="<?= $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
                       />
            </div>
        </div>
        <?php endif; ?>
        <div class="actions">
            <button type="submit"
                    title="<?= $block->escapeHtmlAttr($buttonTitle) ?>"
                    class="action primary tocart"
                    id="product-addtocart-button" disabled>
                <span><?= $block->escapeHtml($buttonTitle) ?></span>
            </button>
            <?= $block->getChildHtml('', true) ?>
        </div>
    </div>
</div>
<?php endif; ?>
<script type="text/x-magento-init">
    {
        "#product_addtocart_form": {
            "Magento_Catalog/js/validate-product": {}
        }
    }
</script>

Step 5: Create Observer file : SetAdditionalOptions.php

Path : app/code/Klizer/AdditionalOption/Observer/SetAdditionalOptions.php

<?php

/**
 * Klizer
 *
 * @category  Klizer
 * @package   Klizer_AdditionalOption
 * @copyright Copyright © 2025 Klizer. All rights reserved.
 * @author    Klizer - info@klizer.com
 */

namespace Klizer\AdditionalOption\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Serialize\Serializer\Json;

class SetAdditionalOptions implements ObserverInterface
{
    /**
     * @var SerializerInterface|null
     */
    private $serializer;
    /**
     * @param RequestInterface $request
     */    
    protected $_request;  

    public function __construct(
        RequestInterface $request, 
        Json $serializer = null
        ) 
    {
        $this->_request = $request;
        $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
            ->get(\Magento\Framework\Serialize\Serializer\Json::class);
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getProduct();    
        $post = $this->_request->getParam('notes');

        /*Set Notes Value When Product Add To Cart Start*/
   $fullActionName = $this->_request->getFullActionName();
        if(($fullActionName == 'checkout_cart_add') && $post)
        {
            $product = $observer->getProduct();
            $additionalOptions = [];
            $additionalOptions[] = array(
                'label' => "Notes",
                'value' => $post,
                'option_value' => ''
            );                        
            $product->addCustomOption('additional_options', $this->serializer->serialize($additionalOptions));
        }
        /*Set Notes Value When Product Add To Cart End*/
    }
}

You can set the multiple options using the same approach.

Using this approach you can set additional options in cart item and you will be able to view this information on all pages.

Product Page:

Mini Cart:

Cart Page:

Checkout Page:

Add Products To Cart Programatically Using Custom Options With Klizer

That’s it! This is how you can add products to cart programmatically with custom options. 

By now, you should have a solid understanding of the concept of Observers in Magento 2. We have developed a custom module that added an additional option to the cart. 

If you have any questions about the process or want to contribute to the discussion, feel free to leave a comment below. Don’t forget to share this article with your Magento developers and if you still have any doubts, contact us for Magento 2 solutions.

Picture of Vrajesh Patel

Vrajesh Patel

Vrajesh Patel is a skilled and passionate Magento Developer at Klizer (DCKAP) with a proven track record of creating exceptional and innovative ecommerce solutions. With over 5 years of experience in the field and a commitment to continuous learning, he excels in exploring the latest advancements and remains dedicated to delivering exceptional solutions.

Begin Your eCommerce Journey

Get Expert Advice

At Klizer, we bring over 18 years of specialized expertise in ecommerce website development and design.

© Copyright 2024 Klizer. All Rights Reserved

Scroll to Top