7

I want to catch sales order place after event in Magento 2.

Here is my 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="neo_ordercomment_observer_orderneo" instance="Neo\OrderComment\Observer\Orderneo" />
    </event>
</config>

And my observer file is Orderneo file,

<?php

namespace Neo\OrderComment\Observer;

class Orderneo implements \Magento\Framework\Event\ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $order= $observer->getData('order');
        $comment = $this->getRequest()->getParams('comment');
        print_r("Catched event succssfully !"); exit;
    }
}

But it is not comming to this file,

It should print that last line and then exit. But it is redirecting to Magento's order success page.

4
  • 3
    Use checkout_onepage_controller_success_action event
    – Jackson
    Commented Mar 29, 2017 at 9:26
  • Okay means in events.xml, do I have to replace the event name ? Commented Mar 29, 2017 at 9:27
  • 1
    Yes <event name="checkout_onepage_controller_success_action"> & public function execute(\Magento\Framework\Event\Observer $observer) { print_r("Catched event succssfully !"); exit; }
    – Jackson
    Commented Mar 29, 2017 at 9:29
  • Okay let me check.. Commented Mar 29, 2017 at 9:29

6 Answers 6

8

You can try with below code in your observer and check,

class Orderneo implements \Magento\Framework\Event\ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
     $order = $observer->getEvent()->getOrder();
     echo $orderId = $order->getId();
     $comment = $this->getRequest()->getParam('comment');
     print_r("Catched event succssfully !"); exit;
    }
}
10
  • So no need to make changes, in events.xml ? Commented Mar 29, 2017 at 9:32
  • 1
    yes no need to change in event.xml file Commented Mar 29, 2017 at 9:34
  • No, still directly order success page is getting called Commented Mar 29, 2017 at 9:42
  • 1
    You can try with @ankit suggested event, checkout_onepage_controller_success_action and check. Commented Mar 29, 2017 at 9:43
  • 1
    just comment line $comment = $this->getRequest()->getParam('comment'); and check. Commented Mar 29, 2017 at 9:55
9

It's better use this event instead of sales_order_save_after and checkout_onepage_controller_success_action

checkout_submit_all_after

It will work even site not redirected to success page because of some errors like internet issue, etc.

3

You can use checkout_onepage_controller_success_action and sales_order_save_after event while after order placing event.

But you can not use print_r(),die(); and exit(); for debugging. So you can use log method for debugging here.

you can use print_r(),die();,exit(); and also log method in checkout_onepage_controller_success_action event.

while useing checkout_onepage_controller_success_action event

Filepath:app\code\Vendorname\Modulename\etc\frontend\events.xml

<event name="checkout_onepage_controller_success_action">
    <observer name="mymodule_controller_success_action" instance="Vendorname\Modulename\Observer\MyObserver"  />
</event> 

Filepath:app\code\Vendorname\Modulename\MyObserver.php

<?php
namespace Vendorname\Modulename\Observer;

use Magento\Framework\Event\ObserverInterface;

class MyObserver implements ObserverInterface
{
      public function execute(\Magento\Framework\Event\Observer $observer)
    {
     $order = $observer->getEvent()->getOrder();
     echo $orderId = $order->getId();
     print_r("Catched event succssfully !"); 
     exit;
    }

}

while using sales_order_save_after event

Filepath:app\code\MyCompany\MyModule\etc\frontend\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_save_after">
        <observer name="mymodule_sales_order_save_after" instance="MyCompany\MyModule\Observer\MyObserver" />
    </event>
</config>

Filepath:app\code\MyCompany\MyModule\MyObserver.php

  <?php namespace MyCompany\MyModule\Observer; 
    use Magento\Framework\Event\ObserverInterface; 

    class MyObserver implements ObserverInterface { 


        public function execute(\Magento\Framework\Event\Observer $observer) { 
            $order = $observer->getEvent()->getOrder();
            $customerId = $order->getCustomerId();
            $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/templog.log');
            $logger = new \Zend\Log\Logger();
            $logger->addWriter($writer);
            $logger->info('Catched event succssfully');

       }
   }

Edited Date:- 19th Aug, 2021 "sales_order_save_after" event is best for any custom operation becuase "sales_order_save_after" event fire on every state change(works for Front Side & Admin side both)...

If you wants to do any custom operation at any specific state, then you can easily using this event.

I share detail example below...

If you want to do any operation at only "new" state of sales order then you can do...

$order = $observer->getEvent()->getOrder();
if($order->getState() == "new")
{
     ....
     //do your code as per your need
     ....
}

Please Note that:-

we can't debug it in sales_order_save_after event using like echo $variable, print_r($variable) or echo "console.log(".json_encode($variable).")"; If you want to debug it then use logger method(print in log file).

See Below Example code

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

you can see full example below...

<?php 
namespace Vendor\ModuleName\Observer; 
use Magento\Framework\Event\ObserverInterface; 

class classname implements ObserverInterface 
{ 
    protected $order;
    protected $_productFactory;

    public function __construct(
        \Magento\Sales\Model\Order $order,
        \Magento\Catalog\Model\ProductFactory $productFactory
    ) {
        $this->order = $order;
        $this->_productFactory = $productFactory;
    }

