Question

I've followed the guide on the selected answer here: Payment method only admin Magento 2?

But still no luck.

What I want is to be able to show the Cash On Delivery method only to certain customers. The guide above does not remove the payment method.

Thanks all!

Was it helpful?

Solution

We will describe a simple solution based on the Payment Restriction module, where MageWorx – a vendor name and Payment Restriction – a module name.

  1. First, you need to create a directory for the module:

    app/code/MageWorx/PaymentRestriction

  2. Then, add a registration file:

    app/code/MageWorx/PaymentRestriction/registration.php

    <?php
    /**
     * Copyright © 2016 MageWorx. All rights reserved.
     * See LICENSE.txt for license details.
     */
    
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'MageWorx_PaymentRestriction',
        __DIR__
    );
    
  3. A Composer file (if you decide to transfer the module with the ability to install it using the Composer):

    app/code/MageWorx/PaymentRestriction/composer.json

    {
        "name": "mageworx/module-paymentrestriction",
        "description": "N/A",
        "require": {
            "php": "~5.6.0|~7.0.0"
        },
        "type": "magento2-module",
        "version": "1.0.0",
        "license": [
            "OSL-3.0",
            "AFL-3.0"
        ],
        "autoload": {
            "files": [
                "registration.php"
            ],
            "psr-4": {
                "MageWorx\\PaymentRestriction\\": ""
            }
        }
    }
    
  4. A file with the module declaration:

    app/code/MageWorx/PaymentRestriction/etc/module.xml

    <?xml version="1.0"?>
    <!--
    /**
     * Copyright © 2016 MageWorx. All rights reserved.
     * See LICENSE.txt for license details.
     */
    -->
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="MageWorx_PaymentRestriction" setup_version="1.0.0">
        </module>
    </config>
    
  5. Then, we need to create a di.xml file in a common area (this won't work on the Frontend) and declare our plugin in it:

    app/code/MageWorx/PaymentRestriction/etc/di.xml

    <?xml version="1.0"?>
    <!--
    /**
     * Copyright © 2016 MageWorx. All rights reserved.
     * See LICENSE.txt for license details.
     */
    -->
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="Magento\OfflinePayments\Model\Cashondelivery">
            <plugin sortOrder="1" name="restrictByCustomer"
                    type="MageWorx\PaymentRestriction\Plugin\Payment\Method\CashOnDelivery\Available"/>
        </type>
    </config>
    
  6. Now, the last and main file with the plugin class that is responsible for the check:

    app/code/MageWorx/PaymentRestriction/Plugin/Payment/Method/CashOnDelivery/Available.php

    <?php
    /**
     * Copyright © 2016 MageWorx. All rights reserved.
     * See LICENSE.txt for license details.
     */
    
    namespace MageWorx\PaymentRestriction\Plugin\Payment\Method\CashOnDelivery;
    
    use Magento\Customer\Model\Session as CustomerSession;
    use Magento\Backend\Model\Auth\Session as BackendSession;
    use Magento\OfflinePayments\Model\Cashondelivery;
    
    class Available
    {
    
        /**
         * @var CustomerSession
         */
        protected $customerSession;
    
        /**
         * @var BackendSession
         */
        protected $backendSession;
    
        /**
         * @param CustomerSession $customerSession
         * @param BackendSession $backendSession
         */
        public function __construct(
            CustomerSession $customerSession,
            BackendSession $backendSession
        ) {
            $this->customerSession = $customerSession;
            $this->backendSession = $backendSession;
        }
    
        /**
         *
         * @param Cashondelivery $subject
         * @param $result
         * @return bool
         * @throws \Magento\Framework\Exception\LocalizedException
         */
        public function afterIsAvailable(Cashondelivery $subject, $result)
        {
            // Do not remove payment method for admin
            if ($this->backendSession->isLoggedIn()) {
                return $result;
            }
    
            $isLogged = $this->customerSession->isLoggedIn();
            if (!$isLogged) {
                return false;
            }
    
            return $result;
        }
    }
    

For unknown reasons, if you create this plugin only for the frontend, the payment method will be displayed on the checkout page. However, if you try to use it, it will result in an error and return to the checkout. That makes it necessary to validate not only the customer's session but also the admin session. If the admin is logged in, we should not change anything and return the original result.

Also, you can add an additional check on the frontend. For example, you can create a simple module that allows to segment the payment methods according to customer groups. Moreover, you can disable certain payment methods not only for the selected countries (the default option) but also for streets, phone numbers or any other data.

Here is the check:

  1. The Cash on Delivery method is hidden for the not logged in customer:

    The Cash on Delivery method is hidden

  2. The same for the logged in customer:

    enter image description here

  3. Visible:

    enter image description here

  4. Always visible for a store admin:

    enter image description here

Note:

  1. We recommend you to do the same actions in a separate module to have the ability to disable it.

  2. You have to change a vendor and module name to your own.

  3. This solution was created and tested on Magento 2.1.

OTHER TIPS

Solution for the PayPal Express Checkout method if you want to hide it when product with specified sku was found in cart:

Create 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
    }
}

Where inside $disabledForSku we store sku for which method sholud be disabled (unavailable). If you need a custom validation, just add it in the methods body and use a desired result.

PS: I post my answer here because question about PayPal Express Checkout was marked as duplicate of this question and may be removed.

Step 1: Create a custom extension or theme and override customer layout file Step 2: Use a tag to remove any extra link from my account Step 3: Clear cache and check the My Account page Step 1: Create a custom extension or theme and override customer layout file Create an extension and override the layout XML file app/design/frontend/[Namespace]/[Theme]/Magento_Customer/layout/customer_account.xml

Step 2: Use a tag to remove any extra link from my account Just need to use a tag to remove extra links from my account.

Step 3: Clear cache and check the My Account page

The link which we have removed using tag remove=”true” will no longer be displayed on your “my account page”.

This is all to remove unwanted links from customer account navigation. Though it’s a quite simple practice to follow if you stuck anywhere in between reach us freely by leaving the comment below. We’ll be glad to entertain your queries.

Cheers!

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