Magento – Magento 2: Hide payment methods depends on shipping method

magento2payment-methodsshipping-methods

I have created custom shipping method "Pick up at the store" and payment method "Pay in store" and I would like to hide all other payment methods, when I choose "Pick up at the store" shipping method.

I know, that payment method class has function "isAvailable", but it isn't a good idea to create special conditions for all available methods.

Please advice how I can hide all other payment method except "Pay in store", when "Pick up at the store" shipping method is choose. Thanks.

Best Answer

I tried DRAJAs code, but this does not work for me. The Shipping Method title is always NULL. I found another solution using the deprecated Cart Model. I also tried the new Quote model that should replace the Cart Model, but again this returned NULL... so I know it’s not according to Magento Standards, but it does do the trick for now.

The below example is used to hide the Klara payment method when a pick-up location is selected.

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> 

Company/Module/Observer/PaymentMethodAvailable.php

<?php
namespace Company\Module\Observer;

use Magento\Framework\Event\ObserverInterface;
use \Magento\Checkout\Model\Cart;


class PaymentMethodAvailable implements ObserverInterface
{

    /**
     * @var Cart
     */
    protected $cart;

    /**
     * PaymentMethodAvailable constructor.
     * @param Cart $cart
     */
    public function __construct(
        Cart $cart ){
        $this->cart = $cart;
    }

    /**
     * payment_method_is_active event handler.
     *
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $shippingMethod = $this->cart->getQuote()->getShippingAddress()->getShippingMethod();
        $paymentMethod = $observer->getEvent()->getMethodInstance()->getCode();
    
        if ($paymentMethod == "klarna_kp" && $shippingMethod == 'tablerate_pickup') {
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false);
        }
    }
}