Prestashop 1.7 : Créer un module de paiement

Ce tutoriel est compatible avec les versions de Prestashop suivantes :
1.7 +
Cet article est assez ancien, malgré toute l'attention que j' apporte à mes contenus il est possible que celui-ci ne soit plus d'actualité.
N'hésitez pas à me le signaler si nécessaire via le formulaire de contact.

La version 1.7 de prestashop introduit des changements dans la création des modules de paiement.
De mon point de vue cela simplifie vraiment la création de modules de paiement qui deviennent faciles et rapides à coder 🙂

C’est parti pour voir cela en détails et en exemple  via la création d’un module de paiement hhPayment.

use PrestaShop\PrestaShop\Core\Payment\PaymentOption;
 
if (!defined('_PS_VERSION_')) {
    exit;
}
 
class HhPayment extends PaymentModule
{
 
    public function __construct()
    {
        $this->author    = 'hhennes';
        $this->name      = 'hhpayment';
        $this->tab       = 'payment_gateways';
        $this->version   = '0.1.0';
        $this->bootstrap = true;
        parent::__construct();
 
        $this->displayName = $this->l('HH Payment');
        $this->description = $this->l('HH sample Payment for PS 1.7');
    }
 
    public function install()
    {
        if (!parent::install() 
            || !$this->registerHook('paymentOptions')
            || !$this->registerHook('paymentReturn')
            ) {
            return false;
        }
        return true;
    }
}

Comme vous pouvez le voir ci-dessus, le module doit toujours étendre la classe PaymentModule mais vous noterez également l’utilisation de la classe PaymentOption.
Ansi que du nouveau hook paymentOptions.
C’est dans celui-ci que se situe toute la nouveauté !

La classe PaymentOption vous permets de gérer facilement l’affichage et les actions de votre module en quelques lignes.
Le tunnel de commande a été entièrement revu dans cette version 1.7 de prestashop ( inpiré de magento 1 au passage ^^ ) , c’est plus cadré et plus propre

Voici un aperçu de l’affichage d’une méthode, ainsi que des différentes zones dans le template par défaut.
Le template utilisé étant situé dans /themes/classic/checkout/_partials/steps/payment.tpl

Prestashop paiement

 

Voici la liste des méthodes utiles sur cette classe et leur utilisation

  • setCallToActionText : Défini le texte de la méthode de paiement (1) / Obligatoire
  • setAdditionalInformation : Défini les informations additionnelles de la méthode (3) / Optionnel
  • setLogo : Défini le logo de la méthode (2) / Optionnel
  • setAction : Défini le controller à appeler pour valider le paiement (Non visible ) / Obligatoire sauf si utilisation de setForm
  • setInputs : Permets d’ajouter des champs de formulaires, idéalement de type hidden (4)  / Optionnel
  • setForm : Permets d’utiliser un formulaire spécifique au module, si utilisé , les fonctions setInputs et setAction n’ont aucun effet ( ) / Optionnel
  • setModuleName : Nom  du module ( Non visible ) / Obligatoire
  • setBinary : Défini si le module utilise un binaire pour générer le formulaire, c’est le cas pour atos par exemple, dans ce cas il faut également greffer votre module sur le hook displayPaymentByBinaries / Optionnel

 

Exemples :

voici comment créer une option de paiement de type « Chèque »

  $standardPayment = new PaymentOption();
  //Inputs supplémentaires (utilisé idéalement pour des champs cachés )
        $inputs = [
            [
                'name' => 'custom_hidden_value',
                'type' => 'hidden',
                'value' => '30'
            ],
            [
                'name' => 'id_customer',
                'type' => 'hidden',
                'value' => $this->context->customer->id,
            ],
        ];
        $standardPayment->setModuleName($this->name)
                //Logo de paiement
                ->setLogo($this->context->link->getBaseLink().'/modules/hhpayment/views/img/logo.png')
                ->setInputs($inputs)
                //->setBinary() Utilisé si une éxécution de binaire est nécessaires ( module atos par ex )
                //Texte de description
                ->setCallToActionText($this->l('Payment in x days'))
                ->setAction($this->context->link->getModuleLink($this->name, 'validation', array(), true))
                //Texte informatif supplémentaire
                ->setAdditionalInformation($this->fetch('module:hhpayment/views/templates/hook/displayPayment.tpl'));

