Novembre 2014

CKPaypal - Plugin Paypal pour CKEditor

Ce plugin pour CKEditor permet d'ajouter des boutons Paypal sur votre site. Il est particulièrement facile d'utilisation. Grâce à lui vous pourrez vendre des produits sur votre site sans avoir besoin de créer une boutique en ligne. CKPaypal est gratuit sous licence MIT.

CKPaypal permet d'insérer autant de boutons que vous le souhaitez. Les boutons suivants sont disponibles :

  • Acheter,
  • Ajouter au panier,
  • Voir le panier,
  • Faire un don,
  • S'abonner.

Bouton CKPaypal dans CKEditor

Télécharger le plugin ici ou sur GitHub.

Extraire le dossier de l'archive et l'installer dans le dossier plugins de CKEditor.

Ouvrir le fichier de configuration config.js de CKEditor. Le modifier en vous inspirant de ceci :

config.extraPlugins='ckpaypal'; // si plusieurs : 'a,b,c'
config.extraAllowedContent='input[*](ckpaypal)';
 
// Ajouter éventuellement 'ckpaypal' à la liste des boutons.

Dans le dossier ckpaypal, ouvrir ckpaypalConfig.js, le fichier de configuration du plugin. Modifier tous les éléments suivant les indications données à chaque ligne. Ce fichier permet de gagner du temps lorsque l'on ajoute un bouton Paypal ; de nombreux champs étant déjà renseignés.

Si vous souhaitez utiliser le fichier IPN, copier le à un endroit plus pratique comme par exemple le dossier de votre thème.

Vous êtes dans la partie création de pages de votre CMS. Placer le curseur à l'endroit où vous souhaitez insérer un bouton Paypal. Cliquez sur ckpaypal png.

CKPaypal - formulaire de création du bouton Paypal

Choisissez le type de bouton que vous souhaitez. Des champs disparaissent ou apparaissent suivant le type de bouton.

Si vous avez correctement renseigné le fichier de configuration, votre adresse email doit déjà s'afficher, ainsi que la monnaie, le taux de TVA et le style des boutons.

Attention, par défaut, le prix que vous entrez est Hors Taxe. La TVA, si elle est indiquée, s'ajoute au prix. Si cette méthode ne vous convient pas, vous pouvez ne pas mettre de TVA ou bien mettre paypalTaxIncl=1 dans le fichier de configuration. Dans ce dernier cas, la taxe est retirée du prix TTC que vous entrez. Lorsque Paypal la rajoute, vous retombez sur le prix initial mais parfois, avec un écart de plus ou moins 1 centime (arrondi imposé). Ce n'est pas donc pas parfait.

Sur votre page, une info-bulle vous rappelle les éléments du bouton :

CKPaypal - affichage du bouton dans l'éditeur

Le fichier IPN a deux fonctions principales :

  • Sauvegarder les ventes (dons, abonnements...) effectués avec vos boutons Paypal ;
  • Interroger Paypal pour vérifier que vos ventes sont bien réelles et qu'elles ne proviennent pas d'un script malicieux vous faisant croire à un achat.

Lorsque la vente est validée, Paypal envoie les données de la vente sur votre fichier IPN. Celui-ci appelle Paypal avec ces données. Si Paypal répond OK, la vente est confirmée et les éléments sont sauvegardés sur le serveur. Un mail peut vous être envoyé.

Un fichier "générique" a été réalisé avec le plugin. Il doit être adapté en fonction de votre configuration. Pour faire simple, nous allons stocker les données au format JSON. Elles pourront être stockées dans un fichier ou dans un table MySQL. Le fichier ressemble à ceci :

$hostPaypal = 'www.paypal.com'; // ADD sandbox if you need
$urlPaypal = 'https://www.paypal.com'; // ADD sandbox if you need
$req = 'cmd=_notify-validate';
foreach($_POST as $k=>$v){$req .= "&$k=$v";}
$header = "POST /cgi-bin/webscr HTTP/1.1rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rn";
$header .= "Host: ".$hostPaypal."rn";
$header .= "Connection: closernrn";
if(function_exists('openssl_open')) {$fp=fsockopen('ssl://'.$hostPaypal,443,$errno,$errstr,30); $type="_SSL";}
else {$fp=fsockopen($hostPaypal,80,$errno,$errstr,30); $type="_HTTP";}
if(!$fp)
    { //error connecting to paypal
    }
