Какой наблюдатель использовать после успешного заказа на Magento 2?

11

Я работаю над этим расширением Magento 2, и часть его функций заключается в передаче информации о заказах во внешнее приложение с помощью веб-служб. Мне нужно нажать эту информацию после размещения заказа на кассе.

В данный момент я использую событие, checkout_onepage_controller_success_actionкоторое запускает метод для создания заказов во внешнем приложении. Я поместил это событие в /etc/frontend/events.xml.

Пока это работает, но я нашел проблему со статусом заказов. Иногда заказы все еще находятся в pendingстатусе, а в некоторых других случаях заказы находятся в processing. Причина этого заключается в том, что метод оплаты сначала инициализирует заказы как ожидающие, а после того, как платеж утвержден, заказы изменились на обработку. Я хочу выдвигать только processingзаказы. Кажется, что иногда событие checkout_onepage_controller_success_actionпроходит до того, как платеж авторизован, и это вызывает проблемы.

Есть идеи, как это решить? Как я могу убедиться, что обработка платежа выполняется до того, как я запустил свой код checkout_onepage_controller_success_action?

После моего кода:

events.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2017 companyname.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_onepage_controller_success_action">
        <observer name="companyname_order_success" instance="Companyname\Shipping\Observer\CreateCompanynameOrderObserver" />
    </event>
</config>

CreateCompanynameOrderObserver.php

/**
 * Create an order in Companyname when order status match the statuses in the backend
 *
 * @param EventObserver $observer
 * @return void
 */
public function execute(EventObserver $observer){
    $order_ids  = $observer->getEvent()->getOrderIds();
    $order_id   = $order_ids[0];

    //Loading order details
    $orderModel         = $this->_orderFactory->create();
    $order              = $orderModel->load($order_id);
    $shipping_method    = $order->getShippingMethod();
    $order_status       = $order->getStatus();

    if($order_status == 'processing'){
        //Push to external app
    }
}
Эдуардо
источник

Ответы:

7

Вы можете попробовать событие

checkout_submit_all_after

Он запускается после успешной отправки заказа (и в фоновом режиме, когда вы также создали заказ)

Например, в events.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">

    <event name="checkout_submit_all_after">
        <observer name="yourcompany_yourmodule_checkout_submit_all_after" instance="YourCompany\YourModule\Observer\ProcessOrder" />
    </event>

</config>

И в наблюдателе

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getOrder();
    $quote = $observer->getQuote();

    // Do whatever you want here

    return $this;
}
NgocDB
источник
Это не работает для меня. Событие не было запущено. Я попытался с "checkout_submit_all_after", а также с "sales_order_place_after", но единственное событие, которое я могу зафиксировать с помощью наблюдателя, - это checkout_onepage_controller_success_action. Какие-либо предложения?
Даниэль Сильва
@DanielSilva У меня была та же проблема с событиями, которые не запускались, но затем она работала, когда переходил из внешнего интерфейса в глобальный. То есть переехал из etc/frontend/events.xmlв etc/events.xml. Этого не должно происходить, но это происходит, даже если содержание идентично.
clockworkgeek
Согласно этой старой проблеме, Magento не может перехватывать события sales_order_ * , решение состоит в том, чтобы изменить папку "frontend" на "webapi_rest".
часовой механизм
2

Вы можете использовать sales_order_state_change_beforeсобытие. Он предоставляет доступ к заказу и позволит вам проверить, был ли обработан платеж. Затем, когда платеж будет обработан, он будет запущен снова, что позволит вам создать название компании.

В целом Magento 2, похоже, удаляется от событий в пользу плагинов. Хотя многие в сообществе могут не согласиться с таким подходом, здесь определенно следует иметь в виду.

tjons
источник
Спасибо за ответ @tjons. Похоже, что в Magento 2 осталось не так много событий. Я попытаюсь использовать sales_order_state_change_before и сообщу вам, как это происходит.
Эдуардо
Привет @tjons, я пытался sales_order_state_change_beforeвместо, checkout_onepage_controller_success_actionно это не работало. Не уверен, где мне нужно разместить это событие и будет ли оно срабатывать во время оформления заказа. У меня есть событие в etc/frontend/events.xmlкакой-либо подсказке, почему?
Эдуардо
2

Пожалуйста, используйте событие sales_order_place_after .

Это событие вызывается только один раз и при успешном размещении заказа из файла vendor / magento / module-sales / Model / Order.php в функции ниже.

/**
     * Place order
     *
     * @return $this
     */
    public function place()
    {
        $this->_eventManager->dispatch('sales_order_place_before', ['order' => $this]);
        $this->_placePayment();
        $this->_eventManager->dispatch('sales_order_place_after', ['order' => $this]);
        return $this;
    }
Бхавин иФлэр
источник