Magento – Which observer to use after success order on Magento 2

checkoutevent-observermagento-2.1payment-methods

I am working on this Magento 2 extension and part of the features is to push information about the orders to an external application using web services. I need to push this information after an order is placed in the checkout.

At the moment I am using the event checkout_onepage_controller_success_action which triggers the method to create the orders in the external app. I placed this event in /etc/frontend/events.xml.

So far this is working but I found an issue with the orders status. Sometimes the orders are still in pending status and some other times the orders are in processing. The reason for this is because the payment method first initialize the orders as pending and after the payment is approved, the orders changed to processing. I want to push only processing orders. It seems that sometimes the event checkout_onepage_controller_success_action runs before the payment is authorized and this is causing the issues.

Any idea how to solve this? how can I make sure the payment processing runs before I run my code in checkout_onepage_controller_success_action?

Following my code:

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

Best Answer

You can try the event

checkout_submit_all_after

It runs after order is submited successfully (and in back-end when you created an order too)

For example, in 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>

And in the observer

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

    // Do whatever you want here

    return $this;
}
Related Topic