5

I have created etc/events.xml as:

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->

<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="process_gateway_redirect" instance="Magento\SamplePaymentGateway\Observer\ProcessGatewayRedirectOrderPlaceAfter" />
   </event>
</config>

And observer for it:

<?php
namespace Magento\SamplePaymentGateway\Observer;

use Magento\Framework\Event\ObserverInterface;

class ProcessGatewayRedirectOrderPlaceAfter implements ObserverInterface
{
    protected $orderFactory;

    public function __construct(\Magento\Quote\Model\QuoteFactory $quoteFactory,
    \Magento\Sales\Model\Order $orderFactory)
    {
        $this->orderFactory = $orderFactory;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        echo 'here I\'m';
        $orderIds = $observer->getEvent()->getOrderIds();
        $lastorderId = $orderIds[0];

        $order = $this->orderFactory->load($lastorderId);
        var_dump($order);
        die();
    }
}

But the event is not executing, one page success is shown. I even tried creating the etc/frontend/events.xml with same code. Anyway the event is not triggered.

I have found that many people are using this event and discussing about other kind of issues.

Many friends are suggesting me to use checkout_submit_all_after and checkout_onepage_controller_success_action. I know about these events and have used previously. But my question is still the same.

Is it impossible to catch the sales_order_place_after?

P S
  • 1,983
  • 4
  • 22
  • 41

4 Answers4

13

sales_order_place_after is not proper,bcoz of it is not fire every time.

sales_order_place_after naturally fires whenever call place() of Magento\Sales\Model\Order and it's call depend on payment method.

As suggestion, iam suggestion to you use

checkout_submit_all_after

It will fire both for frontend /admin order

Amit Bera
  • 77,456
  • 20
  • 123
  • 237
  • Thank you for the suggestion. Please check my updated question. – P S Jan 10 '18 at 05:28
  • I'm using "checkout_submit_all_after" event, but it does not fire when I'm trying to place an order using Rest API. But Works when I'm using native Magento 2 checkout. Can you please help me? – Yudi Nov 27 '18 at 10:34
  • What are all details enclosed with sales_order_place_after like name, qty, price, etc @Amit – zus Aug 22 '19 at 11:38
  • You will get all details of order . $observer->getEvent()->getOrder() Provide the full info about the product – Amit Bera Aug 22 '19 at 11:59
  • @Yudi In Magento 2 there is separate etc/webapi_rest/events.xml for the webapi. For performance reasons not all events execute on the API by default. – micwallace Mar 20 '20 at 07:02
  • @AmitBera, this will not fire when tried to place an order using Rest API. But Works when I'm using native Magento 2 checkout. what is the fix for this issue? – Jafar Pinjar Oct 07 '20 at 08:39
  • @jafarpinjar read the micwallace answer.. – WaPoNe Jul 23 '21 at 13:33
7

In Magento2 use Observer checkout_onepage_controller_success_action for triggering event after place order

You can do this by using the Observer in

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> 

and in

app\code\Vendorname\Modulename\MyObserver.php

file add code -

<?php
namespace Vendorname\Modulename\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Captcha\Observer\CaptchaStringResolver;

class MyObserver implements 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;

     echo "Do your Neccessary Work Here";
    }

}
Dinesh Yadav
  • 6,447
  • 2
  • 23
  • 50
akgola
  • 2,927
  • 1
  • 26
  • 57
  • Thank you for the suggestion. Please check my updated question. – P S Jan 10 '18 at 05:23
  • The above example throws this issue Fatal error: Uncaught Error: Call to a member function getId() on null. @akgola - Can you recheck your code? – Ejilarasan J May 26 '19 at 14:05
1

This code dispatch sales_order_place_after :

$this->_eventManager->dispatch('sales_order_place_after', ['order' => $this]);

Seems like you can use $observer->getEvent()->getOrderIds();;

Try to replace:

$observer->getEvent()->getOrder()->getOrderId();
Nero Phung
  • 1,303
  • 3
  • 12
  • 24
  • Hello Nero, that is not my question. I have not reached the observer. Please do check it and suggest more. – P S Jan 10 '18 at 04:12
  • You just use this event for basically observer after checkout or you are using API, Payment method? – Nero Phung Jan 10 '18 at 08:26
  • Yes I'm using API of other payment gateway. – P S Jan 10 '18 at 10:12
  • Try to debug inside Magento\SalesRule\Observer\SalesOrderAfterPlaceObserver. If this file doesn't run, It means the event sales_order_place_after not fire. We will know the problem become from magento or your custom module – Nero Phung Jan 10 '18 at 10:55
  • @NeroPhung What are all details enclosed with sales_order_place_after like name, qty, price, etc – zus Aug 22 '19 at 11:38
0

if you want to die out code, this events.xml should work:

<?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="my_event_name" instance="Foo\Bar\Observer\MyObserver" />
    </event>
</config>

and the observer php:

<?php
namespace Foo\Bar\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class MyObserver implements ObserverInterface
{
    public function execute(Observer $observer)
    {
        /** @var $orderInstance Order */
        $order = $observer->getOrder();
        $orderId = $order->getRealOrderId();

        \Zend_Debug::dump($orderId);
        die();
    }
}

Note that if you try to place the order via the web view, Magento will detect the die as an error in the order checkout flow, and redirect most likely back to the shopping cart page. You want to test this route via command line or a tool like Insomnia (https://insomnia.rest/). You'll want to set it up as a standard POST to the URL http://mystore.test/rest/default/V1/guest-carts/945bd25fc5b88834ea460d967305fdc2/payment-information (replacing the cart id here with your cart id). You'll also want to post the JSON:

{"cartId":"945bd25fc5b88834ea460d967305fdc2","billingAddress" {"countryId":"US","regionId":"47","regionCode":"OH","region":"Ohio","street":["123 My Rd"],"company":"Mark Shust","telephone":"2165551212","postcode":"44133","city":"Cleveland","firstname":"John","lastname":"Smith","extensionAttributes":{"checkoutFields":{}},"saveInAddressBook":null},"paymentMethod":{"method":"checkmo","po_number":null,"additional_data":null},"email":"john.smith@gmail.com"}

Now when you execute the request with Insomnia, you should see your output, along with a Fatal error at the bottom. This is fine, as Magento will rollback the order because of the die. You can still test and debug your code this way though.