We are currently having a issue with the Observer, most likely we did something wrong, but I have no clue what I've did wrong.

Basically, we created a module with an observer:

namespace Vendor\Customer\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Vendor\Customer\Model\Customer;
use Vendor;

class SalesOrderSaveAfter implements ObserverInterface {
    /** @var \Magento\Framework\Logger\Monolog */

    protected $logger;
    protected $_customer;

    public function __construct(\Psr\Log\LoggerInterface $loggerInterface, 
            \Vendor\Customer\Model\Customer $customer) {
        $this->logger = $loggerInterface;
        $this->_customer = $customer;

     * fires when sales_order_save_after is dispatched
     * @param Observer $observer
    public function execute(Observer $observer) {
        $result = (array) $this->_customer->getOrderData($order);

The problem is, that the module fires the action when the customer clicks on "Place order" in the frontend.

When the customer clicks on "Place order" he will be redirected to a third party payment provider, and after the customer is finishing his payment there, he comes back to the Success-Page, where this Observer triggeres AGAIN.

The result of this is that the observer is triggered twice in one payment process. This seems buggy.

So the question is: how can I tell the Observer to only fire once and only if the payment is successfully done (= when reaching the Success-Page)?


you can use the event checkout_onepage_controller_success_action at Namespace\module\etc\frontend\events.xml :

<event name="checkout_onepage_controller_success_action">
    <observer name="mymodule_controller_success_action" instance="Namespace\Module\Observer\MyObserver"  />
| improve this answer | |
  • Could you elaborate how I can use your solution? Where do I need to put this XML? – Max Aug 2 '16 at 11:06
  • check the edited answer – Manashvi Birla Aug 2 '16 at 11:11
  • The XML lies in etc/, does it make any difference if I place it in etc/frontend/ or not? – Max Aug 2 '16 at 11:15
  • the scope of the observer is defined by the location of the events.xml file in the specific folder. If the observer is required both on the frontend and in the admin panel, it is kept in etc folder. – Manashvi Birla Aug 2 '16 at 11:18
  • 1
    checkout_onepage_controller_success_action is fired only on frontend, so it is advisable to keep events.xml in etc/frontend folder – Manashvi Birla Aug 2 '16 at 11:19

Observe the sales_order_place_after event instead.

| improve this answer | |
  • What is better sales_order_place_after or checkout_onepage_controller_success_action if user has refresh the success page then? – Jackson Jan 13 '17 at 9:01
  • 3
    Main advantage of sales_order_place_after event is that it is called from front end checkout or when creating an order on admin. – Mat Hellums Jan 21 '17 at 8:00
  • Hey @MatHellums do you know if "checkout_onepage_controller_success_action" will be triggered by any payment method - let's say paypal or others? I see they have their own success page.. and "sales_order_place_after" will be trigger only when orders are created right? what If I want to watch an order already created? – Eduardo Feb 1 '17 at 19:18
  • for admin you can use "checkout_submit_all_after" event – chirag dodia May 1 '17 at 7:34
  • 2
    Well i think sales_order_place_after . triggered each time when the order is created (doesn't matter if its been created by customer on frontend or by admin from admin panel, or through API call), but checkout_onepage_controller_success_action only created when customer is successfully placed order on frontend, it will not be fired when the order is being created from admin panel. – Zeeshan Khuwaja Mar 13 '18 at 6:37

The main problem with checkout_onepage_controller_success_action is that you do not necessarly go this page. For instance if you make a payment via credit card, it is not compulsory to go back to the merchant website.

| improve this answer | |

You need to create observer for checkout_submit_all_after event. In this way you will have access to the saved order and quote data in your observer. If something happens in your extension that won't prevent order from being saved. Plus you observer will be called once.

| improve this answer | |

Your Answer

