Magento 2 : discount depend on Payment Method does not work

Today I’m going to explain why discount coupon code does not work depending on Payment Method in Magento 2.1.X version. Coupon Code 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. So you have to write a custom module to solve the issue. Here I am creating a custom module to solve this issue.

The new module needs only 4 files to be created:

1. app/code/Prashant/Custom/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="prashant_custom" frontName="prashant_custom">
            <module name="Prashant_Custom"/>
        </route>
    </router>
</config>

This will define a new controller for our module.

2. app/code/Prashant/Custom/Controller/Checkout/ApplyPaymentMethod.php

<?php

namespace Prashant\Custom\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/Prashant/Custom/view/frontend/requirejs-config.js

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

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

4. app/code/Prashant/Custom/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('/prashant_custom/checkout/applyPaymentMethod', {
                data: {payment_method: paymentMethod},
                complete: function () {
                    getTotalsAction([]);
                    fullScreenLoader.stopLoader();
                }
            });

        }
    }
);

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

That's it. Now flush magento cache and check.