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 !
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 ?
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.
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 » …
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.