Automatiser son backoffice avec Paypal IPN

Paypal possède une grande notoriété et je ne vous le présenterai donc pas. C’est un bon choix d’intermédiaire pour récolter des paiements sur son site internet. Qu’il soit seul ou couplé à une solution bancaire, Paypal est devenu indispensable. Seulement, Paypal propose une multiplicité de moyens d’intégration sur son site. Du bouton HTML à l’API NVP, il est parfois difficile d’automatiser son backoffice. De l’envoi d’un email de confirmation de commande à la synchronisation de sa base de données clients, l’automatisation est plus pratique – et efficace – que d’attendre les mails de confirmation paiement de Paypal et d’agir manuellement.

Différentes technologies de paiement

Dans l’ensemble, Paypal dispose de trois moyens d’intégrer sa solution de paiement :

IPN : Instant Payment Notification

schéma paypal ipn
Illustration du fonctionnement de l’IPN

L’IPN, s’est en fait le serveur de Paypal qui va se connecter à votre site pour vous avertir d’un paiement, d’un échec… C’est donc un moyen pour vous de savoir si vous avez été payé pour telle ou telle chose, quand et combien, et d’agir en conséquence. À chaque fois que Paypal veut vous notifier d’un paiement (ou annulation etc), il se connecte à votre site via une url que vous aurez définie et transmet donc les informations à votre script.

Cependant, les deux API de Paypal, de la même manière que l’API ATOS, fonctionnent selon le modèle de dialogue client-serveur, et de ce fait, votre site est immédiatement au courant de la réussite ou de l’échec du paiement. Vous vous dîtes alors, à juste titre, que l’intérêt de l’IPN est limité, il servira uniquement aux sites se servant des boutons html et qui n’ont donc pas immédiatement connaissance du résultat du paiement. Pas tout à fait…

D’une part, c’est sans compter par exemple, sur la possibilité des paiements récurrents de Paypal. Dans ce cas, votre utilisateur souscrit un abonnement, donc au premier paiement, il passe par votre site et l’API (ou les boutons html), mais ensuite, il est débité à l’initiative de Paypal sans devoir repasser par votre site, et donc votre API ne vous sera d’aucun secours pour être notifié de la réussite ou de l’échec du paiement. D’autre part, un paiement peut-être annulé, ou remboursé, et cela s’effectue aussi en dehors de votre API SOAP ou NVP. En revanche, nous l’avons évoqué plus haut, la connexion de l’IPN est à l’initiative de Paypal, ce dernier notifiera donc votre site aussi pour la réception d’un paiement récurrent. C’est dans ce cas que l’IPN prend tout son intérêt.

La mise en place

La mise en place de l’IPN peut se faire dans divers langages, ASP, Perl, JAVA, ColdFusion… Vous retrouverez des exemple de codes sur le site des développeurs. Pour notre part, nous allons mettre en place l’IPN en PHP. Je vous laisse donc directement avec le code, dûment commenté :

<?php

// prépare la requête de vérification
$req = "cmd=_notify-validate";

// ajoute le message IPN au format NVP à la requête de vérification
foreach ($_POST as $key => $value) {
  $value = urlencode(stripslashes($value));
  $req .= '&$key=$value';
}


// définition des headers pour la requête de vérification
$header  = "POST /cgi-bin/webscr HTTP/1.0rn";

// test
//$header .= "Host: www.sandbox.paypal.com:443rn";

// production
$header .= "Host: ipnpb.paypal.com:443rn";      

$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";


// Ouverture du socket

// test
//$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

// production
$fp = fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30);

// s'il y a une erreur lors de l'ouverture du socket
if (!$fp) {
  // on s'envoie un mail pour être informé de l'erreur
  $msg = 'Erreur de socket, l\'url n\'a pas pu être ouverte';
  mail('payments@monmail.fr', 'erreur socket', $msg);
}

else {
  // on post la requête de vérification
  fputs ($fp, $header . $req);

  // créé une boucle tant qu'on est pas arrivé à la fin du fichier
  while (!feof($fp)) {
    // lit la réponse de paypal
    $res = fgets ($fp, 1024);

    // si paypal répond VERIFIED,
    // tout s'est bien déroulé et on peut procéder à nos traitements
    if (strcmp ($res, 'VERIFIED') == 0) {
      // type de transaction
      // $_POST['txn_type']

      // mail du compte paypal à qui est destiné le paiement
      // $_POST['receiver_email']

      // montant
      // $_POST['mc_gross']

      // id de la transaction
      // $_POST['txn_id']

      // champ personnalisé
      // $_POST['custom']
    }

    // si la transaction est invalide
    else if (strcmp ($res, 'INVALID') == 0) {
      // on s'envoie un mail pour être informé de l'erreur
      $msg = 'Message de l\'IPN : '.$res;
      mail('payments@monmail.fr', 'erreur IPN', $msg);
    }
  }  

  fclose ($fp);
}

Il y a beaucoup beaucoup de variables disponibles. Il est toujours utile de faire un foreach de $_POST et de logger le résultat ou de se l’envoyer par mail pour voir ce qu’il contient. Il va aussi vous falloir jouer un peu avec le simulateur de messages IPN. Cependant, le simulateur n’est pas parfaitement complet, en effet, il n’offre pas toutes les possibilités, par exemple les paiements récurrents n’y figurent pas… Il faudra donc finir par se faire quelques tests “réels” en s’envoyant de vrais paiements puis en se remboursant entre deux vrais comptes Paypal. Enfin, face à la richesse des variables et des infos, il vous sera bien utile de jeter un œil à la doc qui regroupe les différentes variables IPN.

Par ailleurs, je souligne l’intérêt de la variable custom, qui permet par exemple, de faire passer l’id d’un membre et d’ainsi créditer son compte du paiement. Celle-ci se transmet très facilement, par exemple via les boutons html. Notons néanmoins qu’elle ne permet du coup pas le chiffrement du boutons :

<input type="hidden" name="custom" value="2">

À propos du chiffrement, sachez que Paypal permet de chiffrer les boutons HTML; Ils ne sont ainsi pas modifiable dans le code de la page. Je préfère pour ma part les boutons non chiffrés (avec une validation à posteriori des montants etc.) car on peut directement les modifier côté serveur ou même directement en javascript. J’ai remarqué que par défaut Paypal enregistre les boutons si vous êtes connecté. Déconnectez-vous avant tout puis rendez-vous sur la page de création de bouton.

Enfin, une fois votre script en place, vous devez configurer votre serveur web pour qu’il soit accessible via une url particulière. Ensuite il faut vous connecter à votre compte paypal et aller à Mes préférences > mes ventes > notifications instantanées de paiement, pour configurer l’url auquel paypal doit notifier votre site.

interface de configuration de l'ipn paypal
Page de configuration de l’IPN

Je vous souhaite bien entendu une bonne mise en place, et par la suite, de recevoir beaucoup de paiements !

– Commentaires

Rejoignez la discussion !

Vous pouvez utiliser Markdown pour les liens [ancre de lien](url), la mise en *italique* et en **gras**. Enfin pour le code, vous pouvez utiliser la syntaxe `inline` et la syntaxe bloc

```
ceci est un bloc
de code
```