How to Add a Custom Discount in Magento 2?

Add Magento 2 Custom Discount

Here are the steps that you will follow in this How to add a custom discount in Magento 2?

  1. Register a total in the file xml
  2. Add discount to change the grand total in the model
  3. Add the total in the layout file
  4. View model knockout

Add a Custom Discount in Magento 2

  • First, we will register a total in the file xml app/code/Magestore/Webpos/etc/sales.xml:
<section name="quote">

   <group name="totals">

     <item name="customer_discount" instance="Magestore\Webpos\Model\Total\Quote\Custom" sort_order="420"/>



  • And then, we will add the discount to change the grandtotal in the model app/code/Magestore/Webpos/Model/Total/Quote/Custom.php:

namespace Magestore\Webpos\Model\Total\Quote;


* Class Custom

* @package Magestore\Webpos\Model\Total\Quote


class Custom extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal



    * @var \Magento\Framework\Pricing\PriceCurrencyInterface


   protected $_priceCurrency;


    * Custom constructor.

    * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency


   public function __construct(

       \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency


       $this->_priceCurrency = $priceCurrency;



    * @param \Magento\Quote\Model\Quote $quote

    * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment

    * @param \Magento\Quote\Model\Quote\Address\Total $total

    * @return $this|bool


   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);

           $baseDiscount = 10;

           $discount =  $this->_priceCurrency->convert($baseDiscount);

           $total->addTotalAmount('customdiscount', -$discount);

           $total->addBaseTotalAmount('customdiscount', -$baseDiscount);

           $total->setBaseGrandTotal($total->getBaseGrandTotal() - $baseDiscount);


       return $this;


  • Now, you will see the Grand Total was changed. But there is no total discount information. Because the Magento use knockout js to show the total. We need to add the total to the layout file


<?xml version="1.0"?>

<page xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">


       <referenceBlock name="checkout.cart.totals">


           <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="custom_discount" xsi:type="array">

           <item name="component"  xsi:type="string">Magestore_Webpos/js/view/checkout/summary/customdiscount</item>

           <item name="sortOrder" xsi:type="string">20</item>

           <item name="config" xsi:type="array">

           <item name="custom_discount" xsi:type="string" translate="true">Custom Discount</item>











  • It will call view model knockout







   function ($,Component) {

       "use strict";

       return Component.extend({

           defaults: {

               template: 'Magestore_Webpos/checkout/summary/customdiscount'


           isDisplayedCustomdiscount : function(){

               return true;


           getCustomDiscount : function(){

               return '$10';




  • And the total discount will be shown in the template knockout


<!-- ko if: isDisplayedCustomdiscount() -->

<tr class="totals customdiscount excl">

   <th class="mark" colspan="1" scope="row" data-bind="text: custom_discount"></th>

   <td class="amount">

       <span class="price" data-bind="text: getCustomDiscount(), attr: {'data-th': custom_discount}"></span>



<!-- /ko -->

For more Magento tutorial, visit Webnexs Magento Knowledge Base.









Leave a Reply

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