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. 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 8 |
<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 41 |
<?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; } } |
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.
- 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 24 25 |
<?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">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 21 22 |
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'; } }); } ); |
the total discount will be shown in the template knockout, app/code/Meetanshi/HelloWorld/view/frontend/web/template/checkout/summary/customdiscount.html
1 2 3 4 5 6 7 8 9 10 |
<!-- 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 --> |
The result will be seen as below with the name and the value of the custom discount when you complete the above steps successfully!
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.
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.