TrogloGeek / prestashop-tggatos-module

TggAtos Module for Prestashop (1.4 to 1.7), ATOS SIPS 6xx payment gateway
61 stars 34 forks source link

tgg_atos Erreur de montant si remise groupe #18

Closed TheOnlyOnePascal closed 10 years ago

TheOnlyOnePascal commented 10 years ago

Bonjour,

je viens d'installer en mode test tgg_atos. Je l'ai installé en local et sur un serveur distant. Sur le serveur distant, à cause de la limitation à 52 caractères, il a fallut remonter le répertoire param à la racine, et l'installation se faisant mal, il a fallut que j'intervienne manuellement pour valider le tout.

Les transactions se font bien dans les deux cas.

Par contre, sur le serveur distant, si un client fait partis d'un groupe avec une remise (distributeur), l'envoi du montant au serveur bancaire est juste (remisé), l'accord de la banque est juste, sauf que la validation de la commande se fait avec un montant non remisé et un règlement remisé (donc écart et erreur de paiement affiché).

Le plus bizarre, c'est que cela ne se produit pas en local (montant remisé pris en compte pour la commande et son règlement CB).

D'où peut venir le problème?

Cordialement

prestashop 1.2.5 tgg_atos 2.0 b3-TC3

TrogloGeek commented 10 years ago

Bonjour,

je pense que le problème vient de la réponse automatique/silencieuse : Dans les deux cas (local et distant), le module demande le total du panier et s'en sert pour valider la commande, hors en local je suppose que le serveur bancaire ne peut contacter directement votre instance (adresse non publiquement routable), ce qui fait échouer la réponse silencieuse, c'est donc le retour utilisateur qui convoie les informations de réponse bancaire et valide la commande. Hors lors du retour utilisateur, la session utilisateur est active, ce qui n'est pas le cas de la réponse silencieuse. Je pense que c'est ici que se situe le problème : Prestashop 1.2.5 n'est probablement pas capable d'appliquer correctement la réduction de groupe au panier si la session utilisateur n'est pas active, à moins que ce ne soit le module qui ne fournisse pas assez d'informations de contexte pour cela. La branche 1.2.x de Prestashop est saturée de bugs dès que l'on exploite des fonctionnalités qui ne sont pas activées par défaut, je me souviens avoir passé pas mal de temps pour corriger le calcul des taxes et l'affichage du catalogue en HT pour un client par exemple. Je n'ai pas le temps pour regarder cette semaine si le module tgg_atos est responsable de ce problème ou la version Prestashop, mais je pencherais pour la version Prestashop.

Au fait, la branche 2.0.x est elle aussi sérieusement obsolète, utilisez plutôt la 2.1.7-beta2 ou la 2.1.8-early1.

TrogloGeek commented 10 years ago

Vous devriez pouvoir contourner le problème en ouvrant une session utilisateur grâce à l'ID utilisateur convoyé par la réponse bancaire dans le contexte d'une réponse silencieuse. Cela ne devrait pas demander de grosses modifications sur le module.

TheOnlyOnePascal commented 10 years ago

Bonjour et merci de cette réponse. J'ai installé la 2.1.8-early1.2.1.8-early1 et le problème est identique.

qu'entendez vous par "ouvrant une session utilisateur grâce à l'ID utilisateur convoyé par la réponse bancaire "?

TheOnlyOnePascal commented 10 years ago

En fait, il est vrai que la table cart contient uniquement les qtites et les numero d'article, et au moment de la validation, avec un autre moyen de paiement, prestashop applique à ce moment là la remise : dans la class Product, fonction getPriceStatic, le calcul du prix prend en compte le groupe (// Group reduction if ($id_customer) $price *= ((100 - Group::getReduction($id_customer))/100); ) et cette fonction est appelée par getOrderTotal de Cart.php, utilisé dans PaymentModule.php

Il prend bien en compte l'id_customer.

La réponse de la banque envoi bien le customer_id et l'order_id. Ces données ne sont pas prises en compte dans le script?

TrogloGeek commented 10 years ago

Oui, la mise à jour du module n'était pas censées corriger ce problème, mais d'autres que vous n'avez pas encore remarqués (cf CHANGELOG du module pour connaitre les problèmes en question).

La réponse bancaire comporte l'identifiant de l'utilisateur Prestashop ayant initié le paiement, ouvrir une session utilisateur Prestashop, pour créer un contexte équivalant à celui de la réponse convoyée par le retour client depuis le serveur bancaire, avant l'appel à Cart::getOrderTotal() devrait résoudre le problème.

