Tutoriel Paypal : Intégration et configuration du paiement en ligne

Tutoriel Paypal : Intégration et configuration du paiement en ligne

A travers ce billet, je vais vous expliquer comment intégrer et configurer le paiement avec Paypal. Cela sous-entend que vous disposiez d'un site qui possède un système de panier complet avec enregistrement des données de la commande et des informations propres au client.

Toutes les étapes pour intégrer Paypal sur son site

Ce tutoriel devrait être extrêmement long puisqu'il y a beaucoup de choses à faire afin de bétonner l'installation de Paypal. Entre les différentes inscriptions sur Paypal, le paramétrage du compte vendeur et les contrôles des données après paiement, vous ne risquez pas de vous ennuyer.

Avant de commencer, je tiens à préciser que j'ai profité du très bon travail de Nicolas à travers son article que j'ai trouvé toutefois un chouilla incomplet pour mes besoins. Vous pouvez le consultez en suivant ce lien : http://www.nicolasauge.com/paypal-paiement-securise/.

Je le remercie également pour sa disponibilité sur Skype pour répondre à mes questions.

1ère étape : ouvrir un compte développeur

Afin de pouvoir effectuer tous les tests nécessaire sans voir son compte débité et devoir procéder à des remboursements, il est nécessaire d'ouvrir un compte sur l'environnement de test de Paypal : https://developer.paypal.com/.

A cette étape, vous devez créer un compte principal qui pour permettra par la suite de créer deux comptes pour les tests : un pour le vendeur et un pour l'acheteur.

2ème étape : créer les comptes de tests

Pour cette seconde partie, tout se passe ici et nécessite d'être connecté à votre compte développeur : https://developer.paypal.com/webapps/developer/applications/accounts.

Cliquer sur le bouton Create Account afin d'accéder à la création des comptes de test et obtenir le formulaire ci-dessous :

Formulaire création compte de test Paypal

Commencez par créer le compte Acheteur (Personnal) et pensez à renseigner le champ PayPal balance afin de disposer de fonds (virtuels hein ^^) pour effectuer vos paiements (3 000 € devraient suffire), ce n'est toutefois pas une obligation. Terminez la création par le compte Vendeur (Business).

Une fois que vos comptes sont créés, vous devriez obtenir la liste qui doit ressembler à cela. Pour info, les adresses e-mails n'ont aucune importance puisque Paypal n'envoie aucun mail pendant les tests. Bizarre ? Non Paypal :-)

Liste des comptes Paypal

Astuce : déployez chacun des deux comptes créés pour vous assurer que dans l'onglet Settings de votre profil que le Payment review est bien sur Off.

Profile du compte test Paypal

3ème étape : régler les paramètres du compte vendeur

Vous pensiez que nous en avions terminé avec les comptes de test. Et bien non, il reste une étape qui consiste à régler le renvoi automatique vers le site après le paiement sur Paypal. Cette opération ne concerne que le compte vendeur. Pour ce faire, rendez-vous sur le site de Paypal : https://www.sandbox.paypal.com/fr/webapps/mpp/accueil-professionnel.

Rendez-vous dans l'onglet Préférences et cliquez sur Préférences de réception de paiements sur le site. Vous devez activer le renvoi automatique et, c'est un comble, renseigner une adresse obligatoire qui n'est pas utilisée par Paypal dans le cadre de ce tutoriel. Vous pouvez indiquer n'importe quelle URL, le retour automatique fonctionnera sur n'importe lequel de vos sites. Vous devriez donc obtenir ce visuel :

Renvoi automatique sur le site depuis Paypal

La partie création des comptes est à présent terminée, nous allons voir ensemble comment envoyer les données du panier à Paypal et traiter le retour des informations après le paiement.

4ème étape : construction du formulaire pour envoyer les données à Paypal

Je vais partir du principe que vous avez déjà codé votre panier et passé les données en session. Nous allons directement coder le formulaire pour renseigner les informations à poster sur la page de paiement de votre boutique en ligne.

