Introduction
In this article we will show you how to add a settings form for a payment method.
Implementation
We start with creating an empty module with developer ID XCExample and module ID Payment.
Here is the file main.yaml
of the demo module at the path classes/XLite/Module/XCExample/Payment/main.yaml
version: 5.4.0.0
type: payment
authorName: 'X-Cart examples'
moduleName: 'Example "Payment" module'
description: 'Example "Payment" module'
minorRequiredCoreVersion: 0
dependsOn: { }
incompatibleWith: { }
skins: { }
showSettingsForm: false
canDisable: true
Specifying type:payment
is required so that X-Cart can understand that it is a payment module.
We create the
<X-Cart>/payment.php
file with the following code there:<?php
$location = $_POST['returnURL'] . '&transactionID=' . $_POST['transactionID'] . '&status=Paid';
header('Location: ' . $location);
die();This file will represent our self-designed payment gateway.
We create the
<X-Cart>/classes/XLite/Module/XCExample/Payment/Model/Payment/Processor/DemoPayment.php
file with the following content:<?php
namespace XLite\Module\XCExample\Payment\Model\Payment\Processor;
class DemoPayment extends \XLite\Model\Payment\Base\WebBased
{
protected function getFormURL()
{
return \XLite::getInstance()->getShopURL() . 'payment.php';
}
protected function getFormFields()
{
return array(
'transactionID' => $this->getTransactionId(),
'returnURL' => $this->getReturnURL(null, true),
'invoice_description' => $this->getInvoiceDescription(),
);
}
public function processReturn(\XLite\Model\Payment\Transaction $transaction)
{
parent::processReturn($transaction);
$request = \XLite\Core\Request::getInstance();
$status = '';
$notes = array();
if ($request->status == 'Paid') {
$status = $transaction::STATUS_SUCCESS;
$this->setDetail('Status', $request->status, 'Result');
$this->setDetail('TxnNum', $request->transactionID, 'Transaction number');
} else {
$status = $transaction::STATUS_FAILED;
$notes[] = 'Payment Failed';
}
$this->transaction->setStatus($status);
$this->transaction->setNote(implode('. ', $notes));
}
}This file represents an integration with the self-designed payment gateway described in the point 1 here.
We create the
<X-Cart>/classes/XLite/Module/XCExample/Payment/install.yaml
file with the following content:XLite\Model\Payment\Method:
- service_name: DemoPayment
class: Module\XCExample\Payment\Model\Payment\Processor\DemoPayment
type: C
translations:
- code: en
name: Demo PaymentThis file will register this payment method in the database.
Note: do not forget to push this file into the database.
Now we have the module described in the previous guide, but it has been created with module ID Payment and we want to add some settings to it. We will create a settings form that will contain three fields:
- login
- password
- live/test mode
We start with updating <X-Cart>/classes/XLite/Module/XCExample/Payment/install.yaml file
. We should add payment method settings there, so we append it with following lines:
settings:
- name: login
- name: password
- name: mode
value: live
These lines will add login and password settings with empty default values as well as mode setting that has live value by default. The final version of this YAML file will be as follows:
XLite\Model\Payment\Method:
- service_name: DemoPayment
class: Module\XCExample\Payment\Model\Payment\Processor\DemoPayment
type: C
translations:
- code: en
name: Demo Payment
settings:
- name: login
- name: password
- name: mode
value: live
Once we are done with this, we need to push renewed version of our YAML file to the database.
After that we go to the <X-Cart>/classes/XLite/Module/XCExample/Payment/Model/Payment/Processor/DemoPayment.php
file and add following methods there:
public function getSettingsWidget()
{
return 'modules/XCExample/Payment/config.twig';
}
public function isTestMode(\XLite\Model\Payment\Method $method)
{
return $method->getSetting('mode') != 'live';
}
public function isConfigured(\XLite\Model\Payment\Method $method)
{
return parent::isConfigured($method)
&& $method->getSetting('login')
&& $method->getSetting('password');
}
getSettingsWidget()
method defines a template that will display a settings for this payment method;isTestMode()
method defines a condition that will mark this payment method as in test mode. In our case, if the mode setting is not live, then our payment method is in test mode;isConfigured()
method defines a condition when X-Cart will consider this payment method ready for processing orders and will show it on checkout page. In our case, login and password settings must not be empty. Final version of the<X-Cart>/classes/XLite/Module/XCExample/Payment/Model/Payment/Processor/DemoPayment.php
file will be as follows:
<?php
namespace XLite\Module\XCExample\Payment\Model\Payment\Processor;
class DemoPayment extends \XLite\Model\Payment\Base\WebBased
{
public function getSettingsWidget()
{
return 'modules/XCExample/Payment/config.twig';
}
public function isTestMode(\XLite\Model\Payment\Method $method)
{
return $method->getSetting('mode') != 'live';
}
public function isConfigured(\XLite\Model\Payment\Method $method)
{
return parent::isConfigured($method)
&& $method->getSetting('login')
&& $method->getSetting('password');
}
protected function getFormURL()
{
return \XLite::getInstance()->getShopURL() . 'payment.php';
}
protected function getFormFields()
{
return array(
'transactionID' => $this->getTransactionId(),
'returnURL' => $this->getReturnURL(null, true),
'invoice_description' => $this->getInvoiceDescription(),
);
}
public function processReturn(\XLite\Model\Payment\Transaction $transaction)
{
parent::processReturn($transaction);
$request = \XLite\Core\Request::getInstance();
$status = '';
$notes = array();
if ($request->status == 'Paid') {
$status = $transaction::STATUS_SUCCESS;
$this->setDetail('Status', $request->status, 'Result');
$this->setDetail('TxnNum', $request->transactionID, 'Transaction number');
} else {
$status = $transaction::STATUS_FAILED;
$notes[] = 'Payment Failed';
}
$this->transaction->setStatus($status);
$this->transaction->setNote(implode('. ', $notes));
}
}
Finally, we need to create the template mentioned in the getSettingsWidget() method, so we create the <X-Cart>/skins/admin/modules/XCExample/Payment/config.twig
file with the following content:
<table cellspacing="1" cellpadding="5" class="settings-table">
<tr>
<td class="setting-name">
<label for="settings_login">{{ t('Login') }}</label>
</td>
<td>
<input type="text" id="settings_login" name="settings[login]" value="{{ this.paymentMethod.getSetting('login') }}" class="validate[required, maxSize[255]]" />
</td>
</tr>
<tr>
<td class="setting-name">
<label for="settings_password">{{ t('Password') }}</label>
</td>
<td>
<input type="text" id="settings_password" name="settings[password]" size="64" value="{{ this.paymentMethod.getSetting('password') }}" class="validate[required,maxSize[255]]" />
</td>
</tr>
<tr>
<td class="setting-name">
<label for="settings_mode">{{ t('Processing mode') }}</label>
</td>
<td>
<select id="settings_mode" name="settings[mode]">
<option value="test" {% if this.paymentMethod.getSetting('mode') == 'test' %} selected="selected" {% endif %}>Test mode</option>
<option value="live" {% if this.paymentMethod.getSetting('mode') == 'live' %} selected="selected" {% endif %}>Live mode</option>
</select>
</td>
</tr>
</table>
This template represents the form that will be displayed in the payment method settings page. Important notes are:
- You should use the
{{ this.paymentMethod.getSetting('setting-name') }}
construction in order to display already saved value of payment method setting; - name field of an
<input>
element must besettings[setting-name]
in order to allow X-Cart to properly update its value after submit; That is it with this module example. Now we need to re-deploy the store and check the results. First of all add our payment method on the Store setup > Payment methods page in admin area. Since the login and password fields are not specified yet, the payment methods list displays this method as unconfigured and active/inactive selector is disabled: This is ourisConfigured()
method in action. Go to the payment method's settings page, input any values into Login/Password fields and set Test value for Processing Mode field. Save the results and check this payment method in the payment methods list. It will show you this method as enabled, but it will mark it as in test mode: Here we see theisTestMode()
method in action.
Module pack
Module example (with the settings page) for X-Cart v5.4.x: XCExample-Payment.5.4.0.0.tgz