Chapters Close

Being the responsible Magento eCommerce development agency, we’re determined to solve your basic custom pricing queries. In this article, you will be learning how to set a custom price for a product programmatically when adding a product to the cart in Magento 2.

Here we are using Aureatelabs as Vendor name and CustomPrice as the name of module.  You can change this according to your Vendor and Module name

The first thing you need to do is to  create an events.xml file in the app/code/Aureatelabs/CustomPrice/etc/frontend folder

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
	<event name="checkout_cart_product_add_after">
    		<observer name="set_custom_price_after_add_to_cart" instance="Aureatelabs\CustomPrice\Observer\CustomPrice" />
	</event>
</config>

Here we are using checkout_cart_product_add_after event which will be called after adding a product to the cart.

Now we need to create an Observer as defined in the event.xml file

So we need to create a CustomPrice.php file in the app/code/Aureatelabs/CustomPrice/Observer folder

<?php

namespace Aureatelabs\CustomPrice\Observer;

use \Magento\Framework\Event\ObserverInterface;

/**
 * Class CustomPrice
 * @package Aureatelabs\CustomPrice\Observer
 *
 */
class CustomPrice implements ObserverInterface
{
	public function execute(\Magento\Framework\Event\Observer $observer) {
		$item = $observer->getEvent()->getData('quote_item');

		// Get parent product if current product is child product
		$item = ( $item->getParentItem() ? $item->getParentItem() : $item );

		//Define your Custom price here
		$price = 100;
	 
		//Set custom price
		$item->setCustomPrice($price);
		$item->setOriginalCustomPrice($price);
		$item->getProduct()->setIsSuperMode(true);
	}
}

Related Sources

  1. How to use Magento 2 custom price renderer
  2. Convert price to current currency in Magento 2

If you’re familiar with the Magento basic fundamentals then you certainly know Magento has been developed to show a variety of prices to your buyers. And below is the bunch of all prices that have their own explanation:

  1. Special Price.
  2. Tier Price.
  3. Grouped Price.
  4. The minimum price of composite products
  5. The price range of composite products
  6. Manufacturer price (MSRP)

Magento represents these prices as price types (e.g. final price, minimum price, maximum price, regular price) and is separate from the actual price in the code. For example, Special Price is represented by the final price type in the code and uses a separate template for each price(e.g. final_price.phtml, tier_price.phtml, default.phtml).

Hence being one of the top Magento web development companies, we wrote a custom module that will show you how to use custom price templates for related product lists. For that, you need to override module-catalog/view/base/templates/product/price/final_price.phtml

Step 1: Create a sample module

Create a new module named PriceTemplate under app/code/Aureatelabs/. Then include the needed registration.php and module.xml files.

File:  app/code/Aureatelabs/PriceTemplate/registration.php

 
 
 
Copy Code
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
   \Magento\Framework\Component\ComponentRegistrar::MODULE,
   'Aureatelabs_PriceTemplate',
   __DIR__
);

File: app/code/Aureatelabs/PriceTemplate/etc/module.xml

 
 
 
Copy Code
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
   <module name="Aureatelabs_PriceTemplate" setup_version="1.0.0"/>
</config>

Run below command to enable the created module.

 
 
 
Copy Code
php bin/magento module:enable Aureatelabs_PriceTemplate
php bin/magento setup:upgrade

Step 2: Create a block

Create a new Aureatelabs\PriceTemplate\Pricing\Render block in our modules layout file catalog_product_view.xml.

File: app/code/Aureatelabs/PriceTemplate/view/frontend/layout/catalog_product_view.xml

 
 
 
Copy Code
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <body>
       <block class="Aureatelabs\PriceTemplate\Pricing\Render" name="product.price.render.custom">
           <arguments>
               <argument name="price_render_handle" xsi:type="string">custom_catalog_product_prices</argument>
               <argument name="use_link_for_as_low_as" xsi:type="boolean">true</argument>
               <!-- set "override" configuration settings here -->
           </arguments>
       </block>
   </body>
</page>

Step 3: Add new price render handle

As we define custom price render handle custom_catalog_product_prices in step 2, now we need to create that handle as below.

File: app/code/Aureatelabs/PriceTemplate/view/frontend/layout/custom_catalog_product_prices.xml

 
 
 
Copy Code
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
   <block class="Magento\Framework\Pricing\Render\RendererPool" name="render.product.prices.custom">
       <arguments>
           <argument name="default" xsi:type="array">
               <item name="default_render_class" xsi:type="string">Magento\Catalog\Pricing\Render\PriceBox</item>
               <item name="default_render_template" xsi:type="string">Magento_Catalog::product/price/default.phtml</item>
               <item name="default_amount_render_class" xsi:type="string">Magento\Framework\Pricing\Render\Amount</item>
               <item name="default_amount_render_template" xsi:type="string">Magento_Catalog::product/price/amount/default.phtml</item>
               <item name="prices" xsi:type="array">
                   <item name="final_price" xsi:type="array">
                       <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\FinalPriceBox</item>
                       <item name="render_template" xsi:type="string">Aureatelabs_PriceTemplate::product/price/final_price_related_product.phtml</item>
                   </item>
               </item>
           </argument>
       </arguments>
   </block>
