4

How to disable payment method

Check / Money Order

only on frontend, but left available for admin on backend ?

I can't find solution for M2

2
  • override payment method by custom module.
    – BornCoder
    Jan 23, 2017 at 9:00
  • <can_use_checkout>0</can_use_checkout> in your payment config.xml file
    – joni jones
    Jan 23, 2017 at 11:55

3 Answers 3

5

Best idea to use event/observer concept.Fire an observer on event: payment_method_is_active

Create events.xml at app\code\[Vendorname]\[Modulename]\etc\

<?xml version="1.0"?>
<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="disable_pg" instance="[Vendorname]\[Modulename]\Observer\ObserverforDisabledFrontendPg" />
    </event>
</config>

then at observer class ObserverforDisabledFrontendPg.php rewrite below code:

<?php
namespace [Vendorname]\[Modulename]\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class ObserverforDisabledFrontendPg implements ObserverInterface
{
    protected $_appState;
    public function __construct(
        \Magento\Framework\App\State $appState
    ) {
        $this->_appState = $appState;
    }

    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
      $result = $observer->getEvent()->getResult();
      $method_instance = $observer->getEvent()->getMethodInstance();
      $quote = $observer->getEvent()->getQuote();

      if(null !== $quote){
          /* 
          *  During Checkout magento call payment methods from both
          *   area frontend and Web_api are
          */

          if($method_instance->getCode() =='checkmo' && 
            in_array($this->_appState->getAreaCode(), $this->getDisableAreas()))
            {
               $result->setData('is_available',false);
               //$items= $quote->getAllVisibleItems();    
          }
      }

    }      

    protected function getDisableAreas(){

        return array( \Magento\Framework\App\Area::AREA_FRONTEND, \Magento\Framework\App\Area::AREA_WEBAPI_REST);
    }


}
1
  • A small change $result->setData('is_available',false); Sep 15, 2017 at 12:05
2

I tried to implement this simple solution, but it hides method both in backend and frontend, so I modify plugin this way (added check for current area):

class Available
{
    private $app_state;

    public function __construct(\Magento\Framework\App\State $app_state){
        $this->app_state = $app_state;
    }

    public function afterIsAvailable(\Magento\Payment\Model\Method\AbstractMethod $subject, $result)
    {
        $area_code  = $this->app_state->getAreaCode();
        if($area_code != \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE){
            if($subject->getCode() == 'checkmo') {
                return false;
            }
        }
        return $result;
    }
}
0
0

The best solution to disable the payment method at the front end is the Plugin.

Create di.xml file in you custom module

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\OfflinePayments\Model\Checkmo">
        <plugin sortOrder="1" name="restrictByCustomer1"                type="{Namespace}\{Modulename}\Plugin\Payment\Method\Checkmo\Available"/>
    </type>
</config>

create plugin file in your module app/code/{Namespace}/{Modulename}/Plugin/Payment/Method/Checkmo/Available.php add below code into the plugin file

<?php
/**
 * Copyright © 2016 MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */

namespace {Namespace}\{Modulename}\Plugin\Payment\Method\Checkmo;
use Magento\Customer\Model\Session as CustomerSession;
use Magento\Backend\Model\Auth\Session as BackendSession;
use Magento\OfflinePayments\Model\Checkmo;

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(Checkmo $subject, $result)
    {
        // Do not remove payment method for admin
        if ($this->backendSession->isLoggedIn()) {
            return $result;
        } else {
            return false;
        }
        // Hide payment method from front-end only
        /*$isLogged = $this->customerSession->isLoggedIn();
        if (!$isLogged) {
            return false;
        }*/

    }
}
1
  • Not a good option. What if customer is not login and does checkout ??
    – Avesh Naik
    Jul 26, 2019 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.