cancel
Showing results for 
Search instead for 
Did you mean: 

Magento 2.2 - Observer to restrict a payment method

SOLVED

Magento 2.2 - Observer to restrict a payment method

Hi, I am sort of new to Magento, especially Magento 2.. I am trying to restrict a payment method (for a specific customer group) by implementing an Observer for "payment_method_is_active" event. Nothing I try seems to do the job though.


Currently, I have stripped down the code and simply am trying to turn off Purchase Order method for everyone, but it doesn't work. Could somebody point me the errors in the code?

 

Zen/PaymentMethod/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="Zen_PaymentMethod" setup_version="2.0.0" /></config>

Zen/PaymentMethod/etc/event.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="Zen_PaymentMethod_DisablePMbyGroup" instance="Zen\PaymentMethod\Observer\DisablePMbyGroup" />
    </event>
</config>

Zen/PaymentMethod/registration.php

 

\Magento\Framework\Component\ComponentRegistrar::register(    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Zen_PaymentMethod',    __DIR__);

Zen/PaymentMethod/Observer/Observer.php

<?php
namespace Zen\PaymentMethod\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class DisablePMbyGroup implements ObserverInterface
{
protected $logger;

public function __construct(\Psr\Log\LoggerInterface $loggerInterface) {
$this->logger = $loggerInterface;
}
/**
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$result = $observer->getEvent()->getResult();
$method_instance = $observer->getEvent()->getMethodInstance();
$this->logger->debug($observer->getEvent());

if ($method_instance->getCode() == 'purchaseorder') {
  $result->setData('is_available', false);
}
}
}

 Even the logger doesn't trigger when I get the payment methods displayed..

 

 

SOLUTION: @Sunil Patel's solution with plugin does the job great. I have included the extended plugin code that restricts Payment Method according to specific customer group at the end of this thread.

 

It seems however that the solution to the problem with Observer hasn't been solved, but I feel as long as there's an alternative we can mark this solved... If anyone wants to chip in to the Observer issue, I can help with testing...

 

EDIT #2: 

Just wanted to add this here: according to Magento docs, events' data must not be modified by observers, so @Sunil Patel answer was the only way to do it and my original question about the observer was invalid..

 

14. Events

14.1. All values (including objects) passed to an event MUST NOT be modified in the event observer. ...

1 ACCEPTED SOLUTION

Accepted Solutions

Re: Magento 2.2 - Observer to restrict a payment method

Hello @Zendo

 

you can use plugin method for that

 

you need to create di.xml into 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\Payment\Model\MethodList">
		<plugin name="methodlist" type="CompnayName\ModuleName\Plugin\Model\Method\Available" sortOrder="1" />
</type> </config>

Availbale.php code

<?php

namespace CompanyName\ModuleName\Plugin\Model\Method;

class Available
{
 
    public function afterGetAvailableMethods($subject, $result)
    {
        foreach ($result as $key=>$_result) {
            if ($_result->getCode() == "purchaseorder") {
                $isAllowed =  false; // your logic here
                if (!$isAllowed) {
                    unset($result[$key]);
                }
            }
        }
        return $result;
    }
}

Hope it will help you.

 

If works then mark as solution


Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

View solution in original post

16 REPLIES 16

Re: Magento 2.2 - Observer to restrict a payment method

keep below way to get logger details,

$this->logger->debug($observer->getEvent()->debug());
If Issue Solved, Click Kudos/Accept As solutions. Get Magento insight from
Magento 2 Blogs/Tutorial

Re: Magento 2.2 - Observer to restrict a payment method

 

$this->logger->debug($observer->getEvent()->debug());

This still didn't get any details to the logs. How to know if my Observer module even gets executed properly?

 

It is enabled as a module and shows up in the list...

Re: Magento 2.2 - Observer to restrict a payment method

Yes, thanks.. As I said the module is enabled. It indeed says so in app/etc/config.php as well..

 

Do you see any other issues with the code?

 

Or could some other configuration mess with this module?

Re: Magento 2.2 - Observer to restrict a payment method

Check with below code without use of logger and check log inside var/log/mylog.log,

 public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $result          = $observer->getEvent()->getResult();
        $method_instance = $observer->getEvent()->getMethodInstance();
        
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/mylog.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info(print_r($observer->getEvent()->debug(),true));

        if ($method_instance->getCode() == 'purchaseorder') {
            $result->setData('is_available', false);
        }
    }

Just clear cache and remove var/generated folder.

If Issue Solved, Click Kudos/Accept As solutions. Get Magento insight from
Magento 2 Blogs/Tutorial

Re: Magento 2.2 - Observer to restrict a payment method

Hi @Zendo

 

I think main issue here is your observer file is not called !! 

 

Yes , its because of you have issue with your code - Name of your observer file !!

 

At on this location - Zen/PaymentMethod/Observer/Observer.php

 

You have given file name as an Observer.php but your actual class name is - DisablePMbyGroup

 

So here fileName should DisablePMbyGroup.php instead of Observer.php and that is the reason your file is not calling !!

 

 Hope it helps !!!

if issue solved,Click Kudos & Accept as Solution

Re: Magento 2.2 - Observer to restrict a payment method

Hello @Zendo

 

you can use plugin method for that

 

you need to create di.xml into 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\Payment\Model\MethodList">
		<plugin name="methodlist" type="CompnayName\ModuleName\Plugin\Model\Method\Available" sortOrder="1" />
</type> </config>

Availbale.php code

<?php

namespace CompanyName\ModuleName\Plugin\Model\Method;

class Available
{
 
    public function afterGetAvailableMethods($subject, $result)
    {
        foreach ($result as $key=>$_result) {
            if ($_result->getCode() == "purchaseorder") {
                $isAllowed =  false; // your logic here
                if (!$isAllowed) {
                    unset($result[$key]);
                }
            }
        }
        return $result;
    }
}

Hope it will help you.

 

If works then mark as solution


Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

Re: Magento 2.2 - Observer to restrict a payment method

@Manthan Dave lol thanks! I absolutely missed it!

 

I have now renamed Observer according to it's class name, and I am using the code @Rakesh Jesadiya suggested to write log into mylog file, but that still didn't work.

 

Then I went back to the version with logger and it still didn't work..

 

In between tests I run setup:upgrade, clear cache and even start a new anon session just to be sure..

 

It seems that for some reason the file is still not getting called, even though the observer has been named properly now..

Re: Magento 2.2 - Observer to restrict a payment method

Please check with below code,

<?php
namespace Zen\PaymentMethod\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class DisablePMbyGroup implements ObserverInterface
{
    protected $logger;

    public function __construct(\Psr\Log\LoggerInterface $loggerInterface) {
        $this->logger = $loggerInterface;
    }
    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $paymentMethod = $observer->getEvent()->getMethodInstance()->getCode();
        $result = $observer->getEvent()->getResult();
        $quote  = $observer->getEvent()->getQuote();
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/mylog.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info(print_r($observer->getEvent()->debug(),true));

        if (!$quote) {
            return;
        }

        if ($paymentMethod == 'purchaseorder') {
            $result->setData('is_available', false);
            return;
        }
    }
}
If Issue Solved, Click Kudos/Accept As solutions. Get Magento insight from
Magento 2 Blogs/Tutorial

Re: Magento 2.2 - Observer to restrict a payment method

@Rakesh Jesadiya I tested this code as well, absolutely no change. The log file doesn't get created and there's no effect on payment methods.

 

If we assume that the code is fine, what other issues could there be? Why isn't the observer working when the payment methods get called?

 

Does the payment_method_is_active get dispatched when on "/checkout/#payment" ?