Способ оплаты в magento2?


Как отключить способ оплаты наложенным платежом в бэкэнде и интерфейсе Программно?

Вот код, который я использую:

Etc/di.xml

<type name="Magento\OfflinePayments\Model\Cashondelivery">
    <plugin name="cashondeliveryplugin" type="Xxx\Yyy\Plugin\Model\Cashondelivery" sortOrder="10" disabled="false" />
</type>

Плагин:

public function aroundIsAvailable(
    \Magento\OfflinePayments\Model\Cashondelivery $subject,
    callable $proceed,
    $quote = null
) {
    $result          = $proceed($quote);
    $codAvailability = $this->_pincodeModel->isCODAvailable($quote->getShippingAddress()->getPostcode()) ? "yes" : "no";
    if ($codAvailability == 'no') {
        return false;
    }

    return $result;
}

Фактическая проблема заключается в следующем: цитата пропущена при вызове плагина с интерфейса (страница оформления заказа).

Author: Siarhey Uchukhlebau, 2018-02-21

2 answers

Вы можете использовать простой плагин для метода isAvailable модели Magento\OfflinePayments\Model\Cashondelivery:

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

namespace MageWorx\DisableCOD\Plugin;

use Magento\Customer\Model\Session as CustomerSession;
use Magento\Backend\Model\Auth\Session as BackendSession;
use Magento\OfflinePayments\Model\Cashondelivery;

class DisableCashOnDelivery
{
    /**
     * @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
     */
    public function afterIsAvailable(Cashondelivery $subject, $result)
    {
        $condition = true; // Replace with your condition

        if ($condition) {
            return false;
        }

        return $result;
    }
}

Просто измените условия на желаемые.

Результат на интерфейсе (страница оформления заказа):

The result on the frontend

Результат на серверной части (страница создания нового заказа):

The result on the backend

Полный плагин можно найти на github

Обновленный код:

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

namespace MageWorx\DisableCOD\Plugin;

use Magento\Customer\Model\Session as CustomerSession;
use Magento\Backend\Model\Auth\Session as BackendSession;
use Magento\Framework\App\State;
use Magento\OfflinePayments\Model\Cashondelivery;
use Magento\Checkout\Model\Session as CheckoutFrontendSession;
use Magento\Backend\Model\Session\Quote as CheckoutBackendSession;

class DisableCashOnDelivery
{
    /**
     * @var CustomerSession
     */
    protected $customerSession;

    /**
     * @var BackendSession
     */
    protected $backendSession;

    /**
     * @var CheckoutFrontendSession|CheckoutBackendSession
     */
    protected $session;

    /**
     * @param CustomerSession         $customerSession
     * @param BackendSession          $backendSession
     * @param CheckoutFrontendSession $checkoutFrontendSession
     * @param CheckoutBackendSession  $checkoutBackendSession
     * @param State                   $state
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function __construct(
        CustomerSession $customerSession,
        BackendSession $backendSession,
        CheckoutFrontendSession $checkoutFrontendSession,
        CheckoutBackendSession $checkoutBackendSession,
        State $state
    ) {
        $this->customerSession = $customerSession;
        $this->backendSession  = $backendSession;
        if ($state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
            $this->session = $checkoutBackendSession;
        } else {
            $this->session = $checkoutFrontendSession;
        }
    }

    public function aroundIsAvailable(
        \Magento\OfflinePayments\Model\Cashondelivery $subject,
        callable $proceed,
        \Magento\Quote\Api\Data\CartInterface $quote = null
    ) {
        $result = $proceed($quote);
        if ($quote === null) {
            $quote = $this->session->getQuote();
        }
        $codAvailability = $this->_pincodeModel->isCODAvailable($quote->getShippingAddress()->getPostcode()) ? 1 : 0;
        if (!$codAvailability) {
            return false;
        }

        return $result;
    }
}

Не забудьте добавить свои классы в di (_pincodeModel).

Обновление 2:

На интерфейсе аргумент $quote равен нулю, потому что он был вызван из метода \Magento\OfflinePayments\Model\InstructionsConfigProvider::getConfig(), где метод isAvailable() каждого способа оплаты был вызван без предоставления аргументов, что означает, что $quote будет равен нулю:

public function getConfig()
{
    $config = [];
    foreach ($this->methodCodes as $code) {
        if ($this->methods[$code]->isAvailable()) {
            $config['payment']['instructions'][$code] = $this->getInstructions($code);
        }
    }
    return $config;
}

Но в сеансе проверки он существует, и мы можем получить к нему доступ из объекта сеанса проверки.

Обновление 3:

Для серверной части метод isAvailable() всех способов оплаты был вызван из Magento\Payment\Block\Form\Container::getMethods() метод, который предоставляет цитату в списке аргументов:

/**
 * Retrieve available payment methods
 *
 * @return array
 */
public function getMethods()
{
    $methods = $this->getData('methods');
    if ($methods === null) {
        $quote = $this->getQuote();
        $store = $quote ? $quote->getStoreId() : null;
        $methods = [];
        foreach ($this->getPaymentMethodList()->getActiveList($store) as $method) {
            $methodInstance = $this->getPaymentMethodInstanceFactory()->create($method);
            if ($methodInstance->isAvailable($quote) && $this->_canUseMethod($methodInstance)) {
                $this->_assignMethod($methodInstance);
                $methods[] = $methodInstance;
            }
        }
        $this->setData('methods', $methods);
    }
    return $methods;
}

Вот почему вы можете получить доступ к объекту quote напрямую из серверной части, но не можете сделать это на интерфейсе.

 2
Author: Siarhey Uchukhlebau, 2018-02-21 12:44:10

Теперь таким образом отключите способ оплаты, поэтому, пожалуйста, попробуйте COD ok

Сначала вам нужно будет создать events.xml файл в разделе приложение/код/Компания/Модуль/и т.д./. Затем напишите в нем событие "payment_method_is_active". Это событие, которое попадает на страницу оформления заказа для определения доступности способа оплаты.

Приложение/код/Компания/Модуль/и т.д./

<?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="custom_payment" instance="Company\Module\Observer\PaymentMethodAvailable" />
    </event>
</config>

Теперь создайте PaymentMethodAvailable.php в разделе Компания/Модуль/Наблюдатель/ и напишите следующий код в файле. Я отключаю проверку способ оплаты денежным переводом, вы можете изменить код способа оплаты в соответствии с вашими потребностями.

App/code/Company/Module/Observer/PaymentMethodAvailable.php

<?php

namespace Company\Module\Observer;

use Magento\Framework\Event\ObserverInterface;


class PaymentMethodAvailable implements ObserverInterface
{
    /**
     * payment_method_is_active event handler.
     *
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // you can replace "cashondelivery" with your required payment method code
        if($observer->getEvent()->getMethodInstance()->getCode()=="cashondelivery"){
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false); //this is disabling the payment method at checkout page
        }
    }
}

Теперь способ оплаты Заказа наложенным платежом отключен на странице оформления заказа

 0
Author: Ravindrasinh Zala, 2018-02-21 10:27:50