2

I want to disable a specific payment method on the checkout page based on Product Attribute 'cod'. If it is true then COD Payment Method not visible on Checkout Page. Here is the complete code.

app\code\Vendor\DisableCOD\etc\events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="payment_method_is_active">
        <observer name="Vendor_DisableCOD_Method_Is_Active" instance="Vendor\Disable_COD\Observer\DisablePaymentMethods" />
    </event>
</config>

app\code\Vendor\DisableCOD\etc\module.xml

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_DisableCOD" setup_version="2.0.0" /></config>

app\code\Vendor\DisableCOD\Observer\DisablePaymentMethods.php

<?php
namespace Vendor\DisableCOD\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;
class DisablePaymentMethods implements ObserverInterface
{
    public function __construct(\Psr\Log\LoggerInterface $logger)
    {
        $this->_logger = $logger;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $cart = $objectManager->get('\Magento\Checkout\Model\Cart'); 

        // get cart items
        $items = $cart->getItems();

        // get custom options value of cart items
        foreach ($items as $item) 
        {
            $options = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct());
            $attribute = $options['cod'];
            if ($attribute) 
            {
                if($observer->getEvent()->getMethodInstance()->getCode()=="phoenix_cashondelivery")
                {
                    $checkResult = $observer->getEvent()->getResult();
                    $checkResult->setData('is_available', false); 
                }
            }
        }
    }
}

app\code\Vendor\DisableCOD\registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_DisableCOD',
    __DIR__
)

Error in system.log file

main.CRITICAL: Class Vendor\Disable_COD\Observer\DisablePaymentMethods does not exist [] []

3 Answers3

1

You need to change your events.xml file code. There you specify wrong Extension name.

app\code\Vendor\DisableCOD\etc\events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="payment_method_is_active">
        <observer name="Vendor_DisableCOD_Method_Is_Active" instance="Vendor\DisableCOD\Observer\DisablePaymentMethods" />
    </event>
</config>
Dhiren Vasoya
  • 9,484
  • 12
  • 33
  • 59
0

Modification in files to get the desired result

app\code\Vendor\DisableCOD\etc\events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="payment_method_is_active">
        <observer name="Vendor_DisableCOD_Method_Is_Active" instance="Vendor\DisableCOD\Observer\DisablePaymentMethods" />
    </event>
</config>

app\code\Vendor\DisableCOD\Observer\DisablePaymentMethods.php

<?php
namespace Vendor\DisableCOD\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;
class DisablePaymentMethods implements ObserverInterface
{
    public function __construct(\Psr\Log\LoggerInterface $logger)
    {
        $this->_logger = $logger;
    }
    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $cart = $objectManager->get('\Magento\Checkout\Model\Cart'); 

        // get cart items
        $items = $cart->getItems();

        // get attribute value of cart items
        foreach ($items as $item) 
        {
            $p = $objectManager->get('Magento\Catalog\Model\Product')->load($item['product_id']);
            $attribute = $p->getResource()->getAttribute('cod'); 

            if ($attribute) 
            {
                $attr_value = $attribute ->getFrontend()->getValue($p);
                if($attr_value == 'Yes' || $attr_value == 'yes' || $attr_value == 'YES')
                {
                    if($observer->getEvent()->getMethodInstance()->getCode()=="phoenix_cashondelivery")
                    {
                        $checkResult = $observer->getEvent()->getResult();
                        $checkResult->setData('is_available', false); 
                    }
                }

            }
        }
    }
}
0

Is there any way that I can add a message on checkout page, something like this

COD is not Available on Product - {Product Name}