How to restrict payment methods by Attribute or Category?
-
15-04-2021 - |
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
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/