Question

I want to Restrict payment methods by attribute or category ? I am using Magento 2.4.0.

if someone have idea or solution please share with me, I am stuck in this issue.

Thanks

Was it helpful?

Solution

There are a number of places you could write a plugin to do this, luckily however if you take a look at \Magento\Payment\Model\MethodList the constructor has an $additionalChecks argument allowing you to pass in additional custom checks to restrict specific payment methods. 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">

    <!-- Specify a custom check where `your_custom_restriction` is a unique value -->
    <type name="Magento\Payment\Model\MethodList">
        <arguments>
            <argument name="additionalChecks" xsi:type="array">
                <item name="your_custom_restriction" xsi:type="string">your_custom_restriction</item>
            </argument>
        </arguments>
    </type>

    <!-- Here we specify the class responsible for handling the check specified in the previous block -->
    <type name="Magento\Payment\Model\Checks\SpecificationFactory">
        <arguments>
            <argument name="mapping" xsi:type="array">
                <item name="your_custom_restriction" xsi:type="object">StackExchange\PaymentRestriction\Model\YourCustomRestriction</item>
            </argument>
        </arguments>
    </type>
</config>

In etc/catalog_attributes.xml we also need to tell Magento to load our custom attribute value in the product object when we call getProduct() on the quote item.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="disable_some_method"/>
    </group>
</config>

Our class Model/YourCustomRestriction.php will make the decision to include/exclude the payment method. Our isApplicable() method should return true or false if we want to allow or block the payment method. In my example below I first check if the payment is braintree (if not we immediately return true). If it is, we iterate over all items in the cart and if one of the items has the attribute disable_some_method set to yes we break from the loop, return true, which in turn returns false preventing the payment method from being used.

<?php
declare(strict_types=1);

namespace StackExchange\PaymentRestriction\Model;

use Magento\Payment\Model\Checks\SpecificationInterface;
use Magento\Payment\Model\MethodInterface;
use Magento\Quote\Model\Quote;
use PayPal\Braintree\Model\Ui\ConfigProvider;

class YourCustomRestriction implements SpecificationInterface
{
    /**
     * @param MethodInterface $paymentMethod
     * @param Quote $quote
     * @return bool
     */
    public function isApplicable(MethodInterface $paymentMethod, Quote $quote)
    {
        if ($paymentMethod->getCode() === ConfigProvider::CODE && $this->hasRestrictedItems($quote)) {
            return false;
        }
        return true;
    }

    /**
     * @param Quote $quote
     * @return bool
     */
    private function hasRestrictedItems(Quote $quote)
    {
        $hasRestrictedItems = false;
        /** @var \Magento\Quote\Api\Data\CartItemInterface $item */
        foreach ($quote->getAllItems() as $item) {
            if ($item->getProduct()->getDisableSomeMethod()) {
                $hasRestrictedItems = true;
                break;
            }
        }
        return $hasRestrictedItems;
    }
}

OTHER TIPS

you can follow belog blog that will helpful for you

https://meetanshi.com/blog/disable-payment-method-programmatically-in-magento-2/

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top