else
    { //successful connection
    $written=fwrite($fp,$header.$req);
    if ($written)
        {
        $res=stream_get_contents($fp);
        fclose($fp);
        if(strpos($res, "VERIFIED")!==false)
            { //insert order into database
            if($_POST['payment_status']=="Completed")
                {
                // check txn_id in my database : new payment ?
                // see function VerifIXNID() in the bottom of this script
                if(VerifIXNID($_POST['txn_id'])==0)
                    { // check receiver_email : is it me ?
                    if($myemail==$_POST['receiver_email'])
                        { // OK
                        }
                    else
                        { // bad email
                        }
                    }
                else
                    { // already payed
                    }
                }
            else
                { // Payment statut not good
                }
            }
        else if(strpos($res, "INVALID")!==false)
            { //insert into DB in a table for bad payments for you to process later
            }
        }
    }
//
function VerifIXNID($txn_id)
    { // check if txn_id already in database
    // write a test in your database (MySQL, XML, JSON, TXT ...)
    return 0; // 0:OK - 1:already in base
    }

Le fonctionnement est le suivant :

  • Ligne 4 : Récupération de toutes les données. Réécriture au format GET (URL) pour renvoi vers Paypal.
  • Ligne 10 : Ouverture d'une connexion sécurisée avec Paypal (ou non sécurisée en 11).
  • Ligne 17 : Envoi des données vers Paypal pour vérification.
  • Ligne 19 : Réponse de Paypal.
  • Ligne 28 : La réponse est OK mais est-ce bien une nouvelle vente ? Vérification dans ma base de données.
  • Ligne 31 : Tout est OK. On peut enregistrer cette vente.

On va commencer par enregistrer les données au format JSON pour les archiver ensuite dans un fichier ou une table MySQL. Ligne 10, créer le JSON :

// On ajoute une date format informatique et une valeur de traitement
$kv=array("time" => time(), "treated" => 0); // pour MySQL : $kv=array();
foreach($_POST as $k=>$v)
    {
    $req .= "&$k=$v";
    $kv[$k] = $v;
    }
$ipn = json_encode($kv);

Tout est OK, on sauvegarde les données dans un fichier ou dans une table MySQL. Ligne 31, archiver les données :

// Exemple pour un fichier
if($myemail==$_POST['receiver_email'])
    { // OK
    file_put_contents('chemin/vers/mes_ventes/'.$_POST['txn_id'].'.json',$ipn);
    }
     
// Exemple pour une table MySQL "mes_ventes" à 5 colonnes :
// ID,txn_id(VARCHAR),date(INT),vente(TEXT),traitement(TINYINT)
if($myemail==$_POST['receiver_email'])
    { // OK
    // 1. Connexion MySQL (remplacer par vos éléments de connexion)
    $li = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    // 2. Insertion des données dans la table "mes_ventes"
    $li->query("INSERT INTO mes_ventes (txn_id,date,vente,traitement)
        VALUES ($kv['txn_id']time(),$ipn,0)");
    // 3. Deconnexion MySql
    $li->close();
    }

Enfin, il faut créer la fonction VerifIXNID pour voir si l'opération n'a pas déjà été effectuée :

function VerifIXNID($txn_id)
    {
    // Exemple pour un fichier
    $a=array();
    if ($h=opendir('chemin/vers/mes_ventes/'))
        {
        while (($file=readdir($h))!==false)
            {
            if($file==$txn_id.'.json') {closedir($h); return 1;}
            }
        closedir($h);
        }
    return 0;
 
    // Exemple pour une table MySQL
    // 1. Connexion MySQL (remplacer par vos éléments de connexion)
    $li = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    // 2. Insertion des données dans la table "mes_ventes"
    $q=$li->query("SELECT txn_id FROM mes_ventes WHERE txn_id='".$txn_id."' ");
    // 3. Deconnexion MySql
    $li->close();
    if($q) return 1;
    return 0;
    }

Merci de nous contacter pour signaler les dysfonctionnements.