Qual observador usar após a ordem de sucesso no Magento 2?

11

Estou trabalhando nessa extensão do Magento 2 e parte dos recursos é enviar informações sobre os pedidos para um aplicativo externo usando serviços da web. Preciso enviar essas informações depois que um pedido é feito no check-out.

No momento, estou usando o evento checkout_onepage_controller_success_actionque aciona o método para criar os pedidos no aplicativo externo. Eu coloquei este evento em /etc/frontend/events.xml.

Até o momento, isso está funcionando, mas encontrei um problema com o status dos pedidos. Às vezes, os pedidos ainda estão no pendingstatus e, outras vezes, nos pedidos processing. O motivo disso é que o método de pagamento inicializa os pedidos como pendentes e, após a aprovação do pagamento, os pedidos são alterados para processamento. Eu quero enviar apenas processingpedidos. Parece que, às vezes, o evento checkout_onepage_controller_success_actionocorre antes do pagamento ser autorizado e isso está causando os problemas.

Alguma idéia de como resolver isso? como posso garantir que o processamento do pagamento seja executado antes da execução do meu código checkout_onepage_controller_success_action?

Seguindo meu código:

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
    }
}
Eduardo
fonte

Respostas:

6

Você pode experimentar o evento

checkout_submit_all_after

É executado depois que o pedido é enviado com sucesso (e no back-end quando você criou um pedido também)

Por exemplo, em 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>

E no observador

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

    // Do whatever you want here

    return $this;
}
NgocDB
fonte
Isso não está funcionando para mim. O evento não foi disparado. Tentei com "checkout_submit_all_after" e também com "sales_order_place_after", mas o único evento que posso capturar com um observador é checkout_onepage_controller_success_action. Alguma sugestão?
Daniel Silva
@DanielSilva Eu tive o mesmo problema com eventos que não foram acionados, mas funcionou quando mudou de front-end para global. Ou seja, mudou de etc/frontend/events.xmlpara etc/events.xml. Isso não deveria acontecer, mas acontece mesmo que o conteúdo seja idêntico.
clockworkgeek
De acordo com esse problema antigo, o Magento não pode capturar eventos sales_order_ * , a solução é alterar a pasta "frontend" para "webapi_rest".
clockworkgeek
2

Você pode usar o sales_order_state_change_beforeevento. Ele fornece acesso ao pedido e permitirá que você verifique se o pagamento foi processado. Então, quando o pagamento for processado, ele será acionado novamente, o que permitirá que você crie o nome da empresa.

Em geral, o Magento 2 parece estar se afastando de eventos em favor de plugins. Embora muitos na comunidade possam não concordar com essa abordagem, é definitivamente algo a ter em mente aqui.

tjons
fonte
Obrigado pela resposta @tjons. Parece que não há muitos eventos restantes no Magento 2. Tentarei usar o sales_order_state_change_before e informaremos como ele será.
Eduardo
Hey @tjons, tentei em sales_order_state_change_beforevez de, checkout_onepage_controller_success_actionmas não estava funcionando. Não tenho certeza de onde eu preciso realizar esse evento e se ele será acionado durante o checkout. Eu tenho o meu evento em etc/frontend/events.xmlalguma pista por quê?
Eduardo
1

Por favor, use o evento sales_order_place_after .

Este evento é chamado apenas uma vez e quando o pedido é realizado com sucesso no fornecedor de arquivos / magento / module-sales / Model / Order.php na função abaixo.

/**
     * 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;
    }
Bhavin iFlair
fonte