TheOnlyOnePascal commented 10 years ago

vous n'auriez pas le code sous le main par hasard... :>)

TheOnlyOnePascal commented 10 years ago

A mettre dans PaymentModule.php, validateOrder() si je ne m'abuse?

TrogloGeek commented 10 years ago

Deux approches à ce propos si vous ne souhaitez pas mettre à jour Prestashop :

Dans les deux cas, pour des raisons évidentes de sécurité, je conseille de détruire la session, si il a été nécessaire d'y forcer l'ID utilisateur, avant la fin de PaymentModule::validateOrder() ou Tgg_Atos::processResponse().

De retour de ma semaine de congés j'ai pu effectuer quelques recherches sur le problème dans le code de Prestashop 1.2.5 et c'est effectivement un problème due à la branche 1.2.x : Product::getPriceStatic() n'accepte pas d'identifiant utilisateur en paramètre et ne s'intéresse qu'à celui potentiellement stocké dans le cookie :

    public static function getPriceStatic($id_product, $usetax = true, $id_product_attribute = NULL, $decimals = 6, $divisor = NULL, $only_reduc = false, $usereduc = true, $quantity = 1, $forceAssociatedTax = false)
    {
        global $cookie;

        // Get id_customer if exists
        $id_customer = ((isset($cookie) AND get_class($cookie) == 'Cookie' AND isset($cookie->id_customer) AND $cookie->id_customer)
            ? intval($cookie->id_customer) : null);

Ainsi Cart::getOrderTotal() ne transmet par l'identifiant utilisateur propriétaire du panier à Product::getPriceStatic(), ce qui pose problème pour une validation de commande sans la présence du cookie de session utilisateur (absent lorsque la banque contacte directement la boutique pour valider la commande). Le problème a été corrigé avec Prestashop 1.3.x.

De mon point de vue il s'agit d'une limitation due à une version encore immature de Prestashop qui ne donnera pas lieu à la publication d'une nouvelle version de la branche 2.1.x du module pour contourner le problème puisqu'une mise à jour de Prestashop vers 1.3.x ou 1.4.x corrige le problème d'une manière plus saine que les méthodes proposées plus haut.

TheOnlyOnePascal commented 10 years ago

Bonjour,

il est clair que je ne peut faire de mise à jour de prestashop car le site est en production et cela créerait des problèmes notamment au niveau du template utilisé. J'ai donc décidé de modifier PaymentModule::validateOrder() par contre je ne sais pas comment ouvrir automatiquement la session utilisateur. Pourriez vous me dire comment?

TrogloGeek commented 10 years ago

Ooops, désolé, erreur de ma part : à ce stade on a déjà appelé Cart::getOrderTotal, c'est donc soit dans Tgg_Atos::processResponse() soit dans Cart::getOrderTotal() qu'il faut effectuer la modification. Je conseille plutôt l'approche spécifique (dans le module) car modifier Cart::getOrderTotal() risque d'entrainer des effets de bord indésirables.

TrogloGeek commented 10 years ago
    public function processResponse($Response, &$Customer, &$Order, &$Currency, &$amount, &$cart) {
        global $cookie;
        $Order = null;
        $Response->caller_ip_address = $_SERVER['REMOTE_ADDR'];
        $this->_logResponse($Response);
        $cart = new Cart($Response->order_id);
        if (!Validate::isLoadedObject($cart)) {
            return $this->_invalid_response($this->l('Cart ID returned in id_order field does not exist'), $Response);
        }
        if (!empty($Response->customer_id)) {
            $Customer = new Customer($Response->customer_id);
            if ($cart->id_customer != $Customer->id) {
                return $this->_invalid_response($this->l('Cart which ID has been returned in field id_order does not belong to Customer which ID has been returned in field id_customer'), $Response);
            }
        } else {
            $Customer = new Customer($cart->id_customer);
        }
        if (!Validate::isLoadedObject($Customer)) {
            return $this->_invalid_response($this->l('Customer ID returned in id_customer field does not exist'), $Response);
        }

        // Edit: start
        $idCustomerFaked = false;
        if (($cookie instanceof Cookie) && empty($cookie->id_customer) && $Response->origin == 'silent_response')
        {
            $cookie->id_customer = $cart->id_customer;
            $idCustomerFaked = true;
        }
        // Edit: end

        $currency_used = NULL;

attention cependant à purger la session avant de sortir la fonction si $idCustomerFaked == true pour éviter que cette modification ne puisse permettre de générer des sessions utilisateurs sans authentification.

TheOnlyOnePascal commented 10 years ago

Alors là, bravo. Ça marche nikel.

J'ai rajouté $idCustomerFaked =false à la fin de la fonction processResponse pour purger (je crois que c'est cela qu'il fallait) et cela marche très bien.

Un grand merci...

TrogloGeek commented 10 years ago

$idCustomerFaked =false est totalement inutile, vous devez purger la session $cookie->logout(); avant tout point de sortie de la fonction (return).

TheOnlyOnePascal commented 10 years ago

Ok,Ok, j'ai un peu des problèmes avec les sessions sous presta.... :>) En tout cas merci.

TheOnlyOnePascal commented 10 years ago

Hum, je suis allé un peu vite... au retour de la banque : commande bien validée, mais j'arrive à la page de login car j'ai clos la session et dans 'payment_return.php' j'ai $display_order_confirm = !isset($cookie->{$order_confirm_flag}) && (strtotime($Order->date_add) > strtotime('- 3 hours')); $cookie->{$order_confirm_flag} = TRUE; if ($display_order_confirm) tgg_atos::redirectToShop('order-confirmation.php?key='.urlencode($Order->secure_key).'&id_module='.$Tgg_Atos->id.'&id_cart='.$cart->id);

donc plus de session, donc pas de page de règlement enregistré.

Comment contourner?

TrogloGeek commented 10 years ago

N'auriez-vous pas oublié de conditionner la fermeture de session ?

if ($idCustomerFaked)
    $cookie->logout();
TheOnlyOnePascal commented 10 years ago

exact. j'avais pas pensé comme cela. merci

TheOnlyOnePascal commented 10 years ago

Bonjour,

je vous recontacte suite à un problème: j'avais suivit vos instructions et le module fonctionnait très bien sur mon ancien serveur (Amen) J'ai été obligé de changer de serveur pour passer chez ovh (mutualisé) J'ai donc récupérer tout mon site prestashop et retransféré en binaire ce site sur ovh.

J'ai reparamétré le shell du module, la configuration m'indique ok.

Or lors de l’exécution d'un paiement j'ai l'erreur 127 :

(127): sh: /var/www/philippelaurocreations.fr/web/modules/tgg_atos/bin/request: No such file or directory

J'ai vérifié en ssh et le fichier est bien à la bonne place.

Quand je fait /var/www/philippelaurocreations.fr/web/modules/tgg_atos# bin/request

le serveur me répond: -bash: bin/request: No such file or directory

Qu'est ce qui va pas?

Pour info : tgg_atos 2.0b1.rc1 prestashop 1.2.5

Merci de votre réponse

Le 29/10/2013 01:33, TrogloGeek a écrit :

N'auriez-vous pas oublié de conditionner la fermeture de session ?

if ($idCustomerFaked) $cookie->logout();

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-27269922.

TrogloGeek commented 10 years ago

Bonjour,

premièrement veuillez ne pas recycler un ancien ticket sans rapport avec une demande, en effet les ancien tickets constituent une base de connaissance dans laquelle chacun peu chercher en premier lieu une réponse à sa question, soulever plusieurs problématiques en un seul ticket est donc contre productif.

Autre point, la branche 2.x est maintenant elle aussi sur GitHub : https://github.com/TrogloGeek/old-prestashop-tgg_atos-module, veuillez utiliser le repository GitHub correspondant à votre version.

(127): sh: /var/www/philippelaurocreations.fr/web/modules/tgg_atos/bin/request: No such file or directory

J'ai vérifié en ssh et le fichier est bien à la bonne place.

Quand je fait /var/www/philippelaurocreations.fr/web/modules/tgg_atos# bin/request

le serveur me répond: -bash: bin/request: No such file or directory

Les kernels type unix répondent souvent No such file or directory lorsque les droits sur l'exécutable ne permettent pas de le lire et de l'exécuter.

tucoinfo commented 10 years ago

Tu es certain du chemin /var/www/ ? Ce serait pas plutôt du genre /homez.xx/login/ ?

TheOnlyOnePascal commented 10 years ago

oui, je suis certain du chemin quand je verifie sur le serveur en remontant les répertoires, je trouve bien le fichier request Le chmod de bin est à 755

Le 23/05/2014 11:42, tucoinfo a écrit :

Tu es certain du chemin /var/www/ ? Ce serait pas plutôt du genre /homez.xx/login/ ?

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-43989738.

TrogloGeek commented 10 years ago

Le chmod de bin est à 755

Quid de celui des exécutables ?

TheOnlyOnePascal commented 10 years ago

Le 23/05/2014 11:39, TrogloGeek a écrit :

Bonjour,

premièrement veuillez ne pas recycler un ancien ticket sans rapport avec une demande, en effet les ancien tickets constituent une base de connaissance dans laquelle chacun peu chercher en premier lieu une réponse à sa question, soulever plusieurs problématiques en un seul ticket est donc contre productif.

Autre point, la branche 2.x est maintenant elle aussi sur GitHub : https://github.com/TrogloGeek/old-prestashop-tgg_atos-module, veuillez utiliser le repository GitHub correspondant à votre version.

(127): sh:
/var/www/philippelaurocreations.fr/web/modules/tgg_atos/bin/request:
No such file or directory

J'ai vérifié en ssh et le fichier est bien à la bonne place.

Quand je fait /var/www/philippelaurocreations.fr/web/modules/tgg_atos#
bin/request

le serveur me répond:
-bash: bin/request: No such file or directory

Les kernels type unix répondent souvent |No such file or directory| lorsque les droits sur l'exécutable ne permettent pas de le lire et de l'exécuter.

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-43989492.

Les droits sont à 755 sur bin et request, comme sur l'ancien serveur.

TheOnlyOnePascal commented 10 years ago

A 755

Le 23/05/2014 11:56, TrogloGeek a écrit :

Le chmod de bin est à 755
Quid de celui des exécutables ?

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-43990753.

TrogloGeek commented 10 years ago

755 ou 0755 (octal) ? 0755 est correct et correspond à rwxr-xr-x, 755 lui donne 01363 (octal) ce qui n'est pas bon (et même une sacrée faille de sécurité), Je pars du principe qu'il s'agit de 0755.

Ma seule piste avec les informations données est qu'il y a un lien symbolique quelque part et le path réel du binaire n'a pas le droit d'exécution fixé. Qu'obtiens-tu avec la séquence de commandes ci-dessous :

$ cd /var/www/philippelaurocreations.fr/web/modules/tgg_atos/bin
$ pwd
$ file request
TheOnlyOnePascal commented 10 years ago

Exact 0755

pwd : /var/www/philippelaurocreations.fr/web/modules/tgg_atos/bin

file request: request: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

Le 23/05/2014 12:30, TrogloGeek a écrit :

755 ou 0755 (octal) ? 0755 est correct et correspond à rwxr-xr-x, 755 lui donne 01363 (octal) ce qui n'est pas bon (et même une sacrée faille de sécurité), Je pars du principe qu'il s'agit de 0755.

Ma seule piste avec les informations données est qu'il y a un lien symbolique quelque part et le path réel du binaire n'a pas le droit d'exécution fixé. Qu'obtiens-tu avec la séquence de commandes ci-dessous :

$ cd /var/www/philippelaurocreations.fr/web/modules/tgg_atos/bin $ pwd $ file request

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-43993198.

TrogloGeek commented 10 years ago

Je ne suis pas certain du tout, mais je me demande si l'absence de support x86 (32 bits) sur un serveur x86_64 ne génère pas un message d'erreur de ce type aussi, idem pour une incompatibilité kernel. Je te conseille d'essayer d'autres versions des exécutables fournis par la banque, en évitant les versions dynamically linked qui peuvent plus facilement poser des problèmes de compatibilité.

TheOnlyOnePascal commented 10 years ago

le serveur est bien en 64 bits, donc je demande une version 64 bits à ma banque... Ils doivent les fournir?

Le 23/05/2014 12:40, TrogloGeek a écrit :

Je ne suis pas certain du tout, mais je me demande si l'absence de support x86 (32 bits) sur un serveur x86_64 ne génère pas un message d'erreur de ce type aussi, idem pour une incompatibilité kernel. Je te conseille d'essayer d'autres versions des exécutables fournis par la banque, en évitant les versions dynamically linked qui peuvent plus facilement poser des problèmes de compatibilité.

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-43993886.

TheOnlyOnePascal commented 10 years ago

J'ai installé les binaires en 64bits et ça refonctionne. Merci beaucoup de votre aide.

Le 23/05/2014 12:40, TrogloGeek a écrit :

Je ne suis pas certain du tout, mais je me demande si l'absence de support x86 (32 bits) sur un serveur x86_64 ne génère pas un message d'erreur de ce type aussi, idem pour une incompatibilité kernel. Je te conseille d'essayer d'autres versions des exécutables fournis par la banque, en évitant les versions dynamically linked qui peuvent plus facilement poser des problèmes de compatibilité.

— Reply to this email directly or view it on GitHub https://github.com/TrogloGeek/prestashop-tggatos-module/issues/18#issuecomment-43993886.