How to Programmatically Add Custom Discount in Magento 2
Sometimes E-commerce businesses go through the period when the sales go down than the regular season. In this time to increase sales, bring new customers and retain the old ones, store owners implement sales promotion techniques and offering discounts is one of them. Discount offers are the short term tactics to boost your sale. Customers are generally attracted to the sale and it benefits your stores!
Being a Magento 2 store owner, you may need this strategy to implement in your store. Rather than simply applying discount percentage, you may require to Programmatically Add custom discounts in Magento 2 as a part of the marketing strategies and increase the sale. In order to do so, you need to cut down the price of the product that customers need to pay. Likewise if you are using multiple payment option and want to redirect your customers to one particular payment method then give discount in Magento 2 payment methods and encourage them. The technical work to implement this strategy is important and I have tried to prepare an easy step by step guide here.
Steps to Programmatically Add Custom Discount in Magento 2:
- Register a total in the file sale.xml located at app/code/Meetanshi/HelloWorld/etc/sales.xml
1 2 3 4 5 6 7 |
<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="Meetanshi\HelloWorld\Model\Total\Quote\Custom" sort_order="420"/> </group> </section> </config> |
- Add discount to change the total in the model at app/code/Meetanshi/HelloWorld/Model/Total/Quote/Custom.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php namespace Meetanshi\HelloWorld\Model\Total\Quote; /** * Class Custom * @package Meetanshi\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 = 5; $discount = $this->_priceCurrency->convert($baseDiscount); $total->addTotalAmount('customdiscount', -$discount); $total->addBaseTotalAmount('customdiscount', -$baseDiscount); $total->setBaseGrandTotal($total->getBaseGrandTotal() - $baseDiscount); $quote->setCustomDiscount(-$discount); return $this; } } |
- Add the total in the Layout file resided at app/code/Meetanshi/HelloWorld/view/frontend/layout/checkout_cart_index.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<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">Meetanshi_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> |
- View Model KnockOut, app/code/Meetanshi/HelloWorld/view/frontend/web/js/view/checkout/summary/customdiscount.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
define( [ 'jquery', 'Magento_Checkout/js/view/summary/abstract-total' ], function ($,Component) { "use strict"; return Component.extend({ defaults: { template: 'Meetanshi_HelloWorld/checkout/summary/customdiscount' }, isDisplayedCustomdiscount : function(){ return true; }, getCustomDiscount : function(){ return '$10'; } }); } ); |
summary/customdiscount.html
1 2 3 4 5 6 7 8 |
<!-- 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 --> |
Offering custom discounts in your Magento 2 store is always a good idea to boost sales. Try the code now and let me know how this strategy helped you to boost store sales. And if discount based on payment method not showing in Magento 2 cart total solve it and have better user experience.
Also Read: How to Setup Buy X Get Y Free in Magento 2
Hopefully, you are now familiar with programmatically adding custom discount in Magento 2. I am really eager to get your feedback and suggestions. If you need help with any errors in the implementation, let me know in the Comments section below.
Magento 2 Coupon Code Link extension makes it easy to apply coupon code using a link instead of manually typing the code.
Sanjay Jethva
Sanjay is the co-founder and CTO of Meetanshi with hands-on expertise with Magento since 2011. He specializes in complex development, integrations, extensions, and customizations. Sanjay is one the top 50 contributor to the Magento community and is recognized by Adobe.
His passion for Magento 2 and Shopify solutions has made him a trusted source for businesses seeking to optimize their online stores. He loves sharing technical solutions related to Magento 2 & Shopify.
12 Comments
does not appear in the admin panel. Can you please me on this asap.
This solution is only for frontend.
For admin side display you need to code in sales_order_view.xml.
it doesn’t work for invoices.
does not appear in the admin panel.
on all sites, the same code is not clear who stole it and from whom
Hello Stas,
The above code is for the frontend checkout page not for the invoice.
You’ll need to apply the modification in the .xml file of the invoice view.
Thank You
Hi. How to turn this into API?
Hello,
It works automatically when you call the collect total from the API.
Thank you
Hi,
Can we show the custom discount in admin side order,invoice,shipment and credit memos and email notifications also?
Hello Ram, you need to implement custom code for your requirements.
Hi,
What should I write instead of $10 because you have passed hard coded value to Cart Discount section. Please reply me asap.
Thahnk
Hello Mohit,
You can change the code as per your requirements and dynamically pass the value.
Thanks.
Thanks for reply Sanjay, but I want to get the discount value with correct pricing format from discount defined in Collect function. Can you please me on this asap.
Hey Mohit,
You can get the discount amount from the quote table after applying a discount.
Thank you.