Configuration du paiement sécurisé Ogone (Partie 2)

ingenico

paiements-ogone

 

Cet article constitue la suite et fin du précédent article "Configuration de la solution de paiement électronique Ogone (Partie 1)".

Post-Paiement Ogone

Après le paiement, le système Ogone peut transmettre une requête HTTP à une URL qu'on spécifie, transmettant les données de la transaction. Ce processus nous permet de mettre à jour notre base de données avec le statut de la commande, etc. et de lancer un processus "fin de transaction" selon les besoins de notre application Web.

En effet, quand un paiement est exécuté, Ogone peut transmettre les paramètres aux URL de redirection ('accept', 'cancel', 'exception' ou 'decline') afin de lancer d'autres traitements.

Par exemple, lorsque le paiement est effectué avec succès, on doit récupérer les informations relatives à la transaction pour mettre à jour la commande dans notre base de données, informer l'utilisateur que le paiement a été bien reçu et que sa commande est en cours de traitement. On garde aussi un historique des paiements Ogone dans notre base de données.

Voici l'url de redirection dans notre cas de test :

https://test.netapsys.fr/Integration/fr/ShoppingCart/SuccessPaiement?orderID=1329

&currency=EUR&amount=66%2E89&PM=CreditCard&STATUS=9&PAYID=3004363538

&NCERROR=0&SHASIGN=C584AE048203B496A6D0C7FE058202BEBAFBF78B

Configuration des paramètres entrants

Pour cela, il faudra spécifier les Urls de redirection que j'ai mentionné dans la première partie et cocher la case "

On peut sélectionner ces paramètres dans « Configuration » > « Information technique » > « Retour d’information sur la transaction » >  » e-Commerce  » > « Paramètres dynamiques du commerce en ligne »

choix_parmateres

Voici les méthodes appelées lors de la redirection en fonction du résultat du paiement. Elles prennent en paramètres ceux qu'on a sélectionné précédemment : OrderID, PM, STATUS, PAYID, NCERROR, SHASIGN, Currency, Amount.

        /// <summary>
        /// Accepturl: displayed when the payment has been authorised, stored, accepted or is waiting to be accepted.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult SuccessPaiement(string orderID, string PM, string STATUS, string PAYID,string NCERROR, string SHASIGN, string currency, string amount)
        {
            var result = ProcessOrder(orderID, PM, STATUS, PAYID, NCERROR, SHASIGN, currency, amount);
            if (result == Consts.PaymentStatus.Success)
            {
                return View();
            }
            return RedirectToAction("Index", "Error");
        }
SuccessPaiement()
        /// <summary>
        /// Declineurl: displayed when the acquirer declines the authorization more than the maximum permissible number of times (as defined in the payment retry section of the Transaction tab).
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult DeclinePaiement(string orderID, string PM, string STATUS, string PAYID,
            string NCERROR, string SHASIGN, string currency, string amount)
        {
            var result = ProcessOrder(orderID, PM, STATUS, PAYID, NCERROR, SHASIGN, currency, amount);
            if (result == Consts.PaymentStatus.Decline)
            {
                return View();
            }
            return RedirectToAction("Index", "Error");
        }
DeclinePaiement()
        /// <summary>
        /// Exceptionurl: displayed when the payment result is uncertain.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult FailurePaiement(string orderID, string PM, string STATUS, string PAYID,
            string NCERROR, string SHASIGN, string currency, string amount)
        {
            var result = ProcessOrder(orderID, PM, STATUS, PAYID, NCERROR, SHASIGN, currency, amount);
            if (result == Consts.PaymentStatus.Failure)
            {
                return View();
            }
            return RedirectToAction("Index", "Error");
        }
FailurePaiement()
        /// <summary>
        /// Cancelurl: displayed when the customer cancels the payment.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult CancelPaiement(string orderID, string PM, string STATUS, string PAYID,
            string NCERROR, string SHASIGN, string currency, string amount)
        {
            var result = ProcessOrder(orderID, PM, STATUS, PAYID, NCERROR, SHASIGN, currency, amount);
            if (result == Consts.PaymentStatus.Cancel)
            {
                return View();
            }
            return RedirectToAction("Index", "Error");
        }
CancelPaiement()

Une fois les paramètres reçus, il faudra procéder à la suite des traitements (méthode "ProcessOrder"):

Il existe une deuxième signature SHA-OUT qui permet de vérifier l'intégrité des données reçues par le serveur Ogone, car le client peut intercepter l'URL de la redirection et altérer ces paramètres. Si aucune signature n'est spécifiée dans le back-office, Ogone n'envoie aucune des quatre URL de redirection.

Calcul de la signature SHA-OUT

La signature est calculée de la même façon que la signature SHA-OUT mais avec les paramètres reçus dans l'ordre alphabétique.

