Magento 2 Discount – Fix Discount Depend on Payment Method Not Working

discountmagento2

I go to Magento 2 Admin > Marketing > Promotions > Cart Price Rules and create a new Rule: Bank Transfer Payment:

Tab Rule Information:

  • Rule Name: Bank Transfer Payment
  • Status: Active
  • Websites: Main Website
  • Customer Groups: select all
  • Coupon: No Coupon
  • Uses per Customer: 0
  • From: blank
  • To: blank
  • Priority: 0
  • Public in RSS Feed: No

Conditions tab:

  • If ALL of these conditions are TRUE :
    • Payment Method is Bank Transfer Payment

Actions Tab:

  • Apply: percent of product price discount
  • Discount Amount: 2
  • Maximum Qty Discount is Applied To: 0
  • Discount Qty Step (Buy X): 0
  • Apply to Shipping Amount: No
  • Discard subsequent rules: No
  • Free Shipping: No
  • Apply the rule only to cart items matching the following conditions (leave blank for all items): nothing

Then I enable Bank Transfer Payment method, go to checkout page, click on Bank Transfer Payment but the Discount Percent Price does not show up in Order Summary.

enter image description here

Please give me an advice. How can make a discount on payment method on Magento 2. For Magento 1, it wroks well.

Thanks very much

Best Answer

This rule doesn't work because Magento 2 doesn't save payment method to quote when you select one. And it also doesn't reload totals when selecting a payment method. And unfortunately, you have to write a custom module to solve the issue.

The new module needs only 4 files to be created:

  1. app/code/Namespace/ModuleName/etc/frontend/routes.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="standard">
            <route id="namespace_modulename" frontName="namespace_modulename">
                <module name="Namespace_ModuleName"/>
            </route>
        </router>
    </config>
    

    This will define a new controller for our module.

  2. app/code/Namespace/ModuleName/Controller/Checkout/ApplyPaymentMethod.php

    <?php
    
    namespace Namespace\ModuleName\Controller\Checkout;
    
    class ApplyPaymentMethod extends \Magento\Framework\App\Action\Action
    {
        /**
         * @var \Magento\Framework\Controller\Result\ForwardFactory
         */
        protected $resultForwardFactory;
    
        /**
         * @var \Magento\Framework\View\LayoutFactory
         */
        protected $layoutFactory;
    
        /**
         * @var \Magento\Checkout\Model\Cart
         */
        protected $cart;
    
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\LayoutFactory $layoutFactory
         * @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory,
            \Magento\Framework\View\LayoutFactory $layoutFactory,
            \Magento\Checkout\Model\Cart $cart
        ) {
            $this->resultForwardFactory = $resultForwardFactory;
            $this->layoutFactory = $layoutFactory;
            $this->cart = $cart;
    
            parent::__construct($context);
        }
    
        /**
         * @return \Magento\Framework\Controller\ResultInterface
         */
        public function execute()
        {
            $pMethod = $this->getRequest()->getParam('payment_method');
    
            $quote = $this->cart->getQuote();
    
            $quote->getPayment()->setMethod($pMethod['method']);
    
            $quote->setTotalsCollectedFlag(false);
            $quote->collectTotals();
            $quote->save();
        }
    }
    

    This file creates controller action to save the selected payment method to quote

  3. app/code/Namespace/ModuleName/view/frontend/requirejs-config.js

    var config = {
        map: {
            '*': {
                'Magento_Checkout/js/action/select-payment-method':
                    'Namespace_ModuleName/js/action/select-payment-method'
            }
        }
    };
    

    This file allows to override Magento_Checkout/js/action/select-payment-method file

  4. app/code/Namespace/ModuleName/view/frontend/web/js/action/select-payment-method.js

    define(
        [
            'Magento_Checkout/js/model/quote',
            'Magento_Checkout/js/model/full-screen-loader',
            'jquery',
            'Magento_Checkout/js/action/get-totals',
        ],
        function (quote, fullScreenLoader, jQuery, getTotalsAction) {
            'use strict';
            return function (paymentMethod) {
                quote.paymentMethod(paymentMethod);
    
                fullScreenLoader.startLoader();
    
                jQuery.ajax('/namespace_modulename/checkout/applyPaymentMethod', {
                    data: {payment_method: paymentMethod},
                    complete: function () {
                        getTotalsAction([]);
                        fullScreenLoader.stopLoader();
                    }
                });
    
            }
        }
    );
    

    Sends ajax request to save payment method and reload cart totals.

P.S. Parts of the code were taken from Payment Fee extension for Magento 2.

Related Topic