Back to Top

How To Set Custom Discount Or Fee At Cart In Magento 2

Updated 5 January 2023

How To Set Custom Discount Or Fee At Cart In Magento 2 : here i am going to explain , how you can set a discount or fee in cart. it obvious that if you set a discount, you have to subtract the discount amount from the cart price and if you want to set fee on cart price. then it will be added.

1 => first you have to create a sales.xml file on app/code/companyname/module/etc

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
    <section name="quote">
        <group name="totals">
            <item name="customdiscount" instance="companyname\module\Model\Quote\Address\Total\CustomDiscount" sort_order="400"/>
        </group>
    </section>
</config>

2 => create file CustomDiscount.php on this path app\code\companyname\module\Model\Quote\Address\Total

namespace companyname\module\Model\Quote\Address\Total;

class CustomDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{

    /**
    * @var \Magento\Framework\Pricing\PriceCurrencyInterface
    */
    protected $_priceCurrency;

    /**
     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency [description]
     */
    public function __construct(
        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
    ) {
        $this->_priceCurrency = $priceCurrency;
    }

    public function collect(
        \Magento\Quote\Model\Quote $quote,
        \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
        \Magento\Quote\Model\Quote\Address\Total $total
    ) {
        parent::collect($quote, $shippingAssignment, $total);

            $customDiscount = -10;

            $total->addTotalAmount('customdiscount', $customDiscount);
            $total->addBaseTotalAmount('customdiscount', $customDiscount);
            $quote->setCustomDiscount($customDiscount);
        return $this;
    }

    /**
     * Assign subtotal amount and label to address object
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param Address\Total $total
     * @return array
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
    {
        return [
            'code' => 'Custom_Discount',
            'title' => $this->getLabel(),
            'value' => 10
        ];
    }

    /**
     * get label
     * @return string
     */
    public function getLabel()
    {
        return __('Custom Discount');
    }
}

3 => create file checkout_cart_index.xml on path app\code\companyname\module\view\frontend\layout

<?xml version="1.0"?>
<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="checkout.cart.totals">
		   <arguments>
		       <argument name="jsLayout" xsi:type="array">
		           <item name="components" xsi:type="array">
		               <item name="block-totals" xsi:type="array">
		                   <item name="children" xsi:type="array">
		                       <item name="customdiscount" xsi:type="array">
		                           <item name="component"  xsi:type="string">companyname_module/js/view/checkout/summary/custom-discount</item>
		                           <item name="sortOrder" xsi:type="string">20</item>
		                           <item name="config" xsi:type="array">
		                               <item name="customdiscount" xsi:type="string" translate="true">Custom Discount</item>
		                           </item>
		                       </item>
		                   </item>
		               </item>
		           </item>
		       </argument>
		   </arguments>
		</referenceBlock>
    </body>
</page>

4 => create another file checkout_index_index.xml on same location.

Searching for an experienced
Magento 2 Company ?
Find out More
<?xml version="1.0"?>
<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="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="sidebar" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="summary" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="totals" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                       <item name="customdiscount" xsi:type="array">
                                                            <item name="component"  xsi:type="string">companyname_module/js/view/checkout/cart/totals/custom-discount</item>
                                                            <item name="sortOrder" xsi:type="string">20</item>
                                                            <item name="config" xsi:type="array">
                                                                 <item name="template" xsi:type="string">companyname_module/checkout/cart/totals/custom-discount</item>
                                                                <item name="title" xsi:type="string" translate="true">Custom Discount</item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                                <item name="cart_items" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="details" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="subtotal" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/summary/item/details/subtotal</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>


5 => create file custom-discount.js on path app/code/companyname/module/view/frontend/web/js/view/checkout/cart/totals

define(
    [
        'companyname_module/js/view/checkout/summary/custom-discount'
    ],
    function (Component) {
        'use strict';

        return Component.extend({

            /**
             * @override
             */
            isDisplayed: function () {
                return true;
            }
        });
    }
);

6 => create file on this path custom-discount.js app/code/companyname/module/view/frontend/web/js/view/checkout/summary

define(
    [
       'jquery',
       'Magento_Checkout/js/view/summary/abstract-total',
       'Magento_Checkout/js/model/quote',
       'Magento_Checkout/js/model/totals',
       'Magento_Catalog/js/price-utils'
    ],
    function ($,Component,quote,totals,priceUtils) {
        "use strict";
        return Component.extend({
            defaults: {
                template: 'companyname_module/checkout/summary/custom-discount'
            },
            totals: quote.getTotals(),
            isDisplayedCustomdiscountTotal : function () {
                return true;
            },
            getCustomdiscountTotal : function () {
                var price = 10;
                return this.getFormattedPrice(price);
            }
         });
    }
);


7 => create file custom-discount.html on path app/code/companyname/module/view/frontend/web/template/checkout/cart/totals

<!-- ko if: isDisplayedCustomdiscountTotal() -->
<tr class="totals customdiscount excl">
    <th class="mark" colspan="1" scope="row" data-bind="text: title"></th>
    <td class="amount">
        <span class="price" data-bind="text: getCustomdiscountTotal()"></span>
    </td>
</tr>
<!-- /ko -->

8 => create file custom-discount.html on path app/code/companyname/module/view/frontend/web/template/checkout/summary

<!-- ko if: isDisplayedCustomdiscountTotal() -->
<tr class="totals coupon-discount excl">
   <th class="mark" colspan="1" scope="row" data-bind="text: customdiscount"></th>
   <td class="amount">
       <span class="price" data-bind="text: getCustomdiscountTotal(), attr: {'data-th': customdiscount}"></span>
   </td>
</tr>
<!-- /ko -->


finally you can see the custom discount amount on your cart and checkout page.

customdiscount111
customdiscount22

hope so it will help you !

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


9 comments

  • Aman
  • Andžej Teličan
  • Andžej Teličan
    • Webkul Support
      • Andžej Teličan
        • Webkul Support
  • Jessy Loran
  • Felipe Castilla
  • Masterarts
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home