Magento 2 – How to Programmatically Disable a Payment Method at Checkout

checkoutmagento2payment-methods

I want to disable a specific payment method on the checkout page based on some criteria.

I use the "get_shipping_info" event in the di.xml and make in the
"afterSaveAddressInformation" function a customer check and want to disable some payment methods based on the check result.

I have no idea how I can disable a specific payment method.

I tried it with:

\Magento\Framework\App\Config\ScopeConfigInterface $this->payment

$payment_methods = $this->payment->getValue("payment");
    foreach ($payment_methods as $method) {
        if($method['code'] == "checkmo")
        $method->setData("is_available", false);
    }

But with this I get only an array with all available payment methods.

Best Answer

/app/code/Company/Module/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="custom_payment" instance="Company\Module\Observer\PaymentMethodAvailable" />
    </event>
</config>

app/code/Company/Module/Observer/PaymentMethodAvailable.php

<?php

namespace Company\Module\Observer;

use Magento\Framework\Event\ObserverInterface;


class PaymentMethodAvailable implements ObserverInterface
{
    /**
     * payment_method_is_active event handler.
     *
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // you can replace "checkmo" with your required payment method code
        if($observer->getEvent()->getMethodInstance()->getCode()=="checkmo"){
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false); //this is disabling the payment method at checkout page
        }
    }
}

Note: After did the modifications use di:compile command and remove cache and page cache and check the same in the frontend.