Quel observateur utiliser après une commande réussie sur Magento 2?

11

Je travaille sur cette extension Magento 2 et une partie des fonctionnalités consiste à pousser les informations sur les commandes vers une application externe à l'aide de services Web. Je dois pousser ces informations après qu'une commande est passée à la caisse.

En ce moment, j'utilise l'événement checkout_onepage_controller_success_actionqui déclenche la méthode pour créer les commandes dans l'application externe. J'ai placé cet événement dans /etc/frontend/events.xml.

Jusqu'à présent, cela fonctionne, mais j'ai trouvé un problème avec le statut des commandes. Parfois, les commandes sont toujours en cours pendinget d'autres fois, les commandes sont en cours processing. La raison en est que le mode de paiement initialise d'abord les commandes en attente et après l'approbation du paiement, les commandes sont passées au traitement. Je veux pousser uniquement les processingcommandes. Il semble que parfois l'événement se checkout_onepage_controller_success_actiondéroule avant que le paiement ne soit autorisé et que cela cause des problèmes.

Aucune idée sur la façon de résoudre ça? comment puis-je m'assurer que le traitement des paiements s'exécute avant d'exécuter mon code checkout_onepage_controller_success_action?

En suivant mon code:

events.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2017 companyname.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_onepage_controller_success_action">
        <observer name="companyname_order_success" instance="Companyname\Shipping\Observer\CreateCompanynameOrderObserver" />
    </event>
</config>

CreateCompanynameOrderObserver.php

/**
 * Create an order in Companyname when order status match the statuses in the backend
 *
 * @param EventObserver $observer
 * @return void
 */
public function execute(EventObserver $observer){
    $order_ids  = $observer->getEvent()->getOrderIds();
    $order_id   = $order_ids[0];

    //Loading order details
    $orderModel         = $this->_orderFactory->create();
    $order              = $orderModel->load($order_id);
    $shipping_method    = $order->getShippingMethod();
    $order_status       = $order->getStatus();

    if($order_status == 'processing'){
        //Push to external app
    }
}
Eduardo
la source

Réponses:

7

Vous pouvez essayer l'événement

checkout_submit_all_after

Il s'exécute après que la commande a été soumise avec succès (et en back-end lorsque vous avez également créé une commande)

Par exemple, dans events.xml

<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="yourcompany_yourmodule_checkout_submit_all_after" instance="YourCompany\YourModule\Observer\ProcessOrder" />
    </event>

</config>

Et dans l'observateur

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getOrder();
    $quote = $observer->getQuote();

    // Do whatever you want here

    return $this;
}
NgocDB
la source
Cela ne fonctionne pas pour moi. L'événement n'est pas déclenché. J'ai essayé avec "checkout_submit_all_after" et aussi avec "sales_order_place_after" mais le seul événement que je puisse capturer avec un observateur est checkout_onepage_controller_success_action. Aucune suggestion?
Daniel Silva
@DanielSilva J'ai eu le même problème avec les événements qui ne se déclenchaient pas, mais cela a fonctionné lors du passage du frontend au global. Autrement dit, déplacé de etc/frontend/events.xmlà etc/events.xml. Cela ne devrait pas se produire, mais cela se produit même si le contenu est identique.
clockworkgeek
Selon ce vieux problème, Magento ne peut pas capturer les événements sales_order_ * , la solution est de changer le dossier "frontend" en "webapi_rest".
clockworkgeek
2

Vous pouvez utiliser l' sales_order_state_change_beforeévénement. Il donne accès à la commande et vous permettra de vérifier si le paiement a bien été effectué. Ensuite, lorsque le paiement sera traité, il sera renvoyé, ce qui vous permettra de créer le nom de l'entreprise.

En général, Magento 2 semble s'éloigner des événements au profit des plugins. Bien que de nombreux membres de la communauté ne soient pas d'accord avec cette approche, c'est certainement quelque chose à garder à l'esprit ici.

tjons
la source
Merci pour la réponse @tjons. Il semble qu'il ne reste plus beaucoup d'événements dans Magento 2. J'essaierai d'utiliser sales_order_state_change_before et je vous ferai savoir comment ça se passe.
Eduardo
Hé @tjons, j'ai essayé sales_order_state_change_beforeau lieu de checkout_onepage_controller_success_actionmais cela ne fonctionnait pas. Je ne sais pas où je dois placer cet événement et s'il se déclenchera lors du paiement. J'ai mon événement en etc/frontend/events.xmltout cas pourquoi?
Eduardo
2

Veuillez utiliser l' événement sales_order_place_after .

Cet événement n'appelle qu'une seule fois et lorsque la commande est passée avec succès depuis le fichier vendor / magento / module-sales / Model / Order.php dans la fonction ci-dessous.

/**
     * Place order
     *
     * @return $this
     */
    public function place()
    {
        $this->_eventManager->dispatch('sales_order_place_before', ['order' => $this]);
        $this->_placePayment();
        $this->_eventManager->dispatch('sales_order_place_after', ['order' => $this]);
        return $this;
    }
Bhavin iFlair
la source