public string CheckSignatureAndSaveHisto(string OrderID, string PM, string STATUS, string PAYID,
            string NCERROR, string SHASIGN, string currency, string amount)
        {
            string result = null;
            Dictionary<string, object> parametres = new Dictionary<string, object>();

            parametres.Add("AMOUNT", amount);
            parametres.Add("CURRENCY", currency);
            parametres.Add("NCERROR", NCERROR);
            parametres.Add("ORDERID", OrderID);
            parametres.Add("PAYID", PAYID);
            parametres.Add("PM", PM);
            parametres.Add("STATUS", STATUS);

            //Creation d'un log paiement
            LogPaiement logPaiement = new LogPaiement();
            logPaiement.logpai_DateCreation = DateTime.Now;
            logPaiement.logpai_cmd_Id = int.Parse(OrderID);
            logPaiement.logpai_CodeRetour = STATUS;
            logPaiement.logpai_Reference = PAYID;
            logPaiement.logpai_Montant = amount;
            logPaiement.logpai_TexteLibre = NCERROR;
            _OrderBusiness.CreateLogPaiement(logPaiement);

            //Calculer la signature SHA1
            string signature = "";

            foreach (System.Collections.Generic.KeyValuePair<string, object> pair in parametres)
            {
                signature += String.Format("{0}={1}{2}", pair.Key, pair.Value, ConfigurationManager.AppSettings["OGONE_SHA_OUT"]);
            }
            string calculatedSHA1Signature = PasswordHelper.HashUTF8String(signature).ToUpper();
            //Vérifier que la signature est valide
            if (calculatedSHA1Signature.Equals(SHASIGN))
            {
                //En fonction du statut du paiement, on renvoie un statut 
                //interne pour rediriger vers l'IHM adéquat
                switch (STATUS)
                {
                    case "9":
                    case "95":
                        //Paiement accepté
                        result = Consts.PaymentStatus.Success;
                        break;

                    case "92"://Payment uncertain
                    case "93": //Payment refused
                        result = Consts.PaymentStatus.Failure;
                        break;

                    case "0"://Invalid or incomplete
                        result = Consts.PaymentStatus.Failure;
                        break;

                    case "1":
                        //Canceled by customer
                        result = Consts.PaymentStatus.Cancel;
                        break;

                    case "2"://Authorisation refused
                    case "7":
                        //Paiement Incomplet ou invalide, Annulé par client, Autorisation refusée, Paiement annulé
                        result = Consts.PaymentStatus.Decline;
                        break;

                    default:
                        //Code statut inconnu ou non géré
                        break;
                }
            }
            else
            {
                //La signature SHA1 est incorrecte
                result = Consts.PaymentStatus.Failure;
            }
            return result;
        }
CheckSignatureAndSaveHisto

Mise à jour de la commande, du panier et envoi de l'email de confirmation

Après vérification de l'exactitude de la signature SHASIGN OUT, on sauvegarde l'historique du paiement, ensuite on met à jour la commande selon le statut du paiement et on envoie un email de la confirmation de commande au client récapitulant le panier, les informations de la commande et du paiement.

        [NonAction]
        public string ProcessOrder(string OrderID, string PM, string STATUS, string PAYID,
            string NCERROR, string SHASIGN, string currency, string amount)
        {
            //Vérifier la signature du paiement Ogone
            var result = _OrderModel.CheckSignatureAndSaveHisto(OrderID, PM, STATUS, PAYID, NCERROR, SHASIGN, currency, amount);

            //récupération des infos de la commande
            Commande commande = _OrderModel.GetCommandeById(int.Parse(OrderID));
            //Mise à jour des infos de la commande
            if (commande != null)
            {
                switch (result)
                {
                    case Consts.PaymentStatus.Cancel:
                        //Le client a volontairement annulé le paiement
                        _OrderModel.UpdateCommandeAfterCancelPaiement(commande);
                        _OrderModel.UpdateStatutPaiementCommande(commande, Consts.Statut.AttentePaiement);
                        break;

                    case Consts.PaymentStatus.Decline:
                    case Consts.PaymentStatus.Failure:
                        _OrderModel.UpdateCommandeAfterFailureOrDeclinePaiement(commande);
                        _OrderModel.UpdateStatutPaiementCommande(commande, Consts.Statut.EchecPaiement);
                        break;

                    case Consts.PaymentStatus.Success:
                        //Vérifier que la commande n'a pas déjà été traitée
                        if (commande.cmd_DatePaiement == null && commande.cmd_DateValidation == null)
                        {
                            _OrderModel.UpdateCommandeAfterSuccessPaiement(commande);
                            _OrderModel.UpdateStatutPaiementCommande(commande, Consts.Statut.PaiementRecu);
                            _OrderModel.UpdateAvoirAndReduction(commande);
                            if (commande.cmd_pan_Id != null)
                            {
                                //Mettre à jour le panier
                                _PanierModel.ValiderPanierAfterPaiement((int)commande.cmd_pan_Id);
                                NavigationSessionService.SetShoppingCart(Session, 0, 0);
                            }

                            //Envoyer un mail de confirmation de commande
                            _OrderModel.EnvoiMailConfirmationAchat(commande.cmd_Id, DatabaseLanguageId);
                        }
                        else
                        {
                            RedirectToAction("Index", "Error");
                        }
                        break;
                }
            }
            return result;
        }
ProcessOrder

Une fois tout les traitements finis, note site nous redirige vers la page de confirmation de paiement:

confirmation_de_paiement

 

Laisser un commentaire

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

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.