Интеграция платёжных систем

Представим, что нам необходимо осуществить интеграцию с некой абстрактной платёжной системой под названием "ExpressPay". Для удобства, разделим процесс интеграции на несколько этапов:

  1. добавление способа оплаты в шаблоны данных;
  2. реализация класса платёжной системы;
  3. создание шаблонов вывода формы для перехода в платёжную систему;
  4. настройка оплаты в интернет-магазине.

Добавление способа оплаты

Чтобы добавить свой способ оплаты, создайте в корне сайта файл с любым именем. Поместите в него следующий код и запустите из строки браузера. 


<?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 параметра: логин, пароль и идентификатор магазина. Чтобы в настройках оплаты можно было ввести эти данные, нужно добавить в тип данных новую группу, содержащую необходимые поля.

 

add_payment

 

 

 

 

Реализация класса платёжной системы

Создайте новый 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". Укажите название способа оплаты и заполните необходимые поля (в нашем случае — это логин, пароль и идентификатор магазина), нажмите кнопку Добавить. Теперь пользователи Вашего интернет-магазина смогут оплачивать заказы с помощью данной платёжной системы.

add_payment_final