¿Qué observador usar después del orden de éxito en Magento 2?

11

Estoy trabajando en esta extensión de Magento 2 y parte de las características es enviar información sobre los pedidos a una aplicación externa mediante servicios web. Necesito enviar esta información después de realizar un pedido en la caja.

En este momento estoy usando el evento checkout_onepage_controller_success_actionque activa el método para crear los pedidos en la aplicación externa. Coloqué este evento en /etc/frontend/events.xml.

Hasta ahora esto funciona, pero encontré un problema con el estado de los pedidos. A veces, los pedidos todavía están en pendingestado y otras veces los pedidos están en processing. La razón de esto es porque el método de pago primero inicializa los pedidos como pendientes y después de que se aprueba el pago, los pedidos cambian a procesamiento. Solo quiero enviar processingórdenes. Parece que a veces el evento se checkout_onepage_controller_success_actionejecuta antes de que se autorice el pago y esto está causando los problemas.

Alguna idea de como resolver esto? ¿Cómo puedo asegurarme de que el procesamiento de pagos se ejecute antes de ejecutar mi código checkout_onepage_controller_success_action?

Siguiendo mi código:

eventos.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
fuente

Respuestas:

6

Puedes probar el evento

checkout_submit_all_after

Se ejecuta después de que el pedido se haya enviado correctamente (y también en el back-end cuando creó un pedido)

Por ejemplo, en 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>

Y en el observador

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

    // Do whatever you want here

    return $this;
}
NgocDB
fuente
Esto no está funcionando para mí. El evento no ha sido despedido. Intenté con "checkout_submit_all_after" y también con "sales_order_place_after", pero el único evento que puedo capturar con un observador es checkout_onepage_controller_success_action. ¿Alguna sugerencia?
Daniel Silva
@DanielSilva Tuve el mismo problema con los eventos que no se activaban, pero luego funcionó cuando pasé de la interfaz a la global. Es decir, movido de etc/frontend/events.xmla etc/events.xml. Esto no debería suceder, pero sucede a pesar de que el contenido es idéntico.
clockworkgeek
Según este viejo problema, Magento no puede capturar eventos sales_order_ * , la solución es cambiar la carpeta "frontend" a "webapi_rest".
clockworkgeek
2

Puedes usar el sales_order_state_change_beforeevento. Proporciona acceso al pedido y le permitirá verificar si se procesó el pago. Luego, cuando se procese el pago, se volverá a disparar, lo que le permitirá crear el nombre de la empresa.

En general, Magento 2 parece estar alejándose de los eventos en favor de los complementos. Si bien muchos en la comunidad pueden no estar de acuerdo con ese enfoque, definitivamente es algo a tener en cuenta aquí.

tjons
fuente
Gracias por la respuesta @tjons. Parece que no quedan muchos eventos en Magento 2. Trataré de usar sales_order_state_change_before y le diré cómo va.
Eduardo
Hola @tjons, lo intenté en sales_order_state_change_beforelugar de checkout_onepage_controller_success_actionpero no estaba funcionando. No estoy seguro de dónde necesito colocar este evento y si se activará durante el pago. Tengo mi evento en etc/frontend/events.xmlalguna pista ¿por qué?
Eduardo
1

Utilice sales_order_place_after event.

Este evento se llama solo una vez y cuando el pedido se realiza con éxito desde el archivo vendor / magento / module-sales / Model / Order.php en la siguiente función.

/**
     * 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
fuente