Avec le contenu suivant dans  le tpl par exemple

  <div class="row">
 <div class="col-xs-12 col-md-12">
 <p class="payment-module-description">
 {l s='Your order will be automaticaly payed with your account.' mod='hhpayment'}
 </p>
 </div>
</div>

Un autre exemple de type « CB » qui renvoie l’utilisateur vers une api externe.

 //Variables pour paiement API
        //Variables pour paiement API
        $this->smarty->assign(
            [
                'payment_url' => Configuration::get('PAYMENT_API_URL'),
                'success_url' => Configuration::get('PAYMENT_API_URL_SUCESS'),
                'error_url' => Configuration::get('PAYMENT_API_URL_ERROR'),
                'id_cart' => $this->context->cart->id,
                'cart_total' => $this->context->cart->getOrderTotal(true,
                    Cart::BOTH),
                'id_customer' => $this->context->cart->id_customer,
            ]
        );
 
        $apiPayement = new PaymentOption();
        $apiPayement->setModuleName($this->name)
                ->setCallToActionText($this->l('HH Sample payement module (like CB )'))
                //Définition d'un formulaire personnalisé
                ->setForm($this->fetch('module:hhpayment/views/templates/hook/payment_api_form.tpl'))
                ->setAdditionalInformation($this->fetch('module:hhpayment/views/templates/hook/displayPayment.tpl'));

Avec le contenu suivant pour le formulaire :

