3

I want to show Check/Money order Payment Method only for admin not for the website customers, how to achieve using can_use_internal. I am just trying Event observer

Event Observer:

app/code/Gta/AdminPay/etc/events.xml

<?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="payment_only_for_admin" instance="\Gta\AdminPay\Observer\PaymentMethodAvailable" />
    </event>
</config> 

app/code/Gta/AdminPay/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Gta_AdminPay" setup_version="1.0.1"></module>
</config>

app/code/Gta/AdminPay/Observer/PaymentMethodAvailable.php

<?php
namespace Gta\AdminPay\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class PaymentMethodAvailable implements ObserverInterface
{
    public function __construct(\Psr\Log\LoggerInterface $logger
     )
    {
        $this->_logger = $logger;     
    }
    
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $result          = $observer->getEvent()->getResult();
        $method_instance = $observer->getEvent()->getMethodInstance();
        $quote           = $observer->getEvent()->getQuote();
        $this->_logger->info($method_instance->getCode());

        if ($method_instance->getCode() == 'checkmo') {
            $result->setData('is_available', false);
        }
        else
        {
            $result->setData('is_available', true);
        }
    }
}

app/code/Gta/AdminPay/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Gta_AdminPay',
    __DIR__
);

Note: Hiding both frontend & backend, how to visible only on the backend?

Source : Thank you Divya Sekar

4 Answers 4

3
+50

If you intend to use the checkmo payment method I think the cleanest way is to create a preference for \Magento\OfflinePayments\Model\Checkmo and override canUseCheckout method and return false.

This way you do not have to write any observer or logic in it, it is already handled by Magento standard functionality. It is also minimal code:

app/code/StackExchange/CheckMoney/Model/Checkmo.php

<?php
declare(strict_types=1);

namespace StackExchange\CheckMoney\Model;

class Checkmo extends \Magento\OfflinePayments\Model\Checkmo
{
    public function canUseCheckout()
    {
        return false;
    }
}

app/code/StackExchange/CheckMoney/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"
>
    <preference for="Magento\OfflinePayments\Model\Checkmo"
                type="StackExchange\CheckMoney\Model\Checkmo"
    />
</config>

app/code/StackExchange/CheckMoney/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="StackExchange_CheckMoney" setup_version="0.1.0">
        <sequence>
            <module name="Magento_OfflinePayments"/>
        </sequence>
    </module>
</config>

app/code/StackExchange/CheckMoney/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'StackExchange_CheckMoney',
    __DIR__
);

The code above is tested and works fine.

4
  • Thank you for your initial explanation, and code help. I working on another task like PayPal payment only for a selected customer group. Can i get an idea to work this, i got confused about what should i go plugin or preference or event observer.
    – zus
    Oct 21, 2020 at 6:09
  • 1
    I guess plugin would be a good solution also instead of doing a preference, both will work. I am not so sure about observer, seems observers should be used in slighly different cases.
    – Kristoffer
    Oct 21, 2020 at 7:48
  • Is recommended to use Observer?
    – zus
    Oct 21, 2020 at 7:53
  • I think in this case it is not recommended to use an observer.
    – Kristoffer
    Oct 21, 2020 at 7:54
1

I have created a minimal payment module tonight:

in etc folder, place a config.xml file like below

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <payment>
            <dummy>
                <active>1</active>
                <model>Mbs\Payment\Model\Dummy</model>
                <order_status>pending</order_status>
                <title>Dummy Payment</title>
                <allowspecific>0</allowspecific>
                <group>offline</group>
            </dummy>
        </payment>
    </default>
</config>

then the Model that is in this config file is below:

<?php

namespace Mbs\Payment\Model;

class Dummy extends \Magento\Payment\Model\Method\AbstractMethod
{
    /**
     * Payment method code
     *
     * @var string
     */
    protected $_code = 'dummy';

    /**
     * Availability option
     *
     * @var bool
     */
    protected $_isOffline = true;

    /**
     * Payment Method feature
     *
     * @var bool
     */
    protected $_canUseCheckout = false;
}

what does the trick to be hidden in the checkout is the variable $_canUseCheckout

Happy to put the module fully but the rest is standard module that you likely know already

0

You could checkout our module https://github.com/customgento/module-admin-payment-m2. It adds an internal payment method, only available and visible in the admin area.

8
0

Assuming your code works, change the observer like this to check area code as well.

app/code/Gta/AdminPay/Observer/PaymentMethodAvailable.php

<?php
namespace Gta\AdminPay\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class PaymentMethodAvailable implements ObserverInterface
{
    private $state;

    public function __construct(
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\App\State $state
     ) {
        $this->_logger = $logger;     
        $this->state = $state;
    }
    
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $result          = $observer->getEvent()->getResult();
        $method_instance = $observer->getEvent()->getMethodInstance();
        $quote           = $observer->getEvent()->getQuote();
        $this->_logger->info($method_instance->getCode());

        if ($method_instance->getCode() == 'checkmo'
            && $this->state->getAreaCode() == 'frontend') {
            $result->setData('is_available', false);
        }
        else
        {
            $result->setData('is_available', true);
        }
    }
}
5
  • Check / Money Order Display front-end also, how to restrict only for admin purpose?
    – zus
    Oct 20, 2020 at 10:25
  • Did you add the code I wrote ? It checks which area it is
    – Kristoffer
    Oct 20, 2020 at 10:28
  • My PaymentMethodAvailable.php : paste.ofcode.org/3b9DHfcHw9cVPtAqgLe37ze
    – zus
    Oct 20, 2020 at 10:36
  • Looks good, is it not working?
    – Kristoffer
    Oct 20, 2020 at 17:32
  • Yes, not working
    – zus
    Oct 21, 2020 at 5:38

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.