Notez qu'il y a deux URL à utiliser pour le formulaire, je vais uniquement utiliser celle de test dans ce tutoriel :

  • URL de test : https://www.sandbox.paypal.com/cgi-bin/webscr
  • URL de production : https://www.paypal.com/cgi-bin/webscr

Je vous copie le code du formulaire et je vous explique le pourquoi avec des zones de commentaires :

<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
/* Indication du montant HT du panier ou TTC si la TVA n'est pas détaillée */
<input name="amount" type="hidden" value="<?php echo $_SESSION['panier']['total_ht']; ?>" />
/* Indication de la devise */
<input name="currency_code" type="hidden" value="EUR" />
/* Indication du montant des frais de port */
<input name="shipping" type="hidden" value="<?php echo $_SESSION['panier']['transport']; ?>" />
/* Indication du montant de la TVA (ou 0.00) */
<input name="tax" type="hidden" value="<?php echo $_SESSION['panier']['total_tva']; ?>" />
/* Indication de l'URL de retour automatique */
<input name="return" type="hidden" value="http://www.monsite.com/retour.php" />
/* Indication de l'URL de retour si annulation du paiement */
<input name="cancel_return" type="hidden" value="http://www.monsite.com/panier.php" />
/* Indication de l'URL de retour pour contrôler le paiement */
<input name="notify_url" type="hidden" value="http://www.monsite.com/ipn.php" />
/* Indication du type d'action */
<input name="cmd" type="hidden" value="_xclick" />
/* Indication de l'adresse e-mail test du vendeur (a remplacer par l'e-mail de votre compte Paypal en production) */
<input name="business" type="hidden" value="test-vendeur@monsite.com" />
/* Indication du libellé de la commande qui apparaitra sur Paypal */
<input name="item_name" type="hidden" value="Le texte que vous voulez" />
/* Indication permettant à l'acheteur de laisser un message lors du paiement */
<input name="no_note" type="hidden" value="1" />
/* Indication de la langue */
<input name="lc" type="hidden" value="FR" />
/* Indication du type de paiement */
<input name="bn" type="hidden" value="PP-BuyNowBF" />
/* Indication du numéro de la commande (très important) */
<input name="custom" type="hidden" value="<?php echo $_SESSION['panier']['commande']; ?>" />
/* Bouton pour valider le paiement */
<input class="bouton" type="submit" value="Payer" />
</form>

Lors de cette étape, il y a un champ qui est extrêmement important. C'est celui du numéro de commande puisqu'il va nous être utile pour récupérer des informations de la base de données. Et pourquoi cela ? Tout simplement parce que Paypal va retourner des informations et qu'il n'est pas possible de comparer les informations mises en session puisque Paypal n'est pas l'acheteur.

Donc il est important que vous enregistriez la commande au moment où le client affiche la page sur laquelle il trouvera le formulaire. Dans ce cas précis, je tague le statut de la commande à 0 pour signifier que le paiement n'a pas encore été effectué. Je m'assure également de récupérer l'ID de commande enregistrée pour ce client et de le mettre en session. De cette façon, si le client revient en arrière puis retourne sur le formulaire, la commande ne sera pas enregistrée une seconde fois.

Cela devrait donner un truc dans le genre :

<?php
if (!isset($_SESSION['panier']['commande'])) {
    // 1 - J'enregistre la commande en BDD avec statut 0
    // 2 - Je récupère le n° de commande dans la BDD et je le mets en session
    $_SESSION['panier']['commande'] = "Dernier ID";
}
?>

5ème étape : traitement de la commande après paiement

Puisque vous avez indiqué dans les paramètres de votre compte vendeur que vous souhaitiez un retour automatique vers votre site après le paiement, vous devez créer une page pour afficher un message stipulant que la commande est enregistrée et que le client va recevoir les différentes notifications par mail.

C'est sur cette page que j'ai choisi de tuer la session du panier.

6ème étape : traitement des informations retournées par Paypal

Voici la partie la plus intéressante mais la plus complexe de ce tutoriel. Cette étape va permettre de vérifier les informations afin de valider la commande... ou pas. Nous ne sommes pas dans un monde de Bisounours, certaines personnes malintentionnées pourraient avoir envie de modifier les données avant de les envoyer à Paypal.