</layout>

Step 4: Create Price Render class

As mentioned in step 2, Block type of product.price.render.custom is Aureatelabs\PriceTemplate\Pricing\Render

Hence create the same class and extend Magento\Framework\Pricing\Render

File: app/code/Aureatelabs/PriceTemplate/Pricing/Render.php

 
 
 
Copy Code
<?php

namespace Aureatelabs\PriceTemplate\Pricing;

use Magento\Framework\Pricing\SaleableInterface;

/**
* Base price render
*
* @api
* @method string getPriceRenderHandle()
*
* @api
*/
class Render extends \Magento\Framework\Pricing\Render
{
   /**
    * Render price
    *
    * @param string $priceCode
    * @param SaleableInterface $saleableItem
    * @param array $arguments
    * @return string
    * @throws \InvalidArgumentException
    * @throws \RuntimeException
    */
   public function render($priceCode, SaleableInterface $saleableItem, array $arguments = [])
   {
       $useArguments = array_replace($this->_data, $arguments);

       /** @var \Magento\Framework\Pricing\Render\RendererPool $rendererPool */
       $rendererPool = $this->priceLayout->getBlock('render.product.prices.custom');
       if (!$rendererPool) {
           throw new \RuntimeException('Wrong Price Rendering layout configuration. Factory block is missed');
       }

       // obtain concrete Price Render
       $priceRender = $rendererPool->createPriceRender($priceCode, $saleableItem, $useArguments);
       return $priceRender->toHtml();
   }
}

Here we’ve layout render.product.prices.custom block which was defined previously in catalog_product_view.xml file of our module.

As we want to change the price template for only related product only, now we need to override \Magento\Catalog\Block\Product\ProductList\Related, so first create a preference in di.xml file.

File: app/code/Aureatelabs/PriceTemplate/etc/frontend/di.xml

 
 
 
Copy Code
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\ProductList\Related" type="Aureatelabs\PriceTemplate\Block\Product\ProductList\Related"/>
</config>

Here we’ve told Magento whenever someone requests that the object manager instantiate an Aureatelabs\PriceTemplate\Block\Product\ProductList\Related object instead of Magento\Catalog\Block\Product\ProductList\Related object.

So, create a block class in our module.

File: app/code/Aureatelabs/PriceTemplate/Block/Product/ProductList/Related.php

 
 
 
Copy Code
<?php
namespace Aureatelabs\PriceTemplate\Block\Product\ProductList;

class Related extends \Magento\Catalog\Block\Product\ProductList\Related
{
   /**
    * Return HTML block
    *
    * @param \Magento\Catalog\Model\Product $product
    * @param string $priceType
    * @param string $renderZone
    * @param array $arguments
    * @return string
    * @throws \Magento\Framework\Exception\LocalizedException
    */
   public function getProductPriceHtml(
       \Magento\Catalog\Model\Product $product,
       $priceType,
       $renderZone = \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST,
       array $arguments = []
   ) {
       if (!isset($arguments['zone'])) {
           $arguments['zone'] = $renderZone;
       }

       /** @var \Magento\Framework\Pricing\Render $priceRender */
       $priceRender = $this->getLayout()->getBlock('product.price.render.custom');
       $price = '';

       if ($priceRender) {
           $price = $priceRender->render($priceType, $product, $arguments);
       }
       return $price;
   }
}

Step 6: Create a custom template file

Now, the final step is to create a custom template for the final price and do changes as per your requirement.

File: app/code/Aureatelabs/PriceTemplate/view/frontend/templates/product/price/final_price_related_product.phtml

 
 
 
Copy Code
<?php
// @codingStandardsIgnoreFile
?>

<?php
/** @var \Magento\Catalog\Pricing\Render\FinalPriceBox $block */

$productId = $block->getSaleableItem()->getId();
//$currentProductId = $block->getRequest()->getParam('id');

/** ex: \Magento\Catalog\Pricing\Price\RegularPrice */
/** @var \Magento\Framework\Pricing\Price\PriceInterface $priceModel */
$priceModel = $block->getPriceType('regular_price');

