I need to change the logic of the tier price calculation. I have special prices on my site and their calculation depends on a product base price, but I need to calculate it depending on the special price. I found a partial solution in How to override magento2 product tierprice? and it works only in a PDP when I visit the cart - it doesn't change the price with changing qty, the price for a is always special price... My code is:


<type name="Magento\Catalog\Model\Product">
    <plugin name="after_final_price" type="Vendor\TierPriceOnSpecialPrice\Plugin\ChangeTierPrice" sortOrder="999" disabled="false" />
<type name="Magento\Catalog\Pricing\Price\FinalPrice">
    <plugin name="after_final_price_info" type="Vendor\TierPriceOnSpecialPrice\Plugin\ChangeTierPriceInfo" sortOrder="999" disabled="false" />

Plugins code the same like below:

public function beforeGetFinalPrice($subject, $qty = null)
    $specialPrice = $subject->getSpecialPrice();
    $oldTierPrices = $subject->getData('tier_price');
    $newTierPrices = [];

    if ($oldTierPrices) {
        foreach ($oldTierPrices as $tierPriceName => $tierPriceData) {
            $calculatedTierPrice = $specialPrice - ($tierPriceData['percentage_value'] / 100) * $specialPrice;
            $newTierPrices[$tierPriceName] = [
                'price_id' => $tierPriceData['price_id'],
                'website_id' => $tierPriceData['website_id'],
                'all_groups' => $tierPriceData['all_groups'],
                'cust_group' => $tierPriceData['cust_group'],
                'price' => $calculatedTierPrice,
                'price_qty' => $tierPriceData['price_qty'],
                'percentage_value' => $tierPriceData['percentage_value'],
                'product_id' => $tierPriceData['product_id'],
                'website_price' => $calculatedTierPrice

    //You need to create your own array or modify the default tier price here and set in to product object
    $subject->setData('tier_price', $newTierPrices);

2 Answers 2


You need to subscribe to the checkout_cart_product_add_after event. To do this, in the etc folder of your module, you need to create an events.xml file with something like this.

<?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="custom_cart_item_price" instance="Vendor\ModuleName\Observer\CustomCartItemPrice" />

Then you need to create the observer file itself, where you describe the price logic you need on the cart.


namespace Vendor\ModuleName\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class CustomCartItemPrice implements ObserverInterface
    public function execute(Observer $observer): void
        $item = $observer->getEvent()->getData('quote_item');
        $newCustomPrice = 100; //For example set new item price to 100
  • After some code modifications of my plugins it's working, but only with the "add to cart" feature, when I'm trying to update qty in a cart - it's static. It's possible to try to develop the second observer for the update action, but it'll the code duplication fragments in 4 places, not sure that it's correct. What do you think? Also, I'm not sure about the update action, because the checkout_cart_update_items_after event isn't storing the tier prices(or I checked it bad). Commented Nov 28, 2022 at 21:18

As for me, the best way is to create preference for \Magento\Catalog\Model\Product\Attribute\Backend\Tierprice class.

In your di.xml:

<preference for="Magento\Catalog\Model\Product\Attribute\Backend\Tierprice"

And \Company\Module\Rewrite\Magento\Catalog\Model\Product\Attribute\Backend\Tierprice:


namespace Company\Module\Rewrite\Magento\Catalog\Model\Product\Attribute\Backend;

use Magento\Catalog\Model\Product;

 * Class Tierprice
class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\Tierprice
    protected function modifyPriceData($object, $data)
        /** @var Product $object */
        $data = parent::modifyPriceData($object, $data);
        foreach ($data as $key => $tierPrice) {
            $percentageValue = $this->getPercentage($tierPrice);
            if ($percentageValue) {
                // Implement your logic to get correct base price here:
                $price = $this->yourCustomFunctionForPrice();

                $data[$key]['price'] = $price * (1 - $percentageValue / 100);
                $data[$key]['website_price'] = $data[$key]['price'];
        return $data;

I hope this will help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.