4

I want to show payment methods for particular category products added in cart.

e.g I have paypal and COD payment methods, so when X category Item in cart then Paypal will show and other will hide, And when Y category item in the cart then COD method will show and PayPal will hide.

So how can I achieve this?
Any suggestion would be appreciated.

Thanks

5

Please try this way using payment_method_is_active event observer.

Create events.xml file with the below content.

<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="payment_method_is_active" instance="Vendor\Module\Observer\MethodIsActive" />
    </event>
</config>

And create MethodIsActive.php with the following code.

<?php
namespace Vendor\Module\Observer\Payment;
use Magento\Framework\Event\ObserverInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
class MethodIsActive implements ObserverInterface
{
    protected $_cart;
    protected $_checkoutSession;
    protected $productRepository;
    public function __construct(
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Checkout\Model\Session $checkoutSession,
        ProductRepositoryInterface $productRepository
    )
    {
        $this->_cart = $cart;
        $this->_checkoutSession = $checkoutSession;
        $this->productRepository = $productRepository;
    }
    /**
     * Execute observer
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $quote = $this->getCheckoutSession()->getQuote();
        $categoryID = 155; //Add your category ID
        $items = $quote->getAllItems();
        $flag = false;
        foreach($items as $item) {
            $product = $this->getProduct($item->getProductId());
            $categoryIds = $product->getCategoryIds();
            if(in_array($categoryID, $categoryIds)){
                $flag = true; 
                break;
            }
        }

        // you can replace "checkmo" with your required payment method code
        if($flag == false && $observer->getEvent()->getMethodInstance()->getCode()=="paypal"){
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false); 
        }
        else if($flag == true && $observer->getEvent()->getMethodInstance()->getCode()=="checkmo"){
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false); 
        }
    }
    public function getProduct($productId)
    {
        return $product = $this->productRepository->getById($productId);
    }
    public function getCart()
    {        
        return $this->_cart;
    }

    public function getCheckoutSession()
    {
        return $this->_checkoutSession;
    }
}
4

You can get it with payment_method_is_active event observer.

Create events.xml file with below content.

<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="payroll_payment_method_is_active" instance="Vendor\Module\Observer\DisablePayment" />
    </event>
</config>

And create DisablePayment.php with your condition.

namespace Vendor\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use use \Magento\Checkout\Model\Session;

class DisablePayment implements ObserverInterface
{
    protected $_session;

    private $_objectManager;

    public function __construct(
    Session $session,
    \Magento\Framework\ObjectManagerInterface $objectmanager
    ) {
        $this->_session = $session;
        $this->_objectManager = $objectmanager
    }
    /**
    * @param Observer $observer
    *
    * @return void
    */
    public function execute(Observer $observer)
    {
        $result = $observer->getEvent()->getResult();
        $method_instance = $observer->getEvent()->getMethodInstance()->getCode();
        $quote = $observer->getEvent()->getQuote();

        if($method_instance == 'your_payment_code')
        {
            if (in_array('category id to match', $this->getCategoryIds())) {
                $result = $observer->getResult();
                $result->isAvailable = false;
            }
        }
    }

    public function getCategoryIds()
    {
        /** 
        @var $item \Magento\Quote\Model\Quote\Item 
        */
        $items = $this->_session->getQuote()->getAllItems();
        $categoryIds = [];
        foreach ($items as $item){
            var_dump($item->getName());
            $productid = $item->getProductId();
            $product = $this->_objectManager->create('Magento\Catalog\Model\Product')- >load($productid);
            $categoryIds[] = $product->getCategoryIds();
            return $categoryIds;
        }          
    }
}

Hope it helps!!!

  • how can I check by category products? can you please read my question again in details ? – M2 Developer Sep 6 '19 at 9:18
  • Do you want this feature on the Checkout page? – Sumit Sep 6 '19 at 9:20
  • Yes, on checkout payment section – M2 Developer Sep 6 '19 at 9:21
  • Updated my answer, please check. – Sumit Sep 6 '19 at 9:27
  • 1
    Thanks for your answer, +1 for your effort – M2 Developer Sep 6 '19 at 9:53

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.