Представим, что нам необходимо осуществить интеграцию с некой абстрактной платёжной системой под названием "ExpressPay". Для удобства, разделим процесс интеграции на несколько этапов:
- добавление способа оплаты в шаблоны данных;
- реализация класса платёжной системы;
- создание шаблонов вывода формы для перехода в платёжную систему;
- настройка оплаты в интернет-магазине.
Добавление способа оплаты
Чтобы добавить свой способ оплаты, создайте в корне сайта файл с любым именем. Поместите в него следующий код и запустите из строки браузера.
<?php
$className = "express";
$paymentName = "ExpressPay";
include "standalone.php";
$objectTypesCollection = umiObjectTypesCollection::getInstance();
$objectsCollection = umiObjectsCollection::getInstance();
// получаем родительский тип
$parentTypeId = $objectTypesCollection->getTypeIdByGUID("emarket-payment");
// Тип для внутреннего объекта, связанного с публичным типом
$internalTypeId = $objectTypesCollection->getTypeIdByGUID("emarket-paymenttype");
$typeId = $objectTypesCollection->addType($parentTypeId, $paymentName);
// Создаем внутренний объект
$internalObjectId = $objectsCollection->addObject($paymentName, $internalTypeId);
$internalObject = $objectsCollection->getObject($internalObjectId);
$internalObject->setValue("class_name", $className); // имя класса для реализации
// связываем его с типом
$internalObject->setValue("payment_type_id", $typeId);
$internalObject->setValue("payment_type_guid", "user-emarket-payment-" . $typeId);
$internalObject->commit();
// Связываем внешний тип и внутренний объект
$type = $objectTypesCollection->getType($typeId);
$type->setGUID($internalObject->getValue("payment_type_guid"));
$type->commit();
echo "Готово!";
?>
Этот код создает в системе новый объект типа данных "Способ оплаты" с именем ($paymentName) ExpressPay. Для объекта создается пользовательский класс ($className) Express, который является расширением класса payment. Реализация данного класса приведена ниже.
Перейдите в модуль Шаблоны данных. В списке Способы оплаты Вы увидите только что добавленный тип данных "ExpressPay".
Будем считать, что для успешной авторизации в нашей платёжной системе, ей нужно передать 3 параметра: логин, пароль и идентификатор магазина. Чтобы в настройках оплаты можно было ввести эти данные, нужно добавить в тип данных новую группу, содержащую необходимые поля.
Реализация класса платёжной системы
Создайте новый PHP-файл с названием "express.php" в папке "/classes/modules/emarket/classes/payment/systems/". Поместите в файл описание класса и его методов:
<?php
class expressPayment extends payment
{
public function validate() {
// Запрещаем оплату с помощью ПС,
// если сумма заказа меньше 1000 у/е.
$sum = (float) $this->order->getActualPrice();
if($sum < 1000.0) {
return false;
}
return true;
}
public function process($template = 'default') {
if(!isset($template))
$template = 'default';
$this->order->order();
$login = $this->object->login;
$password = $this->object->password;
$shop_id = $this->object->shop_id;
if(!strlen($login) || !strlen($password) || !is_numeric($shop_id))
throw new publicException(getLabel('error-payment-wrong-settings'));
$sum = (float) $this->order->getActualPrice();
$params = array();
$params['login'] = $login;
$params['password'] = md5($password);
$params['shop_id'] = $shop_id;
$params['sum'] = $sum;
$params['action'] = 'http://expresspay.com/pay.php';
$params['order_id'] = $this->order->getId();
$this->order->setPaymentStatus('initialized');
list($form_block) =
def_module::loadTemplates('emarket/payment/expresspay/' . $template, 'form_block');
return def_module::parseTemplate($form_block, $params);
}
public function poll() {
$buffer = outputBuffer::current();
$buffer->clear();
$buffer->contentType('text/plain');
if (!is_null(getRequest('signature'))) {
$login = $this->object->login;
$password = $this->object->password;
$shop_id = $this->object->shop_id;
$order_id = getRequest('order_id');
$signature = md5($login . $password . $shop_id . $order_id);
if($signature == getRequest('signature')) {
$this->order->setPaymentStatus('accepted');
$buffer->push('success');
} else {
$buffer->push('fail');
}
}
$buffer->end();
}
};
?>
Рассмотрим описание класса более подробно: он должен быть унаследован от абстрактного класса «payment», имя должно повторять идентификатор типа способа оплаты с суффиксом "Payment", обязательно присутствие методов validate, process и poll.
Метод validate вызывается в момент формирования списка возможных способов оплаты. Он позволяет запретить оплату с помощью платёжной системы, если заказ не удовлетворяет каким-либо параметрам. Чтобы разрешить или запретить оплату с помощью платёжной системы метод должен вернуть логическое значение true или false соответственно.
Метод process предназначен для формирования и отправки данных платёжной системе. Когда пользователь выбирает способ оплаты, метод получает необходимые для платёжной системы данные (например: логин, пароль, идентификатор заказа), меняет статус заказа на "инициализирован" и выводит форму для перехода к оплате заказа.
С помощью метода poll производится обработка ответа от платёжной системы и выставляется соответствующий статус оплаты.
Более подробные примеры реализации класса платёжной системы можно посмотреть в системных файлах других платёжных систем, которые находятся в папке "/classes/modules/emarket/classes/payment/systems" (например: "yandex.php", "rbk.php" и т.д.).
Создание шаблонов вывода формы для перехода в платёжную систему
Если Вы используете TPL-шаблонизатор, то Вам необходимо создать файл "/tpls/emarket/payment/expresspay/default.tpl" (это шаблон вывода формы по умолчанию) и поместить в него следующий код:
<?php
$FORMS = array();
$FORMS['form_block'] = <<<END
<form action="%action%" method="post">
<input type="hidden" name="login" value="%login%" />
<input type="hidden" name="password" value="%password%" />
<input type="hidden" name="shop_id" value="%shop_id%" />
<input type="hidden" name="order_id" value="%order_id%" />
<input type="hidden" name="price" value="%price%" />
<p>
Нажмите кнопку "Оплатить" для перехода на сайт платежной системы
<strong>ExpressPay</strong>.
</p>
<p>
<input type="submit" value="Оплатить" />
</p>
</form>
END;
?>
Для передачи платёжной системе необходимых данных, в форме используются hidden поля, значения для этих полей доступны через специальные макросы. Например, если в методе process в массив данных было добавлено поле login, то его значение будет доступно через макрос %login%.
При использовании XSLT-шаблонизатора, необходимо добавить шаблон формы в файл "/xsltTpls/modules/emarket/purchase/payment.xsl". Наиболее удобно будет поступить следующим образом: открыть данный файл, найти шаблон для какой-либо платёжной системы, скопировать и отредактировать его в соответствии с Вашими данными. В случае с нашим примером, получится примерно следующий код:
<xsl:template match="purchasing[@stage = 'payment'][@step = 'express']">
<form action="{action}" method="post">
<input type="hidden" name="login" value="{login}" />
<input type="hidden" name="password" value="{password}" />
<input type="hidden" name="shop_id" value="{shop_id}" />
<input type="hidden" name="order_id" value="{order_id}" />
<input type="hidden" name="price" value="{price}" />
<div>
<xsl:text>&payment-redirect-text; ExpressPay.</xsl:text>
</div>
<div>
<input type="submit" value="Оплатить" class="button big" />
</div>
</form>
</xsl:template>
В XSLT-шаблонизаторе значения для hidden полей доступны через одноимённые переменные. Например, в методе process в массив данных было добавлено поле shop_id, тогда его значение будет доступно через переменную shop_id.
Настройка оплаты в интернет-магазине
Перейдите в модуль Интернет-магазин, на вкладке Оплата наведите курсор на кнопку Добавить способ оплаты и в выпадающем списке выберите "ExpressPay". Укажите название способа оплаты и заполните необходимые поля (в нашем случае — это логин, пароль и идентификатор магазина), нажмите кнопку Добавить. Теперь пользователи Вашего интернет-магазина смогут оплачивать заказы с помощью данной платёжной системы.