> For the complete documentation index, see [llms.txt](https://docs.prestashop-project.org/1-4-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.prestashop-project.org/1-4-documentation/english-documentation/developer-guide/developer-tutorials/creating-your-own-payment-module.md).

# Creating your own payment module

### The rationale <a href="#creatingyourownpaymentmodule-therationale" id="creatingyourownpaymentmodule-therationale"></a>

PrestaShop provides a seller (and his customers) with many ways to handle payment for goods, thanks to the modules installed by default. PayPal, Hipay or Authorize.Net are just a few of the modules that are a click away from activation.

Still, not all payment solutions are available by default, and if you do not find the one you need on the [PrestaShop Addons](http://addons.prestashop.com/en/) website, you might have to work one out yourself – and why not, sell it to other shop owners on PrestaShop Addons!

This tutorial was created to help you with this task.

### Creating a basic module <a href="#creatingyourownpaymentmodule-creatingabasicmodule" id="creatingyourownpaymentmodule-creatingabasicmodule"></a>

A payment module is just like any other PrestaShop module, so you won't be surprised by the first few methods – except for the fact that the main class does not extend the `Module` object, but the `PaymentModule` one. Apart from that, the `__construct()`, `install()` and `uninstall()` methods are mostly as described in the Developer Guide.**mypayment.php**

| `class` `MyPayment extends` `PaymentModule{  public` `function` `__construct()  {    $this->name = 'mypayment';    $this->tab = 'payments_gateways';    $this->version = 0.1;    $this->author = 'PrestaShop';` `$this->currencies = true;    $this->currencies_mode = 'radio';` `parent::__construct();` `$this->displayName = $this->l('Hipay');    $this->description = $this->l('Hipay API implementation');` `if` `(!sizeof(Currency::checkPaymentCurrencies( $this->id)))      $this->warning = $this->l('No currency set for this module');  }}` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

You'll notice a few lines that are not present in the module tutorial from the Developer Guide:

* `$this->currencies = true;`: XXX.
* `$this->currencies_mode = 'radio';`: Indicates the type of restrictions the module should answer to. If 'radio', then the module can only apply to one currency; if checkbox, then it can apply to any number of currencies.
* `if (!sizeof(Currency::checkPaymentCurrencies($this->id)))`: checks whether XXX.

The `install()` method is where you set the different values pertaining to your module, either the needed constants, or filling up the database.**mypayment.php**

| `public` `function` `install(){        if` `(!parent::install() OR !$this->registerHook('payment') OR      !$this->registerHook('paymentReturn') OR      !Configuration::updateValue('MYPAYMENT_MERCHANT_ID', '32029e6d2bcb25cab87232d92c7c634c') OR      !Configuration::updateValue('MYPAYMENT_MERCHANT_KEY', '8790eb2d0fec01c544d57e839b1b3b62') OR      !Configuration::updateValue('MYPAYMENT_NO_SHIPPING', '0'))    return` `false;  return` `true;}` |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

All of these values should be discarded by the `uninstall()` method:**mypayment.php**

| `public` `function` `uninstall(){  return` `(parent::uninstall() AND    Configuration::deleteByName('MYPAYMENT_MERCHANT_ID') AND    Configuration::deleteByName('MYPAYMENT_MERCHANT_KEY') AND    Configuration::deleteByName('MYPAYMENT_NO_SHIPPING') );}` |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

This are the basics. Not any PrestaShop module should be released without these methods.\
Note that these are sample configuration values; you should use only the ones necessary to your provider's needs.

Now let's jump to the specifics.

### Building the hooks <a href="#creatingyourownpaymentmodule-buildingthehooks" id="creatingyourownpaymentmodule-buildingthehooks"></a>

As you might know already, PrestaShop's module framework is based on a system of hooks. If you are not aware of what hooks are, read Julien Breux's [Understanding and using hooks](http://doc.prestashop.com/display/PS14/Understanding+and+using+hooks).

Every PrestaShop payment modules should implement a set of predefined methods, which are called by hooks that are triggered during the payment process (front-office) or as part of the admin interface (back-office).

#### hookPayment() hook <a href="#creatingyourownpaymentmodule-hookpayment-hook" id="creatingyourownpaymentmodule-hookpayment-hook"></a>

This might be the most important hook, as it is always called – namely, when displaying the payment option in the check-out process. It is also the entry point to whole payment process: exploring `hookPayment` will take us through many PHP and TPL files, each serving a specific purpose.**mypayment.php**

| `public` `function` `hookPayment($params){  if` `(!$this->active)    return` `;` `global` `$smarty;` `$smarty->assign(array(    'this_path'` `=> $this->_path,    'this_path_ssl'` `=> Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/'` `)    );  return` `$this->display(__FILE__, 'payment.tpl');}` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

The whole point of this hook is to display the `payment.tpl` template at the right location on the frontpage (namely, the payment method choosing page).

**payment.tpl file**

Our `hookPayment()` code calls for a template file which is very simple, but should match a few essential points.

Here's a a sample template file:**payment.tpl**

| `<p class="payment_module">  <a href="{$this_path_ssl}validation.php"` `title="{l s='Pay with MyPayment module' mod='mypayment'}">    <img src="{$this_path}mypayment.gif"` `alt="{l s='Pay with MyPayment module' mod='mypayment'}"` `style="float:left;"` `/>    <br />{l s='Pay with MyPayment module'` `mod='mypayment'}    <br />{l s='A great way to pay online!'` `mod='mypayment'}    <br style="clear:both;"` `/>  </a></p>` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

Here is what PrestaShop needs in that template file:

* wrapper `<P>` tag with the `"payment_module"` class.
* a link to a PHP file, which role is to validate the payment method choice (recommended: `validation.php` or `payment.php`).
* HTML elements should feature a `mod` attribute, with the module's name as only value
* (optional) an image, ideally the payment provider's logo, making it easier to make a decision. Must be left aligned (`style="float:left;"`), and with size 86\*49.
* {optional) at most two lines of description.

This template merely creates a link to `validation.php`, which is the first real step in putting your payment method into the payment process.

**The payment method validation file: validation.php**

In this step of the payment process, the customer has chosen his mean of payment. Now we need to display a form to obtain his payment details – typically, his credit card details, unless the process is different for the payment gateway provider.**validation.php**

| `<?php` `include(dirname(__FILE__).'/../../config/config.inc.php');include(dirname(__FILE__).'/../../header.php');include(dirname(__FILE__).'/mypayment.php');` `if` `(!$cookie->isLogged())  Tools::redirect('authentication.php?back=order.php');` `$mypayment= new` `MyPayment();echo` `$mypayment->execPayment($cart);` `include_once(dirname(__FILE__).'/../../footer.php');` `?>` |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

The first lines are files which contain methods that we need for the process to continue:

* `config.inc.php` is PrestaShop's own configuration, with important data, such as the MySQL access identifiers.
* `header.php` and `footer.php` are the theme's header and footer file, which will build the theme for us around the payment form.
* `mypayment.php` is our own module's PHP file. This way, we can easily use methods that were define in that file.

We must make sure that the user is already logged, and if not, redirect him to the authentication form.

Once the user is logged with certainty, we can trigger the needed function, `execPayment()`, which is defined in the main module file. The `$cart` variable is handled by PrestaShop.

Here is a sample `execPayment()` method:**mypayment.php**

| `public` `function` `execPayment($cart){  if` `(!$this->active)    return;` `global` `$cookie, $smarty;` `$smarty->assign(array(    'this_path'` `=> $this->_path,    'this_path_ssl'` `=> (Configuration::get('PS_SSL_ENABLED')?'https://':'http://')      .htmlspecialchars($_SERVER['HTTP_HOST'], ENT_COMPAT,'UTF-8')      .__PS_BASE_URI__.'modules/'.$this->name.'/')  );` `return` `$this->display(__FILE__, 'payment_execution.tpl');}` |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

The point of `execPayment()` is to:

* assert that the module is indeed active.
* assign values to the Smarty engine, pertaining to the module's path.
* display the `payment_execution.tpl` template file.

**payment\_execution.tpl**

#### hookPaymentReturn() hook <a href="#creatingyourownpaymentmodule-hookpaymentreturn-hook" id="creatingyourownpaymentmodule-hookpaymentreturn-hook"></a>

Another essential hook, `hookPaymentReturn()` is called

| `public` `function` `hookPaymentReturn($params){  if` `(!$this->active)    return` `;` `return` `$this->display(__FILE__, 'confirmation.tpl');}` |
| ------------------------------------------------------------------------------------------------------------------------------------------------ |

#### getContent() hook <a href="#creatingyourownpaymentmodule-getcontent-hook" id="creatingyourownpaymentmodule-getcontent-hook"></a>

The `getContent()` hook is specifically triggered when the user clicks on the module's "Configure" link. Thus, the method should feature all the interface and methods calls necessary to have the user configure the payment gateway properly.\
If your module doesn't need configuring, then this method is not necessary.

\*\*\*

Basic modules can feature the whole configuration page within the `getContent()` method. For more complexes pages, it is recommended to separate the configuration code to another page with its own object and methods. for instance :**mypayment.php**

| `public` `function` `getContent(){  include(_PS_MODULE_DIR_.$this->name.'/settings.php');  $mypaymentSettings` `= new` `MyPaymentSettings();  return` `$mypaymentSettings->home();}` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

#### execPayment() hook <a href="#creatingyourownpaymentmodule-execpayment-hook" id="creatingyourownpaymentmodule-execpayment-hook"></a>

#### hookOrderConfirmation() hook <a href="#creatingyourownpaymentmodule-hookorderconfirmation-hook" id="creatingyourownpaymentmodule-hookorderconfirmation-hook"></a>

#### preparePayment() hook <a href="#creatingyourownpaymentmodule-preparepayment-hook" id="creatingyourownpaymentmodule-preparepayment-hook"></a>

#### validate() hook <a href="#creatingyourownpaymentmodule-validate-hook" id="creatingyourownpaymentmodule-validate-hook"></a>
