You can write a plugin:
Vendor/Module/etc/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Plugins -->
<type name="Magento\Paypal\Model\Express">
<plugin name="disable_paypal_express"
type="Vendor\Module\Plugin\DisablePayPalExpress"
sortOrder="10"
disabled="false"/>
</type>
</config>
Vendor/Module/Plugin/DisablePayPalExpress.php
<?php
namespace Vendor\Module\Plugin;
class DisablePayPalExpress
{
/**
* @var \Magento\Checkout\Model\Session|\Magento\Backend\Model\Session\Quote
*/
protected $session;
/** List of the skus for which this method should be disabled */
protected $disabledForSku = [
'commission-product',
'another-sku',
'Gloves'
];
/**
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Magento\Backend\Model\Session\Quote $backendQuoteSession
* @param \Magento\Framework\App\State $state
*/
public function __construct(
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Backend\Model\Session\Quote $backendQuoteSession,
\Magento\Framework\App\State $state
) {
if ($state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
$this->session = $backendQuoteSession;
} else {
$this->session = $checkoutSession;
}
}
/**
* @param \Magento\Paypal\Model\Express $subject
* @param $result
* @return bool
*/
public function afterIsAvailable(
\Magento\Paypal\Model\Express $subject,
$result
) {
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $this->session->getQuote();
/** @var \Magento\Quote\Model\Quote\Item[] $quoteItems */
$quoteItems = $quote->getAllItems();
foreach ($quoteItems as $quoteItem) {
if (in_array($quoteItem->getSku(), $this->disabledForSku)) {
return false; // disable the method if we found product with specified sku
}
}
return $result; // return default result
}
}
If you return false, method should be always disabled. If you need a custom validation, just add it in the methods body and use a desired result.