I have an observer for the sales_order_invoice_pay event with the following code.

public function execute(\Magento\Framework\Event\Observer $observer) {
  $order = $observer->getEvent()->getInvoice()->getOrder();
  $orderId = $order->getId();
  $incrementId = $order->getIncrementId();

This works fine most of the time. However, when the invoiced total is 0 (e.g. because of a coupon), then $order->getId() is empty. $incrementId is still available, but I'm not able to get the associated order either. It seems that the order is only partially set in this case.

Is it possible to get the complete order object in this case, or do I need to use another event? It is not clear to me what's the difference, because it works if the invoiced total is more than 0. Note that the "Zero Subtotal Checkout" is enabled.

Also, I don't seem to be able to print / debug these objects. All the suggested variants crash in my case (e.g. $order->debug(), $order->getData(), print_r, var_dump). Any suggestions on how to this are appreciated. I currently use the Psr logger.


If you need the order object and trigger some third-party events using the order data. A reliable event is sales_model_service_quote_submit_success. I'll put some details below:

<?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_model_service_quote_submit_success">
        <observer name="mbs_order_save_after" instance="Mbs\OrderTrigger\Observer\OrderSaveAfter" />

The event you use of course has its uses: for instance you may monitor the payment made through your e-commerce website.. but this activity would not need order data other than the one available at the payment capture.

Now, I will attempt to explain why the order id is not present in your case. Let's imagine you hit the place order button. Several operations will occur before the order is created in the database.

1. checkout button is hit:

so far, Magento knows nothing of the order. Instead, Magento has only quote data saved with the model \Magento\Checkout\Model\Session. I invite you to take a look at the function \Magento\Checkout\Model\Type\Onepage::saveOrder

Winthin this method, you can see the event checkout_submit_all_after will no doubt have an order id.

2. the quote is submitted with the aim to create an order. This function is more hands-on. You can see the customer details, shipping details, the payment being made. Also, you see 2 events: sales_model_service_quote_submit_before and sales_model_service_quote_submit_success. I suggest the latter is a good place if you want to log data as soon as you order is physically created.


Either way, the payment is made before this event within the function

  • Thank you for the quick answer! The event indeed works for the case of a 0 subtotal. However, it is fired when an order is placed, before my payment provider returns (payment pending). This means I need to handle these cases with separate events. Is this expected? I had hoped for a single event which can be used for both.
    – Michael M.
    Sep 19 '20 at 18:46
  • I don’t know what you are trying to do. Just answering which event will give you an order id. If my answer reply to your question, then you may thumb up and accept, it often help to have further help.. Sep 19 '20 at 18:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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