    public function execute(\Magento\Framework\Event\Observer $observer) 
    { 
        $order = $observer->getEvent()->getOrder();
        $orderId = $order->getId();
    
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/templog.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        if($order->getState() == "new")
        { 
            $logger->info("OrderId ".$orderId);
            $logger->info($order->getState());

            $product = $this->_productFactory->create();
            foreach($order->getAllVisibleItems() as $item ) {
                //   $productColl = $product->load($item->getProductId());
                $productId = $item->getProductId();
                $QtyOrdered = $item->getQtyOrdered();
                $logger->info("Order Items ".$productId." Total Qty".$QtyOrdered);
            }
            $logger->info('Catched event succssfully'); 
        }
    }

}
1
  • how does this work sales_order_save_after? Commented Nov 26, 2019 at 9:58
0
<?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="checkout_submit_all_after">
        <observer name="vendor_sales_order_place_after" instance="Vendor\LoyalCustomer\Observer\AfterPlaceOrder" />
    </event>
</config>
0
<?php

declare(strict_types=1);
namespace Vendor\LoyalCustomer\Observer;

use Exception;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\ResourceModel\CustomerRepository;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\State\InputMismatchException;
use Magento\Sales\Model\ResourceModel\Order\Collection;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;

/**
 * Executes on order status change
 *
 * Class AfterPlaceOrder
 */
class AfterPlaceOrder implements ObserverInterface
{
    /**
     * @var CollectionFactory
     */
    private CollectionFactory $_orderCollectionFactory;

    /**
     * @var CustomerRepository
     */
    private CustomerRepositoryInterface $customerRepository;

    /**
     * @param CollectionFactory $orderCollectionFactory
     * @param CustomerRepositoryInterface $customerRepository
     */
    public function __construct(
        CollectionFactory $orderCollectionFactory,
        CustomerRepositoryInterface $customerRepository
    ) {
        $this->_orderCollectionFactory = $orderCollectionFactory;
        $this->customerRepository = $customerRepository;
    }

    /**
     * @param Observer $observer
     * @return void
     * @throws Exception
     */
    public function execute(Observer $observer)
    {
        $order = $observer->getEvent()->getOrder();
        $customerId = $order->getCustomerId();
        $this->updateLoyalAttribute($customerId);
    }

    /**
     * Update the Attribute thorugh customer Id
     *
     * @param $customerId
     * @throws InputException
     * @throws LocalizedException
     * @throws NoSuchEntityException
     * @throws InputMismatchException
     */
    private function updateLoyalAttribute($customerId)
    {
        $collection = $this->countOrders($customerId);
        $customer = $this->customerRepository->getById($customerId);
        if (count($collection) > 2) {
            $customer->setCustomAttribute('loyal_customer', true);
        } else {
            $customer->setCustomAttribute('loyal_customer', false);
        }
        $this->customerRepository->save($customer);
    }

    /**
     * Count the order
     *
     * @param $customerId
     * @return Collection
     */
    private function countOrders($customerId)
    {
        return $this->_orderCollectionFactory->create($customerId)
            ->addFieldToSelect('status')
            ->addFieldToFilter('status', 'Complete');
    }
}
0
<?php

declare(strict_types=1);
namespace Vendor\LoyalCustomer\Observer;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\Session;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\State\InputMismatchException;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
/**
 * Change the behaviour of customer
 *
 * Class AfterPlaceOrder
 */
class AfterPlaceOrder implements ObserverInterface
{
    /**
     * @var CollectionFactory
     */
    private CollectionFactory $orderCollection;

    /**
     * @var CustomerRepositoryInterface
     */
    private CustomerRepositoryInterface $customerRepositoryInterface;

    /**
     * @var Session
     */
    private Session $customerSession;

    /**
     * @param CollectionFactory $orderCollection
     * @param CustomerRepositoryInterface $customerRepositoryInterface
     * @param Session $customerSession
     */
    public function __construct(
        CollectionFactory $orderCollection,
        CustomerRepositoryInterface $customerRepositoryInterface,
        Session $customerSession
    ) {
        $this->orderCollection = $orderCollection;
        $this->customerRepositoryInterface=$customerRepositoryInterface;
        $this->customerSession=$customerSession;
    }

    /**
     * Update the loyal customer attribute after placing the order 2 and more
     *
     * @param Observer $observer
     * @return void
     * @throws InputException
     * @throws InputMismatchException
     * @throws LocalizedException
     * @throws NoSuchEntityException
     */
    public function execute(Observer $observer)
    {
        $order = $observer->getEvent()->getOrder();
        $customerId = $order->getCustomerId();
        $customer = $this->customerRepositoryInterface->getById($customerId);
        $orderCollection = $this->orderCollection->create()->addFieldToFilter('customer_id', $customerId);
        if ($orderCollection->count() >= 2) {
            $customer->setCustomAttribute('loyal_customer', true);
        } else {
            $customer->setCustomAttribute('loyal_customer', false);
        }
        $this->customerRepositoryInterface->save($customer);
    }
}

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.