How to get order id using “sales_order_place_after” event
-
15-04-2021 - |
質問
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...
解決
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();
他のヒント
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;
}
}
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
}
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.
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 );
}
}
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();
...
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.