9

I have an event Observer for sales_order_place_after

namespace Company\Ordertool\Observer;

use Magento\Framework\Event\ObserverInterface;

class OrderComplete implements ObserverInterface
{
    /**
     * @var ObjectManagerInterface
     */
    protected $_objectManager;

    /**
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     */
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Quote\Model\QuoteFactory $quoteFactory,
        \Magento\Sales\Model\Order $order
    ) {
        $this->_objectManager = $objectManager;
        $this->order = $order;
    }

    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {



        $order = $observer->getEvent()->getOrder();
        $orderId = $order->getId();

        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/debug.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info( $orderId );


    }
}

$order does appear to be the order ... but $orderId is empty. I feel like I'm missing something obvious here...

0

7 Answers 7

13

sales_order_place_after: This event is dispatched after the order payment is placed.

$order = $observer->getEvent()->getOrder();
$incrementId = $order->getIncrementId();

sales_order_save_after: This event is called every time the order is saved. For eg. Order status changed, invoiced, shipped & credit memo.

$order = $observer->getEvent()->getOrder();
$orderId = $order->getId();
8

The event sales_order_place_after triggers after payment processed but before the order has been saved to database. Id will be available after order was successfully saved to database. So sales_order_place_after will not give you orderId though you will get order incremental id.

On the other hand, if you use sales_order_save_after, it will be triggered every time the order is saved.

If you like to get order id just after place an order using after plugin for Magento\Sales\Api\OrderManagementInterface::place will be the best option.

etc/di.xml

<?xml version="1.0" ?>
    <config>
        <type name="Magento\Sales\Api\OrderManagementInterface">
            <plugin name="MyOrderPlaceAfterPlugin" type="My\Module\Plugin\Order\PlaceAfterPlugin" sortOrder="99" />
        </type>
    </config>

My\Module\Plugin\Order\PlaceAfterPlugin.php

//namespace My\Module\Plugin\Order;

class  PlaceAfterPlugin {


    /**
     * @param \Magento\Sales\Api\OrderManagementInterface $orderManagementInterface
     * @param \Magento\Sales\Model\Order\Interceptor $order
     * @return $order
     */
    public function afterPlace(\Magento\Sales\Api\OrderManagementInterface $orderManagementInterface , $order)
    {
        $orderId = $order->getId();

        // do something with order object (Interceptor )

       return $order;
    }
}
2
  • hello anuik I am getting an order id before the order place and I am using your code but not show the order id Commented Nov 6, 2020 at 5:24
  • Worked perfectly, used it to automatically create an invoice after an order has been placed, which did not work with an observer for the sales_order_place_after event.
    – Louis B.
    Commented Feb 21, 2022 at 15:37
1

Use this code to get Order Id in sales_order_place_after event

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $orderIds = $observer->getEvent()->getOrderIds();
    $lastorderId = $orderIds[0]; // Here you can get OrderID
}
3
  • Is it necessary to create registration.php, composer.json, module.xml for the simple observer?
    – Gem
    Commented Feb 17, 2020 at 11:11
  • 1
    No, You can create an observer in any existing custom module. But it would be better if you create a new module for the custom functionality. Commented Feb 17, 2020 at 12:49
  • It's not working with sales_order_place_after Commented Apr 3 at 11:18
0

Try to remove the $order in the contruct function.

/**
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 */
public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectManager,
    \Magento\Quote\Model\QuoteFactory $quoteFactory,
) {
    $this->_objectManager = $objectManager;
}

Seems like you have not defined the $order variable.

1
  • Is it necessary to create registration.php, composer.json, module.xml for the simple observer?
    – Gem
    Commented Feb 17, 2020 at 11:11
0

You must have to first create events.xml file in etc folder to your module.

Company/Ordertool/etc/events.xml

<?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="sales_order_place_after">
        <observer name="order_id_sales_after" instance="Company\Ordertool\Observer\OrderComplete" />
    </event>
</config>

By this observer you get the Increment Id instead Order Id as Order Id is only available after successfully order completion.

Comapny/Ordertool/Observer/OrderComplete

namespace Company\Ordertool\Observer;

use Magento\Framework\Event\ObserverInterface;

class OrderComplete implements ObserverInterface
{
/**
 * @var ObjectManagerInterface
 */
protected $_objectManager;

/**
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 */
public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectManager,
    \Magento\Quote\Model\QuoteFactory $quoteFactory,
    \Magento\Sales\Model\Order $order
) {
    $this->_objectManager = $objectManager;
    $this->order = $order;
}

/**
 *
 * @param \Magento\Framework\Event\Observer $observer
 * @return void
 */
public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getEvent()->getOrder();
    $orderId = $order->getIncrementId();

    $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/debug.log');
    $logger = new \Zend\Log\Logger();
    $logger->addWriter($writer);
    $logger->info( $orderId );
}
}
0

I've just faced the same situation. I wanted to automatically create an invoice after payment but I needed the orderId for it.

I didn't want to use the 'sales_order_payment_save_after' event because it was running recursively. I wanted to use the 'sales_order_place_after' event instead.

The solution was to call $order->save() in the execute command of the observer before I needed to use it:

public function execute(\Magento\Framework\Event\Observer $observer) {
  $order = $observer->getEvent()->getOrder();
  ...
  // check conditions and if you want to save the order
  $order->save();
  // add code where you need $order->getId() to work
  $orderId = $order->getId();
  ...
0

Use the sales_model_service_quote_submit_success event.

vendor/magento/module-quote/Model/QuoteManagement::submitQuote dispatches the sales_model_service_quote_submit_success after OrderService place() which saves the order and creates the ID.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.