<form method="post" action="{$payment_url}">
<div class="form-group">
{* choix du mode de carte *}
{l s='please choose your card type' mod='hhpayment'}
<div class="radio">
<label>
<input type="radio" name="cb_type" value="mastercard" id="cb_type1" checked="checked" /> Mastercard
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="cb_type" id="cb_type2" value="visa"/> Visa
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="cb_type" id="cb_type3" value="cb"/> CB
</label>
</div>
</div>
{* Informations pour l'api *}
<input type="hidden" name="success_url" value="{$success_url}" />
<input type="hidden" name="error_url" value="{$error_url}" />
<input type="hidden" name="id_cart" value="{$id_cart}" />
<input type="hidden" name="cart_total" value="{$cart_total}" />
<input type="hidden" name="id_customer" value="{$id_customer}" />
</form>

 

L’affichage du message de retour reste toujours géré via le hook paymentReturn.

/**
     * Affichage du message de confirmation de la commande
     * @param type $params
     * @return type
     */
    public function hookDisplayPaymentReturn($params) 
    {
        if (!$this->active) {
            return;
        }
 
        $this->smarty->assign(
            $this->getTemplateVars()
            );
        return $this->fetch('module:hhpayment/views/templates/hook/payment_return.tpl');
    }

Pour voir le code de démo complet vous pouvez télécharger mon module de démo, qui inclue les différents tps ainsi qu’une configuration basique dans l’administration.

hhpayment

Nous avons à présent fait le tour du fonctionnement des modules de paiement sur Prestashop 1.7 🙂

58 réflexions sur “Prestashop 1.7 : Créer un module de paiement”

  1. Bonjour j’utilise le tuto pour créer un module de payement API externe
    quand je parametre l’url return succes de payement ça marche sur mon API mais ça ne valide pas la commande dans la zone admin

  2. Bjr est-ce que je peux avoir la procedure d’utilisation de l’archive du module
    j’ai vu controller/front/api.php
    mais je vois pas PayementModule.php dans le module

    voila la fonction validator dans le controlleur api.php
    validateOrder((int)$cart->id, Configuration::get(‘PS_OS_PAYMENT’), $total, $this->module->displayName, null, array(), (int)$currency->id, false, $customer->secure_key);
    ===Comment le modifier====

    pour le « payement en x days » j’ai la confirmation dans la zone admin
    mais le payement a distance xa marche toujours pas
    Besoin d’aide

    1. Bonjour,

      Pour plus de clarté J’ai regroupé vos différents commentaires.
      Le code fourni ne se charge que de mettre à jour le statut de la commande dans prestashop.
      Concernant la remontée de l’information et son renvoi depuis son api, tout dépends de celle-ci. Je ne peux donc malheureusement pas vous fournir plus d’informations.

      Cordialement,
      Hervé

  3. Bonjour, bonsoir Comment puis-je changer l’email qui est envoyé quand le paiement est effectué?, C’est-à-dire, quand j’effectue le paiement, j’envoie le paiement accepté, je veux le changer pour l’email en attente

    1. Bonjour,

      Il faudrait changer le statut par défaut le commande lors de l’appel de la fonction validateOrder
      Ou sinon changer le wording de vos emails.

      Cordialement,
      Hervé

  4. Bonjour, j’ai suivi votre tuto et c’est cool.
    j’ai un soucis. le API externe que j’ai de ma banque demande l’envoie des informations en XML.
    cela m’amène à modifier le formulaire pour prendre receuillir les données de la CB du client et envoyer.
    Je suis bloqué. comment renseigner ces informations en XML et l’envoyer POST au paiement_Api_Url?
    Merci de me donner des pistes.

    1. Bonjour Maurice,

      Merci pour la citation, j’ai lu votre article qui est bien plus détaillé que celui-ci effectivement.
      Je ne suis pas allé aussi loin que vous dans mes explications.

      Cordialement,
      Hervé

  5. Merci pour votre réponse. En prenant pour model votre module de paiement j’ai pas retrouvé setAction(). Je ne maitrice pas trop tous les fichiers prestashop. Pouvez vous m’orienter SVP?
    Merci

  6. bonjour

    je trouve très utile et intéressant comme script j’ai installer le module et sa marche top !

    mais je tente de faire une modification de proposer seulement le paiement par carte de crédit et d’envoyer la commande vers la platforme VAD de ma banque (banque et carte algérienne)

    comment faire? disons que

    la page de paiement de la banque: http://www.bdl.dz

    et le nom de la carte CIB bleu et CIB gold

    merci d’avance

  7. bonjour

    j’ai reussi a opté seulement pour le paiement en CB

    j’ai meme modifier le nom des carte en CIB BLEU ET GOLD sur le fichier :
    payment_api_form

    voir exemple :

    {l s=’veuillez choisir votre type de carte de crédit’ mod=’hhpayment’}

    CIB BLEU

    CIB GOLD

    mais sur la page de paiement sur prestashop , j’ai toujours un message en anglai:

    Your will be redirected to payment api to confirm your order

    et les carte reste 3:
    visa, mastercard et cb

    alors que je désire proposer que deux carte cib bleu et cib gold

    que faire cher Monsieur

    merci d’avance 😉

    1. Bonjour,
      Le script fourni n’est pas clé en main et sers uniquement d’exemple.
      En fonction de votre banque et de ses contraintes il sera certainement nécessaire de modifier le formulaire pour envoyer les informations nécessaires vers une url que la banque vous aura fourni.

      Cordialement,

  8. Bonjour Hervé,
    J’utilise votre exemple de module de paiement. Ma question est de savoir quelle url dois-je retourner depuis ma gateway à mon site marchand pour lui confirmer que le paiement a été effectué ?

    1. Bonjour Will,
      Si vous regardez dans le zip fourni en fin d’article il y’a un controller Api qui traite cette problèmatique.
      Il faut donc renvoyer votre plateforme de paiement vers celui-ci.

    1. Je réponds tout de même au cas ou d’autres se posent la question 😉
      Le plus simple pour construire le lien est d’utiliser la classe Link pour récupérer le lien du controller du module

      Dans le contexte de votre module de paiement vous pouvez fournir le lien de retour caché comme un paramètre de formulaire.
      VIa un code du type
      $mylink = $this->context->link->getModuleLink('hhpayment',api');

  9. Bonjour,
    J’essaye de faire deux méthodes de paiement, paiement cache, ou simuler un crédit bancaire.
    Je n’arrive pas a adapter votre module dans mon cas.
    Le code de simulation est prêt, mais j’arrive a l’intégrer.
    Cordialement

  10. Bonjour, j’aime bien votre API.
    Je veux l’adapter au paiement mobile. j’ai un API de l’opérateur. Dans le guide de l’opérateur il est dit que le format de transmission est JSON.
    Comment fournir les informations à l’API dans ce cas?
    Merci

  11. Bonjour, je voudrais utiliser votre api pour realiser un paiement mobile : le mobile money.
    J’ai le code fourni par l’operateur de telephonie; seulement je ne sais pas où l’integrer.

    J’ai généré un module de paiement que j’edite en consulte le votre.Quand je remplace le formulaire contenu dans le fichier hhpaiement.tpl par celui fourni par l’opérateur. le module ne s’affiche comme moyen de paiement au moment de la validation.

    Mais lorsque j’integre le votre module, il s’installe normalement et propose les trois paiements decrits ci-dessus.

    MErci

    1. Bonjour,

      Cet article et ce module expliquent les mécaniques générales de fonctionnement d’un module de paiement.
      Cependant il n’est en aucun cas fonctionnel pour une implémentation spécifique.
      Dans un premier temps il est donc important de comprendre la logique Prestashop, avant de l’appliquer au code fourni par votre solution de paiement.

      Cordialement,
      Hervé

  12. Bonjour

    Merci pour votre module. il s’installe correctement. **
    Cependant, les moyens de paiement ne sont pas adéquats. *je voudrais ajouter le paiement mobile. Mobile Money

    L’operateur de telephonie fournit le code suivant :

    Le module que je suis en train de développer s’affiche dans le Gestionnaire de modules mais ne s’affiche pas au moment de réaliser le paiement contrairement à hhpaiement.

    Merci de m’avoir lu

  13. bonjour Merci pour ce tuto
    je suis debutant en prestashop, j’ai pu integré et modifier votre module en fonction de mon besoin, mais mon probleme est moi jai un seul Api, apres apres appeler l’APi et lui envoyé les informations comment revenir valider la commande

    1. Bonjour,

      Cela dépends de l’api de paiement que vous utilisez, je donc pas vous dire exactement.
      En règle générale il est possible de fournir une adresse de retour dans celle-ci ( via une configuration dans leur backoffice ou via l’envoi des informations dans les paramètres )

      Cordialement,
      Hervé

    1. Bonjour,
      Une fois la réponse de votre webservice parsée ( via un json_decode )
      Vous pouvez rediriger vers un controller comme le fichier « validation.php » de l’archive hhpayement et ainsi changer le statut de la commande vers son statut final.

      Cordialement,

  14. please comment integrer l’appel d’un api avec curl dans prestashop? ou exactement injecter le code curl dans hhpayment merci
    voici un exemple de code que je voudrais intergrer dans hhpayment
    quand je mets tout simplement url dans le back office ca me demande l’authentification d’ou j’ai besoin d’utiliser curl
    mais please je ne sais pas comment l’intergrer
    merci
    $url = ‘https://android.googleapis.com/gcm/send’;
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_POST, true );
    curl_setopt( $ch, CURLOPT_HTTPHEADER, array(‘Content-Type: text/xml’));
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, « here » );
    $result = curl_exec($ch);
    curl_close($ch);

    1. Bonjour,

      En partant du principe que vous avez téléchargé l’archive présente dans cet article.
      Vous pouvez utiliser le controller front api.php du fichier controllers/front/api.php

      Dans celui-ci avant le contenu déjà présent dans la fonction postprocess, vous pouvez effectuer votre appel à l’api et lui envoyer les éléments qui ont été définis dans le formulaire.
      Je ne connais pas du tout le fonctionnement de votre api, mais si ensuite l’appel curl suffit à récupérer une réponse de l’acceptation du paiement ou non, vous pouvez ensuite en fonction appliquer la réponse ok ou ko pour procéder à la validation de la commande.

      Cet article est assez basique car il donne uniquement une trame, chaque implémentation dépendra ensuite de l’api qui est en face.

      Cordialement,
      Hervé

  15. grand merci pour le temps que tu prends pour repondre
    j’ai crée un formulaire dans le fichier payment_api_form.tpl
    pour pouvoir recuperer le numero entrer par l’utilisateur et l’operateur choisi . j’ai place le function callApi dans le fichier api.php
    stp ou est ce que je peux ensuite l’appeler ?
    quand je vais dams le cote admin et que j’insere l’url ca me dit authentification failed
    donc j’ai besoin d’appeler l’url avec le header , boody et l’identification
    voici le code ajoute dans le fichier api comme recomende merci

    <?php
    class hhpaymentapiModuleFrontController extends ModuleFrontController {

    /**
    * call api
    */
    function ApiCall(){

    $accountNumber = $_POST[‘accountNumber’]; //j’essaye de recuperer cette variable de payment_a[i_form.tpl
    $operator = $_POST[‘operator’];
    $paymentType = « succes »;
    $amount = $total = (float)$cart->getOrderTotal(true, Cart::BOTH);

    $array = array(
    ‘accountNumber’ => $accountNumber,
    ‘amount’ => $amount,
    ‘operator’ => $operator,
    « paymentType » => $paymentType
    );

    try {
    //code…
    $body = json_encode($array);
    } catch (\Throwable $th) {
    throw $th;
    }

    //The URL of the resource that is protected by Basic HTTP Authentication.
    $url = ‘https://XXXXXXXXXXXXXXXXX/api/processPayment’;

    //Your username.
    $username = ‘klaus’;

    //Your password.
    $password = ‘3421’;

    //Initiate cURL.
    $ch = curl_init($url);
    //Specify the username and password using the CURLOPT_USERPWD option.
    curl_setopt($ch, CURLOPT_USERPWD, $username . « : » . $password);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    //curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    ‘Content-Type: application/json’,
    ‘Content-Length: ‘ . strlen($body))
    );

    //Tell cURL to return the output as a string instead
    //of dumping it to the browser.
    //curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    //Execute the cURL request.
    $response = curl_exec($ch);
    //Check for errors.

    if (curl_errno($ch)) {
    //If an error occured, throw an Exception.
    throw new Exception(curl_error($ch));
    }

    curl_close($ch);
    //Print out the response.
    return $response;
    }
    /**
    * Retours de l’api de paiement
    */
    public function postProcess()
    {
    //Contenu du controller initial
    }
    }

  16. voici l’erreur que j’obtiens je ne pense pas que l’execution arrive
    jusqu’a la page api.php

    il execute juste l’url inserer a partir du back office

    « status »:401, »displayMessage »: »AUTHENTICATION_REQUIRED », »detailledMessage »: »AUTHENTICATION_REQUIRED », »exceptionId »: »4863fc0f-185b-46b7-a44b-4c318421bc04″}

    STP pouvez vous regarder le code que j’ai inserer dans le fichier api.php et me dire si c’est correct et si oui comment le faire executer.
    merci

  17. stp j’ai inserer le code dans api.php comme vous m’avez conseille mais seulement je ne sais pas comment l’appeler ou le faire executer je l’ai mise dans une function callApi()
    ou exactement appeler cette function? toujours dans api.php ou alors je dois l’appeler dans un autre fichier ?

    1. Bonjour,

      Comme précisé dans ma précédente réponse, votre code d’appel à l’api est à mettre DANS le contenu de la fonction postProcess.
      Car c’est la fonction qui est appellée pour le traitement des variables posts dans les controllers prestashop.

      Cordialement,
      Hervé

  18. bonjour
    je l’ai inserer mais elle ne s’execute pas.
    comment l’executer ? quand je mets le code dans postProcces et ne met aucun lien dans le chanp Payment api url du back office rien ne se passe
    et lorsque je mets un un lien dans le champ Payment api url du back office c’est ce lien qui est appeler

    alors comment appeler le code inserer dans api.php lorsque je clique sur le bottons commande
    merci et encore grand merci pour le temps que vous prenez pour me repondre Mr herve

  19. bonjour
    je vous remercie pour ce module 🙂

    voila je l’ai bien modifier pour permettre au client d’effectué des paiement par carte de crédit sur notre banque via un contrat VAD

    le client sera redirigé vers l’url de la banque motionné sur le champs admin : Payment api url :exemple http://bdl.dz

    sur cette dernière le client va effectué son paiement.

    la banque me demande une url de retour de confirmation de paiement et je pense c’est Payment api success url …

    je pense c’est a ce moment que la commande sera enregistré avec un eta de commande?

    j’ai modifier les champs comme suit
    :

    {* Informations pour l’api *}

    j’espere pouvoir avoir un ptite aide

    merci

  20. Bonjour

    j’ai toujours le même problème

    pouvez vous me donner un coup de main
    j’ai créer une page success.php
    avec des champs hidden qui contienent toutes les données pour validé et enregistré la commande qui pointe directement vers le validate

    mais quand je teste

    j’obtiens se message d’erreur :

    Fatal error: Uncaught Error: Class ‘ModuleFrontController’ not found in /homepages/21/d826055477/htdocs/modules/hhpayment/validation.php:28 Stack trace: #0 {main} thrown in /homepages/21/d826055477/htdocs/modules/hhpayment/validation.php on line 28

    pouvez vous me donnée un exemple comment avez vous appeler ou lié votre page api payement a validate merci

    je galère depuis 2 semaines

    merci d’avance

  21. Bonjour Hervé. Je suis débutant en prestashop mais j’ai compris votre module. Mais je veux faire un appel à une API externe avec du CURL. Les appels CURL je maitrise mais je ne sais pas ou mettre mon code d’appel CURL quand le client choisi les options de paiement quil faut et la ou mettre l’appel curl de retour avant de changer l’état de la commande.

    1. Bonjour,
      Dans ce cas si vous prenez l’exemple avec le formulaire.
      Il vous suffit de renseigner dans l’url de paiement api l’url d’un controller prestashop
      ( Vous le récupérer dynamiquement dans le php via un code du type $this->context->link->getModuleLink($this->name, ‘validation’, array(), true) )
      Ensuite dans votre controller vous faîtes votre appel curl et vos traitements.

  22. Bonjour, tout d’abord merci pour votre tuto

    J’ai bien compris votre tuto, et je l’ai modifié, j’ai un petit problème

    Dans mon cas je dois envois les paramètres a ma banque via une URL X elle me retourne un code Json qui contient une URL, et je dois rediriger les clients a cette URL

    Jusqu’à maintenant j’ai mis l’URL X comme payment_url, j’ai comme réponse code json(avec deux paramètres code_erreur et formUrl)

    Comment puis-je récupérer la réponse de ma banque(plus exactement formUrl) afin de rediriger le clienta cet URL?

    1. Bonjour,

      Dans votre cas je partirais sur le fonctionnement suivant :
      Comme pour le mode cb envoi vers un controller prestashop spécifique à votre module.
      Et c’est sur celui-ci que vous faites votre appel à l’api de la banque en ajax ( via un javascript de votre module )
      Lorsque vous recevez l’url de la banque vous redirigez ensuite le client vers celle-ci.

      Cordialement,
      Hervé

  23. Bonjour je suis tout nouveau sur prestashop, l’explication me semble très claire mais j’essaye d’appliquer des frais pour l’utilisation du moyen de paiement, pourriez-vous m’aider un peu sur la partie du code à modifier …

Répondre à Radia Annuler la réponse

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