Magento : Module de détection des commandes annulées puis payées

Cet article est assez ancien, malgré toute l'attention que j' apporte à mes contenus il est possible que celui-ci ne soit plus d'actualité.
N'hésitez pas à me le signaler si nécessaire via le formulaire de contact.

J’ai récemment été confronté à un problème de commandes annulées, mais payées quand même sur un site Magento en production avec les modes de paiements Atos et Paypal.
Ces changements de statuts empêchent le bon fonctionnement du processus de traitement de la commande.

Pour éviter de devoir consulter l’ensemble des commandes, j’ai donc développé un module Magento pour détecter ces commandes qui posent problème.

Voici l’arborescence des fichiers du module :

— app
–code
— local
— Test
— Module
— controllers
— CronController.php
— etc
— config.xml
–etc
— modules
–Test_Module.xml

C’est également l’occasion de voir ensemble comment créer un module simple sur la plateforme ecommerce Magento. (Version 1.4.1.1)

Pour commencer nous allons créer le fichier de déclaration du module à Magento.
Celui-ci doit être placé dans le dossier « app/etc/modules » sous la forme « MonNamespace_MonModule.xml »
Voici son contenu :

<xml version="1.0"?>
<config>
 <modules>
 <Test_Module>
<active>true</active>
 <codePool>local</codePool>
 </Test_Module>
 </modules>
</config>

Dans ce fichier nous déclarons notre module à magento, et que celui-ci appartient au codepool « local » c’est à dire au code qui est développé par vos soins.

Une fois cette étape réalisée, nous pouvons nous atteler à l’écriture du fichier de configuration du module qui sera placé dans le dossier « app/code/local/Test/Module/ect/config.xml
Dans ce fichier nous allons détailler la version du module, ainsi que son nom d’affichage dans l’url du site ( champ frontname )

<xml version="1.0"?>
<config>
<modules>
<Test_Module>
<version>1.0</version>
</Test_Module>
</modules>    
<frontend>
<routers>
<monrouteur>
<use>standard</use>
<args>
<module>Test_Module</module>
<frontName>test-module</frontName>
</args>
</monrouteur>
</routers>
</frontend>    
</config>

Ainsi configuré notre module sera accessible via le chemin suivant : http://www.votresite.com/index.php/test-module/

Une fois le module configuré, nous allons passer au code de détection en lui même qui sera appelé via une tâche cron et inséré dans le fichier suivant : « app/code/local/Test/Module/controllers/CronController.php »

<?php
/**
 *
 * Tâche cron de détection des commandes à problèmes
 * 
 * @author Hervé Hennes
 * @version 1.0
 * @package Test_Module
 */
 
 class Test_Module_cronController extends Mage_Core_Controller_Front_Action {
 
 /**
 * Affichage du contenu
 *
 * @input : rien
 * @return : mail si nécessaire
 *
 */
 public function indexAction() {
 
 //Envoi d'un email si un problème est détecté
 $checkList = $this->_checkOrders();
 
 if ($checkList) {
 
 $message = '<p>Bonjour,</p>
<p>Le script de detection des erreurs de commandes a detecté des erreurs ce jour</p>
<p>Voici l\'entity_id des éléments concernés :</p>
<ul>';
 foreach ( $checkList as $entity_id ) {
 $message .= '<li>'.$entity_id.'</li>';    
 }
 $message .= '
</ul>
<p>Ce message vous est envoyé automatiquement par le site : http://www.site.com</p>';
 
 $mail = new Zend_Mail();
 $mail->setBodyText('Erreur commandes,merci de consulter la version html');
 $mail->setBodyHtml($message);
 $mail->setFrom('[email protected]', 'Cron');
 $mail->addTo('[email protected]', 'Sender');
 $mail->setSubject('Erreurs Commandes');
 $mail->send();
 
 }
 }
 
 /**
 * Verifie les commandes du jour
 *
 * @input : rien
 * @return : array => liste des commandes à problèmes
 */
 private function _checkOrders() {
 
 $dateRecherche = date('Y-m-d');
 
 // Connexion à la base de données
 $db = Mage::getSingleton('core/resource')->getConnection('core_write');
 
 //Recherche des commandes
 $req_commandes = $db->query("SELECT entity_id , increment_id 
 FROM mag_sales_flat_order 
 WHERE DATE(created_at) = '".$dateRecherche."'   
 OR DATE(updated_at) = '".$dateRecherche."'
 ");                             
 
 $liste_commandes = $req_commandes->fetchAll();
 
 //Récupération des statuts
 $commandes_annulees = array();
 $commandes_probleme = array();
 
 foreach ( $liste_commandes as $commande ) {
 
 $req_statuts = $db->query("SELECT * 
 FROM mag_sales_flat_order_status_history
 WHERE parent_id = ".$commande['entity_id']
 );
 $cancel_flag = false;
 
 while ($liste_statuts = $req_statuts->fetch() ) {
 
 //Si on a encore un statut après le statut annulé c'est qu'il y a un problème
 if ( $cancel_flag == true && $liste_statuts['status']!= 'canceled' && !in_array($commande['entity_id'],$commandes_probleme))
 $commandes_probleme[] = $commande['entity_id'];
 
 //Si la commande a un status annulée on la mets dans un tableau
 if ( $liste_statuts['status'] == 'canceled' ) {
 
 //Pour éviter les doublons (commandes annulées X fois)
 if ( $cancel_flag == false ) {
 $cancel_flag = true;
 $commandes_annulees[] = $commande['entity_id'];
 }
 }
 
 }
 }
 
 // Retours des commandes
 if (sizeof($commandes_probleme))
 return $commandes_probleme;
 else return false; 
 
 }
 }
 
?>

Ce script sera appelé via l’url : http://www.votresite.com/index.php/test-module/cron/ et exécuté de manière quotidienne vers miniuit.
Si il trouve des erreurs il envoie des emails pour vous tenir au courant.

Si vous avez rencontré des problèmes similaires avec Magento, n’hésitez pas à partager vos expériences !

4 réflexions sur “Magento : Module de détection des commandes annulées puis payées”

  1. ce serait bien de résoudre le probleme sur magento plutôt, non ?
    J’ai encore ce problème avec Paypal sur une version 1.7….
    Avez trouvé un correctif ?

    1. De mon côté ce problème se produisait plus souvent avec le paiement CB ( Module Atos/Sips) que Paypal.
      Celui-ci s’est amélioré tout seul après plusieurs semaines… je n’ai donc malheureusement pas de correctif à te fournir
      En ce qui concerne Paypal tu peux consulter le fichier « paypal_unknown_ipn.log » dans var/log il pourra te donner des indications sur les commandes qui posent problèmes.

  2. Le truc c’est que les logs IPN sont bon : le paiement est bien valide.
    Le process semble être le suivant : la personne arrive sur l’interface paypal , fait annulée car elle a pas les infos (=> retour sur le site => la commande passe en annulée) , puis un moment apres fait precedent dans son navigateur(=> retourne sur paypal) et valide le paiement => retour sur le site
    => le statut de la commande passe en « Paiement effectué » puis dans la meme seconde à « Expediée » …

    1. C’est plausible comme fonctionnement.
      Le problème vient du fait que les process de paiement n’intègrent pas le fait que les clients utilisent les boutons précédents / suivants du navigateur.
      A ce stade je ne vois pas trop comment corriger ce comportement.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *