Titre: Mise en place d'une plateforme d'e-commerce avec Ogone (24/11/2005 Par ovh)
Présentation générale du processus
Ogone est une société d'origine belge, mais qui possède des succursales dans les principaux pays d'Europe. Son rôle est de servir d'intermédiaire entre le site marchand et les différentes institutions financières (banques et organismes de crédit) propres à chaque pays. Pour le programmeur, l'avantage est énorme : plutôt que de devoir développer une interface pour chaque moyen de paiement qu'il souhaite offrir à sa clientèle, une intégration unique suffit.

images/articles/article151/001.gif


Une fois la commande effectuée sur le site marchand (le plus souvent via un panier virtuel), le client est redirigé de manière transparente sur le site d'Ogone où il pourra choisir un moyen de paiement et effectuer la transaction. Ogone le renvoie ensuite automatiquement sur le site marchand qui pourra lui afficher le statut de sa commande (paiement réussi, échoué ou annulé) et entreprendre les actions appropriées (enregistrement dans une base de données, envoi d'un e-mail, etc.).

Voici le schéma des étapes du processus de paiement et les tâches auxquelles elles font appel dans la colonne de droite :

images/articles/article151/002.jpg


Pour bien comprendre le mécanisme il faut savoir que le basculement vers Ogone s'effectue via le bouton submit d'un formulaire GET ou POST du site marchand, dont l'action est une page du serveur d'Ogone. Concrètement, une fois le panier complété sur le site de vente en ligne, celui-ci présente au client une page confirmant les détails de sa commande au bas de laquelle se trouve un formulaire avec des champs cachés (<input type="hidden">) et un bouton submit qui pointe sur Ogone. Les champs cachés contiennent en fait les paramètres du paiement tels que la somme totale, la devise (l'euro), le code d'identification du marchand, etc. Quand il clique sur le bouton, le client se retrouve sur une page d'Ogone où il peut effectuer son paiement. Le serveur d'Ogone va alors communiquer avec le site marchand de manière transparente pour sécuriser la transaction et stocker le résultat (réussite, échec ou annulation), puis afficher le statut avant de proposer une redirection vers le site marchand.

Comme vous pouvez le remarquer sur le schéma, certaines étapes sont facultatives : il s'agit soit de tâches de contrôle, soit de personnalisation de l'affichage. Cet article se base sur une expérience réelle de site d'e-commerce, où j'ai mis la priorité sur la sécurité. J'aborderai donc, outre les étapes de base, les 3 étapes supplémentaires suivantes :

  1. phase de contrôle de la transaction en illustrant les 2 méthodes possibles (signature SHA-1 et envoi d'une page de pseudo-xml)
  2. page post-sale pour stocker dans la base de données le résultat de la transaction renvoyé par Ogone
  3. redirection automatique vers le site marchand avec affichage du statut pour le client final
Ouverture et configuration d'un compte Ogone
Pour développer et tester un site d'e-commerce avec Ogone, la société propose de s'inscrire pour un compte de test entièrement gratuit, permettant d'effectuer des paiements fictifs (voir www.ogone.fr). Une fois le compte créé, il faut paramétrer le comportement général du compte (menu "informations techniques", expliqué plus en détail au point 2.1), puis ajouter et configurer les moyens de paiement.

images/articles/article151/003.jpg


La société propose différents types de solutions suivant les cas d'utilisation : ici nous prendrons le module Ogone e-commerce. Les paramètres généraux à renseigner sont assez explicites sur le site d'Ogone et concerne les coordonnées de la société essentiellement. Dans la configuration de l'abonnement, il n'y a rien de spécial, sauf un module supplémentaire intéressant à activer : le Fraud Detection Module qui permet d'activer les protocoles de sécurité 3D-Secure de VISA et SecureCode de MasterCard pour limiter les risques de fraude par carte de crédit.

images/articles/article151/004.gif


images/articles/article151/005.gif


Paramètres techniques

Il faut ensuite introduire les paramètres techniques qui vont permettre au serveur d'Ogone de dialoguer avec le site marchand, via le menu "Configuration --> Informations techniques". Les différents paramètres sont expliqués sur leur site, je ne les aborderai donc que brièvement :

  1. 1. choix de la méthode GET ou POST pour le dialogue entre Ogone et le serveur du commerçant (donc, nous) : j'ai choisi POST. Il faut aussi définir les différentes adresses e-mail pour les communications de type administratif et technique.
  2. 2. contrôles de l'origine des demandes de paiement : pour éviter le piratage, Ogone vérifiera que l'adresse IP appelante correspond à celle que vous avez indiquée (IP fixe du serveur marchand), et que la page web est bien celle correspondant à l'URL que vous indiquez.
  3. 3. contrôle des données avant paiement : vous indiquez soit une page web qui contiendra des éléments de contrôle en pseudo-XML (format défini par Ogone), soit une chaîne de caractère qui servira à confectionner la signature SHA-1 du formulaire de paiement. Ces points sont expliqués en détail plus bas dans cet article.
  4. 4. ce point définit comment le serveur Ogone retourne le résultat de la transaction financière au marchand : on peut définir une page web "post-sale" sur le site marchand, qui sera appelée (en GET ou POST suivant la config. du point 1) automatiquement par le serveur d'Ogone, et aussi une adresse e-mail qui contiendra un rapport détaillé. Les 2 sont conseillés. Ce point est abordé en détail plus loin dans cet article.
  5. 5. on paramètre ici les messages affichés au client sur le serveur d'Ogone.
  6. 6 à 9 : configuration du traitement de la transaction : paramétrer tout sur "online", "traitement immédiat", "vente directe", et ne rien autoriser en différé ou en offline.


images/articles/article151/006.gif


Cliquez pour agrandir l'image de l'écran de configuration du compte Ogone (ici c'est dans le compte de test).

Configuration des moyens de paiement

Cela se fait via le menu "Configurations --> Moyens de paiement". La liste des moyens de paiement disponibles apparaît en-dessous, il faut les activer puis les configurer un à un. La configuration est généralement assez simple, il suffit la plupart du temps de rentrer un numéro de compte bancaire sur lequel verser l'argent des ventes, ou un numéro de client auprès de l'institution financière. Pour un compte de production réel, Ogone vous met automatiquement en relation par e-mail avec les personnes adéquates dans chaque institution, et vous explique les démarches administratives à effectuer. Il faut en général signer un contrat pour chaque moyen de paiement...
Initialisation : le formulaire d'achat
Une fois que l'acheteur a sélectionné et mis dans son panier tous les articles qu'il souhaite et que les frais de port sont connus et calculés (tout cela se fait en général sur une page récapitulative, dernière étape avant paiement effectif chez Ogone), on peut coder le formulaire html avec le lien vers Ogone de la manière suivante :

  1. <? // ces constantes sont traditionnellement définies dans un fichier annexe 
  2. define("URL""http://mon.magasin.com/"); 
  3. define("URLOGONE""https://secure.ogone.com/ncol/test/orderstandard.asp"); 
  4. define("PSPID""masociete");     // identifiant du marchand = login du compte Ogone 
  5. define("SHASIG""masignature");    // chaine de car. pour construire la sig. SHA-1 
  6. ?> 
  7. <form method="post" action="<?=URLOGONE?>"
  8. <!-- mandatory fields -->             
  9. <input type="hidden" name="orderID" value="<?=$id_vente?>"
  10. <input type="hidden" name="pspid" value="<?=PSPID?>"
  11. <input type="hidden" name="RL" value="ncol_2.0"
  12. <input type="hidden" name="currency" value="EUR"
  13. <input type="hidden" name="language" value="fr_FR"
  14. <? /* il FAUT arrondir à 2 décimales car ogone veut un chiffre rond */ ?> 
  15. <input type="hidden" name="amount" value="<? echo round($prixtot, 2)*100 ?>"
  16. <!-- optional fields --> 
  17. <? /* page de statut à afficher en cas de réussite ou d'échec : ici tout sur la même page */ ?> 
  18. <input type="hidden" name="accepturl" value="<?=URL?>statut.php"
  19. <input type="hidden" name="declineurl" value="<?=URL?>statut.php"
  20. <input type="hidden" name="exceptionurl" value="<?=URL?>statut.php"
  21. <input type="hidden" name="cancelurl" value="<?=URL?>statut.php"
  22.  
  23. <? $shastring = $id_vente.(round($prixtot2)*100)."EUR".PSPID.SHASIG; ?> 
  24. <input type="hidden" name="SHASign" value="<?=sha1($shastring)?>"
  25.  
  26. <? /* paramètres supplémentaires factultatifs pour fonctionnement interne */ ?> 
  27. <input type="hidden" name="paramplus" value="toto=blabla&titi=blublu"
  28.  
  29. <!-- paramde mise en page Ogone --> 
  30. <input type="hidden" name="title" value="Mon magasin virtuel, mon joli titre"
  31.  
  32. <input type="submit" value="Payer"
  33. </form>



Quelques explications sur les variables PHP présentes dans le code :
  1. $id_vente est un numéro unique (clé primaire) représentant la commande. Ogone ne peut jamais voir 2 commandes différentes avec le même numéro, sinon il refuse en affichant un message d'erreur tout sauf clair... Même une commande annulée par l'acheteur doit donc être enregistrée dans votre base de données, pour ne pas réutiliser le même numéro pour une prochaine commande. Faites également très attention au problème de concurrence, en terme de base de données : si vous générez le numéro vous-mêmes, prenez garde à ce qu'aucun client ne puisse obtenir le même numéro en faisant une transaction avec quelques secondes de décalage sur votre site... La meilleure solution consiste à laisser faire votre SGBD : insérez directement une ligne concernant votre commande dans votre DB avant même de lancer la procédure Ogone; votre identifiant sera ainsi fixé et ne pourra pas être "volé". Ensuite quand Ogone vous communique le résultat, faites un update SQL de cette ligne avec le statut du paiement.
  2. $prixtot : montant total de la vente. S'il y a des frais de transport, pensez à les inclure, idem pour toutes les taxes dues par le client (TVA principalement). Ogone veut voir le prix multiplié par 100 pour supprimer les décimales. Exemple : montant = 125.47 EUR, le nombre à indiquer à Ogone sera 12547. Pour éviter toute surprise lors de la multiplication par 100 (montant affiché par Ogone légèrement différent de celui que vous avez affiché à votre client, dû à un problème d'arrondi), il est primordial de penser à arrondir d'abord le montant à 2 décimales avant d'effectuer la multiplication. C'est la raison d'être de la fonction round() dans le code ci-dessus.


L'url de la page action n'est pas la même en test et en production ! Il suffit de remplacer le mot "test" par "prod". La page de statut sera abordée en détail plus loin, de même que la signature de contrôle SHA-1. Vous constatez également la présence de 2 paramètres supplémentaires : paramplus et title. Paramplus permet de renseigner des champs pour l'usage interne du site marchand. Ces champs ne seront pas touchés par Ogone, qui se contentera de les retransmettre tels quels à la page post-sale (appelée automatiquement par Ogone après la transaction), qui pourra donc les traiter comme bon lui semble. L'intérêt pour le marchand est de pouvoir communiquer n'importe quel type d'informations qui lui serait utile à sa page postsale (attention : ne pas oublier d'encoder les valeurs de ces champs avec la fonction PHP urlencode()). Enfin le paramètre "title" permet de personnaliser le titre affiché sur les pages du serveur Ogone vues par le client. Il y a bien d'autres paramètres facultatifs disponibles, qui permettent de personnaliser encore plus le traitement, tout est détaillé dans la documentation d'Ogone.

Les champs accepturl, declineurl, etc. sont les pages du site marchand qui vont afficher le statut de la transaction, c'est le point de retour depuis Ogone. A ne pas confondre avec la page postsale qui n'est qu'un traitement batch, sans aucun affichage, destiné uniquement à mettre à jour la base de données du marchand en fonction des résultats envoyés par le serveur de paiement.
Sécurité : contrôle de la transaction
Par sécurité, Ogone veut s'assurer que les données transmises par le formulaire vu ci-dessus n'ont pas été trafiquées (ce qui est possible par exemple en copiant la page sur son ordinateur local et en modifiant les champs). Pour cela, il propose 2 types de vérification que nous allons aborder.

Signature SHA-1

Cette méthode est identique à la signature des e-mails ou des fichiers que vous téléchargez sur le net (images iso de linux par exemple). Elle consiste à réaliser un "hash" numérique (= la signature) des informations au moyen d'un algorithme tel que SHA-1 ou MD5, qui sera envoyée à Ogone. Celui-ci recalculera cette signature sur base des données de la vente pour vérifier que la signature obtenue est bien identique à celle qu'il a reçue. Si ce n'est pas le cas, c'est que les données ont été altérées.

Cette signature s'effectue au niveau du formulaire de vente, vu au paragraphe précédent; je reprends ici les lignes concernées :

  1. <? $shastring = $id_vente.(round($prixtot2)*100)."EUR".PSPID.SHASIG; ?> 
  2. <input type="hidden" name="SHASign" value="<?=sha1($shastring)?>">


La signature se calcule sur base des caractéristiques de la vente, sous forme de plusieurs chaînes de caractères concaténées (= collées) l'une à l'autre :

  1. la référence de la vente : $id_vente
  2. le montant, arrondi à la façon Ogone (montant réel multiplié par 100) : round($prixtot, 2)*100
  3. le code de la monnaie utilisée (currency), ici donc l'euro : EUR
  4. le PSPID (login) du marchand
  5. la chaîne de caractères propre au marchand, définies dans les paramètres de son compte : SHASIG (on appelle la constante définie plus haut)


Toutes ces données sont concaténées au moyen de l'opérateur PHP . (point) pour former une chaîne unique, $shastring. De cette chaîne on calculera la signature en utilisant l'algorithme SHA-1 au moyen de la fonction intégrée à PHP : sha1($shastring) et on l'envoit à Ogone dans le champ caché "SHASign" du formulaire.

C'est la méthode de contrôle la plus simple à mettre en place et qui est très sûre, je la conseille donc.

Page de pseudo-XML

Ici Ogone va demander au serveur du marchand de lui confirmer les données de la commande qui vient d'être passée. Il transmet le numéro de la commande en question via le paramètre orderID à la page du site marchand dont l'url est renseignée dans la configuration du compte, et attend le résultat sous une forme de pseudo-XML telle que définie dans la documentation Ogone.

Si la commande existe réellement sur le serveur marchand, le résultat doit être du type :

  1. <orderID="12345" amount="12547" currency="EUR">


Sinon il s'attend à un message d'erreur du genre :

  1. <uncorrect orderid 12345>


Voici donc le code de la page de contrôle :

  1. <?php 
  2. // Vérifie provenance IP = serveur OGONE 
  3. if ($_SERVER["REMOTE_ADDR"] != "212.23.45.97"die("Remote server not recognized. Access denied."); 
  4. // ici : récupération des données de la vente 
  5. ... 
  6. // $montant correspondra au montant total 
  7. if (!$montant) { 
  8. ?> 
  9. <uncorrect orderid : "<?=$_REQUEST["orderID"]?>"
  10. <? 
  11. else { 
  12. ?> 
  13. <orderID="<?=$_REQUEST["orderID"]?>"  
  14. amount="<?=round($montant, 2)*100?>"  
  15. currency="EUR"
  16. <? 
  17. ?>


Pour augmenter encore la sécurité (mode paranoïaque), je commence par m'assurer que le serveur appelant est bien celui d'Ogone en contrôlant son adresse IP. Ensuite je récupère les données de la vente, cette partie n'étant pas reproduite ici, libre à vous de faire selon vos habitudes :wink: Les données sont ensuite formatées de la manière requise par Ogone.
Page "post-sale" : retour d'information par Ogone
Si les contrôles vus au point précédent se sont bien déroulés, le client peut poursuivre son paiement sur le site d'Ogone. Une fois l'opération terminée, Ogone renvoit le résultat ainsi qu'une série d'informations au site marchand sur sa page postsale, telle que définie dans la configuration du compte. Classiquement la page postsale se contente de stocker toutes ces variables dans sa base données, comme le montre l'exemple suivant :

  1. <?php 
  2. // Vérifie provenance IP = serveur OGONE 
  3. if ($_SERVER["REMOTE_ADDR"] != "212.23.45.97"die("Remote server not recognized. Access denied."); 
  4. require("...");   // fichier d'inclusion nécessaire 
  5. $vente = new Vente(); 
  6. $vente->registerVente($_POST["orderID"], $_POST["amount"], $_POST["STATUS"],  
  7. $_POST["PAYID"], $_POST["PM"], $_POST["toto"], $_POST["titi"]); 
  8. ?>


A noter que les variables envoyées par Ogone le sont en POST, comme on l'a défini dans le premier paramètre de configuration du compte. Ici j'ai illustré le stockage en base de données via un simple appel de classe, qui se charge d'envoyer les requêtes nécessaires au SGBD. A nouveau, je vérifie si l'adresse IP appelante correspond bien au serveur Ogone avant de faire quoique ce soit. L'appel de cette page est totalement invisible pour le client, qui est pour l'instant toujours sur le site d'Ogone.

Voici la signification des différents paramètres envoyés par Ogone :

  1. orderID : référence de la commande
  2. amount : montant de la commande, au format décimal normal, non multiplié par 100
  3. STATUS : valeur numérique correspond à l'état du paiement. En résumé le plus important est de savoir que 9 représente un paiement accepté.
  4. PAYID : référence interne du paiement Ogone. Valeur importante, car il se retrouvera sur les relevés de compte bancaire du marchand.
  5. PM : pour "payment method", c'est une valeur alphanumérique indiquant la méthode de paiement utilisée par le client : "CreditCard" pour tout type de carte de crédit, "DEXIA" pour un paiement par netbanking de la banque Dexia, etc.
  6. toto et titi : ce sont les champs supplémentaires du "paramplus", à l'usage exclusif du vendeur. Ils peuvent contenir n'importe quelle information, cela reste toujours la liberté du vendeur.


Note : il est important d'utilser les majuscules pour les noms des champs tels qu'envoyés par Ogone, car PHP fait la différence, comme pour les noms de variables.

Redirection sur site marchand et affichage du statut

Nous en arrivons à la fin du processus : le paiement est effectué et le serveur du marchand a été informé du résultat. La dernière étape pour Ogone consiste donc à rediriger le client sur le site du marchand. Il sélectionne une des URL renseignées dans le formulaire de paiement initial (accepturl, declinenurl... ) selon le résultat de la transaction. Dans mon cas toutes ces url sont identiques, car la page sera toujours grosso modo la même, le code PHP étant à même de différencier l'affichage selon le statut qu'il va récupérer dans la base de données. Cette page n'a donc plus aucun lien "technique" avec Ogone, aucun paramètre n'est échangé (puisque tout est déjà fait), il s'agit juste d'afficher au client la page finale de la vente en rappelant les références qui lui seront utiles. A ce stade il est aussi classique de lui envoyer un e-mail de confirmation ou lui permettre de sauvegarder et/ou imprimer son bon de commande ou sa facture. Je n'illustre cet aspect d'aucun code étant donné qu'il n'y a rien de particulier à Ogone ici :wink: Je donnerai cependant 2 liens qui peuvent être utiles : la classe phpmailer pour l'envoi d'e-mail en PHP, bien plus souple et puissante que la fonction mail() intégrée; et la classe FPDF pour la conception de documents PDF plus aisée qu'avec les fonctions de bas niveau.
Conclusion
Nous avons fait le tour des principales fonctionnalités du module Ogone e-commerce, qui permettent de mettre en place relativement aisément un ensemble de possibilités de paiement sur votre site de vente en ligne. Malgré la documentation fournie par Ogone, j'ai estimé utile de rédiger cet article basé sur mon expérience personnelle pour un site réel d'e-commerce, qui d'une part synthétise l'information utile, et d'autre part met en garde sur certains éléments auxquels il vaut mieux prêter attention. J'espère que cela vous aidera si vous envisagez de réaliser un site d'e-commerce utilisant Ogone comme opérateur de paiement.
Retour