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 [] []

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>
| improve this answer | |
  • Its Perfect. After that, I made some modification in the DisablePaymentMethods.php to get the desired result. – Apoorv Gupta Sep 5 '19 at 6:55
  • If answer help you mark as solution and upvote. So it help other into community as well. – Dhiren Vasoya Sep 5 '19 at 7:10
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); 
                    }
                }

            }
        }
    }
}
| improve this answer | |
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}

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.