Magento2 | PWA | GraphQL

Magento2 Disable Specific Payment Methods On Checkout Page When Cart Have At Least One Product From Specific Category


In this post, we will check how to disable specific payment methods on checkout page when cart have at least one product from specific category.

Before that cashondelivery payment method will display on checkout:


After installing module cashondelivery payment method will not display on checkout:


You can find complete module on Github.

Create folder inside app/code/Magelearn/RestrictPayment

Add registration.php file in it:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Magelearn_RestrictPayment',
    __DIR__
);
Add composer.json file in it:
{
    "name": "magelearn/module-restrictpayment",
    "description": "Disable specific payment methods on checkout page when cart have at least one product from specific category.",
    "type": "magento2-module",
    "license": "OSL-3.0",
    "authors": [
        {
            "email": "info@mage2gen.com",
            "name": "Mage2Gen"
        },
        {
            "email": "vijaymrami@gmail.com",
            "name": "vijay rami"
        }
    ],
    "minimum-stability": "dev",
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\RestrictPayment\\": ""
        }
    }
}
Add etc/module.xml file in it:
<?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="Magelearn_RestrictPayment" setup_version="0.0.1"/>
</config>
Now we will give the admin system configuration option to select category from admin store configurations.

Create file at app/code/Magelearn/RestrictPayment/etc/adminhtml/system.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="magelearn" translate="label" sortOrder="10">
            <label>Magelearn</label>
        </tab>
        <section id="magelearn_restrictPayment" translate="label" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Restrict Category for Payment</label>
            <tab>magelearn</tab>
            <resource>Magelearn_RestrictPayment::config_restrictPayment</resource>
            <group id="categoryselection_setting" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Settings</label>
                    <field id="categorylist" translate="label" type="select" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                        <label>Please Select Category</label>
                        <source_model>Magelearn\RestrictPayment\Model\Config\Source\Categorylist</source_model>
                    </field>
            </group>
        </section>
    </system>
</config>
Create file at etc/acl.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magento_Backend::stores">
                    <resource id="Magento_Backend::stores_settings">
                        <resource id="Magento_Config::config">
                            <resource id="Magelearn_RestrictPayment::config_restrictPayment" title="Restrict Category for Payment Settings" />
                        </resource>
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>
Now as per highlighted in system.xml file, we will add our source model file at:
Model/Config/Source/Categorylist.php
<?php
namespace Magelearn\RestrictPayment\Model\Config\Source;
  
use Magento\Framework\Option\ArrayInterface;
  
class Categorylist implements ArrayInterface
{
    protected $_categoryHelper;
  
    public function __construct(\Magento\Catalog\Helper\Category $catalogCategory)
    {
        $this->_categoryHelper = $catalogCategory;
    }
     
    /**
     * Retrieve current store level 2 category
     *
     * @param bool|string $sorted (if true display collection sorted as name otherwise sorted as based on id asc)
     * @param bool $asCollection (if true display all category otherwise display second level category menu visible category for current store)
     * @param bool $toLoad
     */
    public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true)
    {
        return $this->_categoryHelper->getStoreCategories($sorted , $asCollection, $toLoad);
    }
  
    public function toOptionArray()
    {
  
        $arr = $this->toArray();
        $ret = [];
  
        foreach ($arr as $key => $value)
        {
  
            $ret[] = [
                'value' => $key,
                'label' => $value
            ];
        }
  
        return $ret;
    }
  
    public function toArray()
    {
  
        $categories = $this->getStoreCategories(true,true,true);
  
        $catagoryList = array();
        foreach ($categories as $category){
            $catagoryList[$category->getEntityId()] = __($category->getName());
        }
  
        return $catagoryList;
    }
  
}

Now to disable specific payment method, we will use magento's 'payment_method_is_active' event.

Create app/code/Magelearn/RestrictPayment/etc/events.xml file:
<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="Magelearn\RestrictPayment\Observer\Payment\MethodIsActive" />
    </event>
</config>

Create Obseerver file app/code/Magelearn/RestrictPayment/Observer/Payment/MethodIsActive.php

<?php


namespace Magelearn\RestrictPayment\Observer\Payment;

use Magento\Checkout\Model\Cart;
use Magento\Checkout\Model\Session;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magelearn\RestrictPayment\Helper\Data as DataHelper;

class MethodIsActive implements ObserverInterface
{

    protected $_cart;
    protected $_checkoutSession;
    protected $productRepository;
    protected $dataHelper;

    public function __construct(
        Cart $cart,
        Session $checkoutSession,
        ProductRepositoryInterface $productRepository,
        DataHelper $dataHelper
    )
    {
        $this->_cart = $cart;
        $this->_checkoutSession = $checkoutSession;
        $this->productRepository = $productRepository;
        $this->dataHelper = $dataHelper;
    }

    /**
     * Execute observer
     *
     * @param Observer $observer
     * @return void
     * @throws LocalizedException
     * @throws NoSuchEntityException
     */
    public function execute(Observer $observer)
    {
        $quote = $this->getCheckoutSession()->getQuote();
        $categoryID = $this->getCategoryId(); //Add your category ID to disable specific payment method on its products
        $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 "cashondelivery" with your required payment method code to disable it
        if($flag == true && $observer->getEvent()->getMethodInstance()->getCode()=="cashondelivery"){
            $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;
    }
    
    /**
     * Get category ID
     *
     * @return integer|null
     * @throws NoSuchEntityException
     */
    public function getCategoryId()
    {
        $categoryId = $this->dataHelper->getConfig('magelearn_restrictPayment/categoryselection_setting/categorylist');
        return $categoryId;
    }
}

At last create our Data Helper file at app/code/Magelearn/RestrictPayment/Helper/Data.php

<?php
 
namespace Magelearn\RestrictPayment\Helper;
 
use Magento\Framework\App\Helper\AbstractHelper;
 
class Data extends AbstractHelper
{
    /**
     * Get scope config
     *
     * @param $path
     * @return mixed
     */
    public function getConfig($path)
    {
        return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    }
}

After adding above files, just run Magento commands:

php bin/magento set:upg

php bin/magento set:d:c

php bin/magento set:s:d en_US

php bin/magento c:c

php bin/magento c:f

Now, when you add any product frm category ID 52 at that time cashondelivery payment method (if active) will not display.

0 Comments On "Magento2 Disable Specific Payment Methods On Checkout Page When Cart Have At Least One Product From Specific Category"

Back To Top