How to Add a Custom Discount Programmatically in Magento 2?

Today, we’re going to teach you guys how to add a custom discount programmatically in Magento 2 store.

Many times, all eCommerce businesses go through a period where the sales go down. 

Sales can slow down for many reasons — seasonality, changing customer behavior, or market competition. During these times, store owners often turn to promotional strategies to boost conversions. One proven tactic is offering custom discounts at checkout.

Instead of using Magento's built-in cart rules, sometimes you might want more control. In this tutorial, we’ll walk you through how to add a custom discount programmatically in Magento 2 using simple steps — no fluff, just code that works.

Why Add a Custom Discount Programmatically?

Magento’s built-in cart price rules work well for most basic promotions. But what if your discount logic goes beyond the default options?

Here’s where programmatic discounts shine — they let you define custom logic for applying discounts dynamically at checkout. This gives you flexibility to tailor promotions to your business strategy.

Common Use Cases:

  • Apply discounts based on payment method: E.g., $10 off for orders paid via bank transfer.
  • Target specific customer groups: Give exclusive discounts to B2B users or wholesale customers.
  • Offer product-specific or shipping-based discounts: Reduce the total when certain SKUs or shipping methods are selected.
  • Boost high-value cart conversions: Apply a discount only when the cart value exceeds a certain threshold.
  • Run advanced promotional logic: Integrate with custom modules or third-party services to apply real-time incentives.

By implementing your discount logic in code, you gain full control over when and how the discount appears — no compromises.

How to Add a Custom Discount Programmatically in Magento 2?

In order to add a custom discount programmatically in your Magento 2 store, you need to implement the below-mentioned steps to configure a custom discount in your store.

Step 1. Add Custom Total in sales.xml

First of all, you need to enter a total in the sale.xml file inside app/code/MageDelight/HelloWorld/etc/ folder and copy the following code.

<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="customer_discount" instance="MageDelight\HelloWorld\Model\Total\Quote\Custom" sort_order="420"/>

   </group>

 </section>

</config>


Step 2. Create Discount Logic in Custom.php Model

After that, we need to decide and insert the value of the custom discount in the Custom.php model file inside the app/code/MageDelight/HelloWorld/Model/Total/Quote/ folder and copy the following code.

<?php

namespace MageDelight\HelloWorld\Model\Total\Quote;

/**

* Class Custom

* @package MageDelight\HelloWorld\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);

           $quote->setCustomDiscount(-$discount);

       return $this;

   }

}


Step 3. Add Custom Discount to Cart Layout

Once you implement the above two steps, the grand total in your store will be changed with the updated price. However, your customers will not be able to see any information about the discount.

For that, we need to execute a command to add the total in the checkout_cart_index.xml layout file inside app/code/MageDelight/HelloWorld/view/frontend/layout/ folder and copy the following 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>

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

                                   <item name="component"  xsi:type="string">MageDelight_HelloWorld/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>

                                   </item>

                               </item>

                           </item>

                       </item>

                   </item>

               </argument>

           </arguments>

       </referenceBlock>

   </body>

</page>


Step 4. Display Custom Discount with customdiscount.js

Lastly, we need to display the total by calling the model knockout customdiscount.js file inside app/code/MageDelight/HelloWorld/view/frontend/web/js/view/checkout/summary/ folder and copy the following code.

define(

   [

       'jquery',

       'Magento_Checkout/js/view/summary/abstract-total'

   ],

   function ($,Component) {

       "use strict";

       return Component.extend({

           defaults: {

               template: 'MageDelight_HelloWorld/checkout/summary/customdiscount'

           },

           isDisplayedCustomdiscount : function(){

               return true;

           },

           getCustomDiscount : function(){

               return '$10';

           }

       });

   }

);


Step 5. Create HTML Template for Custom Discount

Finally, we also need to get the total discount in the customdiscount.html template knockout file inside app/code/MageDelight/HelloWorld/view/frontend/web/template/checkout/summary/ folder and add the following code.

<!-- 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>

   </td>

</tr>

<!-- /ko →

And that’s it!

Wrapping Up…

That’s it! Once all steps are implemented, your Magento 2 store will:

✅ Apply a custom discount directly to the cart total
✅ Display the discount clearly in the cart summary
✅ Let you tailor discounts to your own business logic

This approach is especially useful when you're running advanced promotions that default cart price rules can’t handle.

And if you need our professional assistance with Magento eCommerce Agency, feel free to reach out to us.

Recommended: Magento 2 Price Per Customer to offer Custom Price to Customers

Also, you can refer this Magento 2 Price Per Customer Extension's FAQ Page for most common question and it’s answers.

Price Per Customer Magento 2