/** ex: \Magento\Catalog\Pricing\Price\FinalPrice */
/** @var \Magento\Framework\Pricing\Price\PriceInterface $finalPriceModel */
$finalPriceModel = $block->getPriceType('final_price');
$idSuffix = $block->getIdSuffix() ? $block->getIdSuffix() : '';
$schema = ($block->getZone() == 'item_view') ? true : false;
?>
<?php if ($block->hasSpecialPrice()): ?>
   <span class="special-price">
       <?php /* @escapeNotVerified */ echo $block->renderAmount($finalPriceModel->getAmount(), [
           'display_label'     => __('Special Price'),
           'price_id'          => $block->getPriceId('product-price-' . $idSuffix),
           'price_type'        => 'finalPrice',
           'include_container' => true,
           'schema' => $schema
       ]); ?>
   </span>
<?php else: ?>
   <?php /* @escapeNotVerified */ echo $block->renderAmount($finalPriceModel->getAmount(), [
       'price_id'          => $block->getPriceId('product-price-' . $idSuffix),
       'price_type'        => 'finalPrice',
       'include_container' => true,
       'schema' => $schema
   ]); ?>
<?php endif; ?>

<?php if ($block->showMinimalPrice()): ?>
   <?php if ($block->getUseLinkForAsLowAs()):?>
       <a href="<?= /* @escapeNotVerified */ $block->getSaleableItem()->getProductUrl() ?>" class="minimal-price-link">
           <?= /* @escapeNotVerified */ $block->renderAmountMinimal() ?>
       </a>
   <?php else:?>
       <span class="minimal-price-link">
           <?= /* @escapeNotVerified */ $block->renderAmountMinimal() ?>
       </span>
   <?php endif?>
<?php endif; ?>

Conclusion

In this way, you’re done with the successful module building to change price templates for related products only. In case you’re stuck in between and need any help in this regard, we’re all glad to help you. Feel free to contact us.

In this article, I’ve shown you how to change price templates for related products step by step. If you still need any help regarding the price template or Magento, we are happy to help you. Feel free to get in touch!

Also read: Set custom price programmatically in Magento 2

FAQs

How do I change price in Magento?


To change price in Magento, follow the below steps:
1. Login to the admin dashboard.
2. Click on the “Catalog” menu and open the “Manage products” page.
3. Click on the product whose price you want to edit.
4. In the blank labeled “Price,” write the updated price. 
5. Click the save button at the button to save the new price.
You can also change the price of multiple products at once by clicking on the “Actions” button at the top.

What is final price in magento2?


The final price in Magento 2 is the base price of the product plus any additional costs or discounts. It can be higher or lower than the base price and is the cost customers pay while making the final purchase of the product. Usually, final price = base price + tax +shipping +other costs – discounts.

How to override Final_price Phtml in Magento 2?


To override final_price.phtml in Magento 2, follow these steps:

1. Create Vendor Module as app/code/Vendor/Extension/etc/di.xml
 <type name="Magento\Catalog\Pricing\Render\FinalPriceBox">
        <plugin name="override_price_block" type="Vendor\Extension\Plugin\FinalPricePlugin" />
</type>

2. Next, create the Plugin file in Vendor Module as app/code/Vendor/Extension/Plugin/FinalPricePlugin.php -
<?php
namespace Vendor\Extension\Plugin;
class FinalPricePlugin
{
    public function beforeSetTemplate(\Magento\Catalog\Pricing\Render\FinalPriceBox $subject, $template)
    {
        if ($template == 'Magento_Catalog::product/price/final_price.phtml') {
           return ['Vendor_Extension::product/price/final_price.phtml'];
        } 
        else
        {
            return [$template];
        }
    }
}

3. Further, create a new template file in Vendor Module as app/code/Vendor/Extension/view/frontend/templates/product/price/final_price.phtml.
4. Now, copy the content of the default template file you want to override and make the required changes.

How do I add custom text under the price in frontend?


To add custom text under the price on the front end, you can use a plugin by following the below-mentioned steps –

1. Create a Custom Price Module as app/code/CustomPriceText/etc/di.xml
<type name="Magento\Catalog\Pricing\Render\PriceBox">
<plugin name="add_custom_text_under_price" type="CustomPriceText\Pricing\Plugin\AddCustomTextUnderPrice"/>
</type>

2. Next, create a Plugin folder under the Custom Price Module as app/code/CustomPriceText/Pricing/Plugin.
3. Now, create AddCustomTextUnderPrice.php in the above folder and use the code – 
<?php
namespace CustomPriceText\Pricing\Plugin;
use Magento\Framework\View\Element\Template;
class AddCustomTextUnderPrice
{
    public function afterToHtml(Template $subject, $result)
    {
        $customText = "Custom Text";
        $result .= "<div>{$customText}</div>";
        return $result;
    }
}

4. Refresh the cache and run the setup:upgrade command.

Grow your online business like 3,853 subscribers

    * This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
    envelope

    Thank You!

    We are reviewing your submission, and will be in touch shortly.