В данной теме постараюсь полностью описать возможности JBZoo 220 по интеграции со сторонними платежными системами. Иначе говоря - создание элемента платежной системы.
1. Расположение элементов
Элементы находятся в папке
\media\zoo\applications\jbuniversal\cart-elements\payment
внутри находятся папки с названием элемента, а внутри каждой находится минимум 2 файла - это основной файл элемента(расширение php) и файл конфигурации(xml)
Например мы хотим сделать интеграцию с платежной системой Yandex Касса (хочу оговориться, что полной интеграции с каким то из сервисов тут не будет).
В корневой папке мы создаем папку для нашего элемента например с названием yandexkassa. Внутри нашей папке создаем 2 файла
yandexkassa.php yandexkassa.xml
2. Необходимый минимум кода в файлах
2.1 Файл конфигурации должен иметь следующий вид
<?xml version="1.0" encoding="utf-8"?> <element type="element" group="Core" hidden="false"> <name>JBZOO_ELEMENT_PAYMENT_YANDEXKASSA_NAME</name> <author>JBZoo.com</author> <creationDate>2015</creationDate> <copyright>Copyright (C) JBZoo.com</copyright> <authorEmail>admin@jbzoo.com</authorEmail> <authorUrl>http://jbzoo.com</authorUrl> <version>1.0</version> <description>JBZOO_ELEMENT_PAYMENT_YANDEXKASSA_DESC</description> <params> <param name="description" type="textarea" label="JBZOO_ELEMENT_DESCRIPTION" default="JBZOO_ELEMENT_PAYMENT_YANDEXKASSA_DEFAULT_DESCRIPTION" description="JBZOO_ELEMENT_ELEMENT_DESCRIPTION_DESC" /> <!-- ВАШИ ПАРАМЕТРЫ ДЛЯ ЭЛЕМЕНТА --> </params> </element>
Тут ни каких проблем возникнуть не должно. Внутри группы params описываем необходимые значения которые требуются для авторизации в платежной системе.
Например платежная система LiqPay для работы требует как минимум 2 параметра которые должны передаваться в запросе. Пример можно посмотреть в файле
\media\zoo\applications\jbuniversal\cart-elements\payment\liqpay\liqpay.xml
2.2 Класс элемента платежной системы.
Название класса состоит из 2-х частей это префикс(JBCartElementPayment) и название платежной системы, т.е это название нашей папки. Наш класс должен наследоваться от родительского класса JBCartElementPayment который расположен по пути
\media\zoo\applications\jbuniversal\cart-elements\core\payment\payment.php
Именно в этом классе находятся необходимый набор методов - API по платежным системам.
Наш файл по пути
media\zoo\applications\jbuniversal\cart-elements\payment\yandexkassa\yandexkassa.php
Имеет следующее содержимое
<?php // no direct access defined('_JEXEC') or die('Restricted access'); /** * Class JBCartElementPaymentYandexKassa */ class JBCartElementPaymentYandexKassa extends JBCartElementPayment { }
3. Классы и методы при создании элемента.
Минимальный набор методов в классе это:
- getRedirectUrl - должен вернуть ссылку на платежную систему, страницу оплаты (например в элементе qiwi данный метод возвращает ссылку на страницу для ввода номера телефона - об этом чуть позже).
- isValid - функция, которая вызывается роботом платежной системы. Тут происходит валидация платежа, если функция вернула true, то заказ будет отмечен на сайте как "оплачен" со всеми последствиями (письма итд)
- getRequestOrderId - номер заказа из реквеста от робота. Обычно переменная уникальная, поэтому ф-я используется для определения, что это именно робот робокассы или какой то другой платежной системы.
- getRequestOrderSum - сумма оплаты, которую отправил робот. Используется для валидации, что сумма оплаты совпадает с суммой в заказе.
Рассмотрим по подробнее каждый класс.
В методе getRedirectUrl обычно добавляются необходимые параметры которые запрашивает платежная система. Разберем пример для РобоКассы минимальный набор это:
'OutSum' = стоимость заказа в валюте, выбранной Продавцом через интерфейс администрирования 'InvId' = номер заказа 'MrchLogin' = логин Продавца (обычно данные которая предоставляет платежная система устанавливаются в конфиге платежного элемента как параметры); 'Desc' = описание платежа 'SignatureValue' = контрольная сумма MD5 (подпись). У разных сервисов своя контрольная сумма (Хэш)
Разберем код:
public function getRedirectUrl() { /* * получаем нашу сумму(объект). _getOrderAmount - это внутренний метод который производит конвертацию */ $orderAmount = $this->_getOrderAmount(); /* * $this->isDebug() - возвращает true или false в зависимости от параметра (тестовый режим) в настройках элемента * исходя их этого можно перенаправлять пользователя на тестовый или боевой сервер */ $merchantUrl = $this->isDebug() ? $this->_testUrl : $this->_realUrl; /* * Массив данных для передачи в ссылке */ $fields = array( 'OutSum' => $orderAmount->val(), // значение цены т.е цифры 1500 'InvId' => $this->getOrderId(), // id созданного заказа 'MrchLogin' => $this->config->get('login'), // из конфига элемента получаем login 'Desc' => $this->getOrderDescription(), // получаем описание платежа 'SignatureValue' => $this->_getSignature(), // это внутренний метод для создания хэша из данных в соответствие с документацией ); /* * Перенаправляем пользователя на страницу платежной системы * $this->_jbrouter->query($fields) - аналог http_build_query */ return $merchantUrl . '?' . $this->_jbrouter->query($fields); }
Если вы сделали правильный редирект с необходимыми данными, пользователя перенаправит на страницу оплаты платежной системы.
В методе isValid происходит проверка данных. Зачастую сравниваются подписи. Т.е робот присылает нам данные, а мы должны их сравнить. В случае Робокассы:
public function isValid($params = array()) { /* * Получаем хэш от робота и приводим его к верхнему регистру */ $crc = JString::trim(JString::strtoupper($_REQUEST["SignatureValue"])); /* * Создаем хеш из своих данных согласно документации */ $myCrc = JString::trim(JString::strtoupper(md5(implode(':', array( $_REQUEST['OutSum'], $this->getOrderId(), $this->config->get('password2') ))))); if ($crc === $myCrc) { return true; } return false; }
В методе getRequestOrderId мы возвращаем $_REQUEST['InvId'] - в этой переменной робот присылает id заказа.
В методе getRequestOrderSum мы возвращаем объект цены.
Стоит отметить для работы с объектом цены используется
$this->_order->val();
это аналог
JBCart::val();
Более подробно о работе с объектом цены можете узнать из темы.
Не мало важным методом является renderResponse. Данный метод должен оповестить(вывести согласно документации необходимую информацию) робота. В случае Робокассы необходимо вывести текст - OK234, где 234 это номер заказа (ID).
Данный вывод находиться в родительском классе:
media\zoo\applications\jbuniversal\cart-elements\core\payment\payment.php
Именно поэтому в элементе робокассы вы не найдете переопределенный метод renderResponse. В случае Qiwi необходимо было отдать результат роботу в виде XML, поэтому в файле qiwi
\media\zoo\applications\jbuniversal\cart-elements\payment\qiwi\qiwi.php
Вы можете увидеть переопределенный метод renderResponse.
public function renderResponse() { header("HTTP/1.1 200 OK"); header('content-type: text/xml; charset=UTF-8'); $response = '<!--?xml version="1.0"?--><result><result_code>0</result_code></result>'; jexit($response); }
При разработке платежного элемента для QIWI нам потребовалось создать дополнительный экшен который выводил бы форму для ввода номера телефона, поэтому API расширилось и добавилось несколько методов.
1. renderPaymentForm - метод который выводит форму с помощью хелпера jbform, метода render который расположен
\media\zoo\applications\jbuniversal\framework\helpers\jbform.php
Что бы вывести форму необходимо создать xml файл формы, а ее расположение должно быть в
media\zoo\applications\jbuniversal\cart-elements\payment\ПЛАТЕЖНАЯ_СИСТЕМА\forms\НАЗВАНИЕ_ФОРМЫ.xml
далее в методе выводим форму
public function renderPaymentForm() { return $this->app->jbform->render('default', array( 'action' => 'index.php?' . $this->_jbrouter->query(array( 'option' => 'com_zoo', 'controller' => 'basket', 'task' => 'form', 'orderId' => $this->_jbrequest->get('orderId') )), 'submit' => JText::_('JBZOO_BUTTON_SUBMIT_SHOW') )); }
Первый параметр это название формы, второй это массив данных\атрибутов формы. В action мы устанавливаем тот же URL для того что бы после отправки формы методом POST сделать валидацию через метод элемента validatePaymentForm и выполнить какое то действие после удачной проверки с помощью метода actionPaymentForm. Данные методы достаточно редко могут использоваться и пока что из всех элементов платежек данные методы используются только в Qiwi. Структура xml формы похожа на стандартные xml всей joomla, посмотреть можно по адресу:
media\zoo\applications\jbuniversal\cart-elements\payment\qiwi\forms\default.xml
4. Как получить данные заказа и параметров элемента при разработке?
- $this->config->get('НАЗВАНИЕ_ПАРАМЕТРА', 'ЗНАЧЕНИЕ_ПО_УМОЛЧАНИЮ') - получение параметров элемента.
- $this->getOrder() - вернет объект заказа
- $this->getOrderId() - вернет id заказа
- $this->getDefaultCurrency() - вернет значение валюты по умолчанию
- $this->getOrderSumm() - вернет объект цены
- $this->getOrderDescription() - вернет описание для заказа
5. Вывод логотипа платежной системы в списке.
Для этого необходимо создать файл по следующему пути:
\media\zoo\applications\jbuniversal\cart-elements\payment\ПЛАТЕЖНАЯ_СИСТЕМА\tmpl\submission.php
с выводом картинки(пример из qiwi):
<?php // no direct access defined('_JEXEC') or die('Restricted access'); ?> <img src="<?php echo JUri::root(); ?>media/zoo/applications/jbuniversal/cart-elements/payment/qiwi/assets/logo.png">
Если вникнуть и потратить не много своего времени, то написание элемента для платежной системы сводится к минимуму. Больше времени займет разбор документации по платежной системе. Постарался по максимуму описать работу с API, если что всплывет еще буду дополнять.
Edited by Cheren-dow, 30 June 2015 - 10:47.