Comment est-ce possible me direz-vous ? C'est extrêmement simple. Il suffit sur Firefox, sur la page de paiement où se trouver le formulaire, de faire un clic droit et de cliquer sur Examiner l'élément pour modifier les valeurs des champs où se trouvent les montants de la commande ou l'adresse e-mail du vendeur.

Nous allons donc nous assurer que ces informations n'ont pas été modifiées. Créez un fichier que vous pouvez nommer par exemple ipn.php.

On commence par indiquer en dur l'adresse e-mail du vendeur que l'on pourra comparer avec celle que renvoi Paypal :

<?php
// Adresse e-mail du vendeur
$email_vendeur = "test-vendeur@monsite.com";

Ensuite, on construit la requête de récupération des infos postées par Paypal :

// Envoi des infos a Paypal
$req = "cmd=_notify-validate";
foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req.= "&$key=$value";
}

On interroge Paypal en utilisant CURL. Pensez à modifier les URL lorsque vous passerez en production :

$fp = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
curl_setopt($fp, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($fp, CURLOPT_POST, 1);
curl_setopt($fp, CURLOPT_RETURNTRANSFER,1);
curl_setopt($fp, CURLOPT_POSTFIELDS, $req);
curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($fp, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($fp, CURLOPT_FORBID_REUSE, 1);
curl_setopt($fp, CURLOPT_HTTPHEADER, array('Connection: Close'));
if( !($res = curl_exec($fp)) ) {
    curl_close($fp);
    exit;
}
curl_close($fp);

Nous allons pouvoir contrôler les données. On commence par vérifier que le paiement est valide comme suit, dans le cas contraire on envoi un mail au vendeur avec les données renvoyées par Paypal :

// Le paiement est validé
if (strcmp(trim($res), "VERIFIED") == 0) {
} else {
    // Le paiement est invalide, envoi d'un mail au vendeur
    $from = "From: test-vendeur@monsite.com";
    $to = "test-vendeur@monsite.com";
    $sujet = "Paiement invalide";
    $body = $req;
    foreach ($_POST as $key => $value) {
        $text.= $key . " = " .$value ."nn";
    }
    mail($to, $sujet, $text . "nn" . $body, $from);
}
?>

Partons du principe que le paiement est OK. Nous allons donc vérifier que le statut du paiement est complet, que l'e-mail du vendeur est conforme et que le montant de la commande n'a pas été modifié par un petit futé :

// Le paiement est validé
if (strcmp(trim($res), "VERIFIED") == 0) {
    // Vérifier que le statut du paiement est complet
    if ($_POST['payment_status'] == "Completed") {
        // Vérification de l'e-mail du vendeur
        if ($email_vendeur == $_POST['receiver_email']) {
            // Récupération du montant de la commande dans la BDD
            $req = "SELECT montant_ttc FROM commandes WHERE id=".$_POST['custom'];
            $rep = mysqli_query($db, $req);
            $row = mysqli_fetch_array($rep);
            // Vérification de la concordance du montant
            if ($_POST['mc_gross'] == $row['montant_ttc']) {
                // Requête pour la mise à jour du statut de la commande => Statut à 1
                // Envoi du mail de récapitulatif de la commande à l'acheteur et au vendeur
            } else {
                // Envoi d'une alerte par mail (voir modèle en bas de cette section)
                // Envoi d'un mail au client pour lui dire qu'on l'a gaulé ? ^^
           }
        } else {
            // Envoi d'une alerte par mail (voir modèle en bas de cette section)                        // Envoi d'un mail au client pour lui dire qu'on l'a gaulé ? ^^        }    } else {        // Envoi d'une alerte par mail (voir modèle en bas de cette section)    }} else {    // Le paiement est invalide, envoi d'un mail au vendeur    $from = "From: test-vendeur@monsite.com";    $to = "test-vendeur@monsite.com";    $sujet = "Paiement invalide";    $body = $req;    foreach ($_POST as $key => $value) {        $text.= $key . " = " .$value ."nn";    }    mail($to, $sujet, $text . "nn" . $body, $from);}?>

Avec toutes ces infos, vous devriez pouvoir installer Paypal sur votre boutique en ligne sans trop de difficultés. Mais comme tout tutoriel, cela ne fonctionnera sans doute pas du premier coup alors n'hésitez pas à vous armer d'un thermos de café et d'une bonne dose de patience.

Votre fichier final devrait sensiblement ressembler à ça. Je dis sensiblement parce que je vous laisse mettre en place vos différentes requêtes et envois de mails.

<?php
// Adresse e-mail du vendeur
$email_vendeur = "test-vendeur@monsite.com";

// Envoi des infos a Paypal
$req = "cmd=_notify-validate";
foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req.= "&$key=$value";
}
$fp = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
curl_setopt($fp, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($fp, CURLOPT_POST, 1);
curl_setopt($fp, CURLOPT_RETURNTRANSFER,1);
curl_setopt($fp, CURLOPT_POSTFIELDS, $req);
curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($fp, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($fp, CURLOPT_FORBID_REUSE, 1);
curl_setopt($fp, CURLOPT_HTTPHEADER, array('Connection: Close'));
if( !($res = curl_exec($fp)) ) {
    curl_close($fp);
    exit;
}
curl_close($fp);
// Le paiement est validé
if (strcmp(trim($res), "VERIFIED") == 0) {
    // Vérifier que le statut du paiement est complet
    if ($_POST['payment_status'] == "Completed") {
        // Vérification de l'e-mail du vendeur
        if ($email_vendeur == $_POST['receiver_email']) {
            // Récupération du montant de la commande dans la BDD
            $req = "SELECT montant_ttc FROM commandes WHERE id=".$_POST['custom'];
            $rep = mysqli_query($db, $req);
            $row = mysqli_fetch_array($rep);
            // Vérification de la concordance du montant
            if ($_POST['mc_gross'] == $row['montant_ttc']) {
                // Requête pour la mise à jour du statut de la commande => Statut à 1
                // Envoi du mail de récapitulatif de la commande à l'acheteur et au vendeur
            } else {
                // Envoi d'une alerte par mail (voir modèle en bas de cette section)
                // Envoi d'un mail au client pour lui dire qu'on l'a gaulé ? ^^
            }
        } else {
            // Envoi d'une alerte par mail (voir modèle en bas de cette section)
            // Envoi d'un mail au client pour lui dire qu'on l'a gaulé ? ^^
        }    
    } else {
        // Envoi d'une alerte par mail (voir modèle en bas de cette section)
    }
} else {
    // Le paiement est invalide, envoi d'un mail au vendeur
    $from = "From: test-vendeur@monsite.com";
    $to = "test-vendeur@monsite.com";
    $sujet = "Paiement invalide";
    $body = $req;
    foreach ($_POST as $key => $value) {
        $text.= $key . " = " .$value ."nn";
    }
    mail($to, $sujet, $text . "nn" . $body, $from);
}
?>

Astuce : n'oubliez pas de protéger les requêtes de vos scripts lorsque vous dialoguez avec votre BDD. Beaucoup oublient de le faire. ;)

Une question ? Un commentaire ? Une idée d'amélioration à apporter ? Laissez un commentaire en dessous. ;)

Catégorie Tutoriels - Écrit par le 14/02/2014 - Article lu 29 520 fois - 17 commentaires

17 réflexions sur ce billet

Écrit par 512banque du site http://www.cultivaref.fr/
Le 16/02/2014 à 13h03

Merci Hervé, même si cet article risque d'avoir peu de commentaires, il est réellement salvateur et vraiment utile :)
En tout cas il va me servir à moi. Merci !

Écrit par Aurélien du site http://oseox.fr/
Le 16/02/2014 à 13h57

Super merci pour le partage !!!

Ah oui, merci beaucoup, c'est pile ce que je cherchais pour un projet à venir. Je fais un lien vers ton article sur mon blog ;-)

Matthieu

Écrit par Karibou de l'Ouganda
Le 04/03/2014 à 14h52

Très bon article ! Dommage que Paypal ne soit pas aussi flexible que les autres moyens de paiement en ligne comme Payza par exemple.

Écrit par cedrine
Le 27/05/2014 à 17h28

Exactement le tuto dont j'avais besoin ! Merci beaucoup pour cet article bien pratique !

Écrit par Adrien
Le 05/08/2014 à 14h36

Merci :)

Écrit par MaPomDamour
Le 10/08/2014 à 12h55

Bonjour !

Tout d'abord, merci beaucoup pour l'article qui m'a été d'une grande aide !
J'arrive presque au bout de mon dev mais je rencontre un soucis pour la partie IPN !

Déjà une question, tu prépares une variable $header mais au final, tu ne l'utilises pas dans ton code, est ce normal ?

J'ai récupéré ton code d'exemple et je l'ai modifié à ma sauce pour mes besoins mais lorsque je fais un test d'appel IPN via le simulateur présent l'interface dev de paypal, ils me retournent cette erreur : "We're sorry, we could not connect to this URL. Please make sure it was entered correctly".

Je ne comprends vraiment pas d'où vient le problème :/
Si tu as des tuyaux, je prends !

Merci d'avance

Écrit par Hervé
Le 10/08/2014 à 16h05

@MaPomDamour

Bien vu pour la variable $header qui n'avait rien à faire là. Pour le simulateur dans l'interface de dev de Paypal, je ne l'ai jamais utilisé. J'ai testé via mon site directement en appelant l'URL de dev de Paypal (sandbox).

Écrit par schfraxx
Le 02/04/2015 à 20h57

Merci !

Écrit par Yannickdu54300
Le 02/12/2015 à 10h50

Merci beaucoup, je confirme que le script fonctionne à la perfection :)

Écrit par PhilippeF75
Le 16/01/2016 à 20h19

Merci !

Super tuto simple et efficace comparé à d'autres sur le sujet que j'ai pu lire avant d'arriver ici et qui ne font que compliquer une procédure somme toute relativement simple.

Après modifications pour l’adapter à mon cas, ça fonctionne très bien.

Bravo encore et tous mes vœux.

Écrit par herve
Le 08/03/2016 à 17h02

Bonjour Hervé

Merci pour le tuto très clair.

Mais je ne sais pas si c'est parce qu'il date de 2014 mais j'ai un souci à l'étape 3 quand tu dis d'aller sur https://www.sandbox.paypal.com/fr/webapps/mpp/accueil-professionnel. Quand je suis cette URL, il me redirige vers https://www.paypal.com/fr/webapps/mpp/merchant et là je ne suis plus sur le sandbox.

Ensuite les indications que tu donnes diffèrent de ce que je vois. Sais tu s'il y a eu des modifs sur le site Paypal ou bien est ce moi qui n'ai pas bien suivi ?

Merci en tout cas

Hervé

Écrit par Hervé
Le 09/03/2016 à 10h28

Bonjour Hervé

A priori cela a changé sur Paypal. Il faudrait que je mette à jour le tutoriel à l'occasion. Mais pour le moment, je manque de temps.

Écrit par Dimitri
Le 29/04/2016 à 15h55

Il faudrait en effet :) Parce qu'il est un peu obsolète et est un des rares tuto pourtant. :(

Mais merci quand même ^^

Dimitri

Écrit par Quent1
Le 14/10/2016 à 10h25

Bonjour,
Serait-il possible d'avoir une mise à jour de ce tutoriel ? Ou quelqu'un a-t-il un tutoriel à jour ?

Merci d'avance.
Quentin.

Écrit par Yaguediop
Le 09/11/2016 à 18h48

Vraiment un grand merci à vous !

Écrit par mistel2
Le 27/01/2017 à 07h51

Merci pour ce tuto super claire.

Mais j'ai un problème de retour paypal, lorsque la transaction est confirmé il me renvoie vers la page déclaré dans return et non dans notify_url..... donc verif impossible

Avez vous déjà eu ce problème ?

Merci d'avance

Mistel2

Écrire un commentaire

Pseudo

E-mail (non publié)

Votre commentaire

Recevoir une notification par e-mail lorsqu'une réponse est postée

Veuillez recopier le code de sécurité : vctchzgpwv

Haut de page