Magento – Magento 2 – enable cash on delivery only for specific shipment method

magento2payment-methodsshipping-methods

How to, for example, enable cash on delivery payment only when customer selected flat rate shipping method?

I cannot find a way doing this in shipment/payment configuration or in cart rules.

Best Answer

I use an plugin in a custom module to set the isAvailable() function for Magento\OfflinePayments\Model\Cashondelivery to false when shipping method flatrate_flatrate is selected.

file: <magento-root>/app/code/MyCompany/MyModule/Plugin/CashondeliveryPlug.php

<?php
namespace MyCompany\MyModule\Plugin;
use Magento\Payment\Model\Method\AbstractMethod;
use Magento\Quote\Model\Quote;

class CashondeliveryPlug
{
  /**
   * @var \Magento\Checkout\Model\Session
   */
   protected $_checkoutSession;

  /**
   * Constructor
   *
   * @param \Magento\Checkout\Model\Session $checkoutSession
   */
    public function __construct(
        \Psr\Log\LoggerInterface $logger,
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->logger = $logger;
        $this->_checkoutSession = $checkoutSession;
    }

    public function aroundIsAvailable(
      \Magento\Payment\Model\Method\AbstractMethod $subject, callable $proceed)
    {
        $shippingMethod = $this->_checkoutSession->getQuote()->getShippingAddress()->getShippingMethod();
        // $this->logger->debug($shippingMethod);

        if ($shippingMethod == 'flatrate_flatrate')
            return false;

        return $proceed();
    }
}

file: <magento-root>/app/code/MyCompany/MyModule/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\OfflinePayments\Model\Cashondelivery">
        <plugin name="cashondeliveryplug" 
            type="MyCompany\MyModule\Plugin\CashondeliveryPlug"
            disabled="false" sortOrder="10"/>
    </type>
</config>

Hope this helps you! Feel free to ask any questions.

Related Topic