Перейти к содержимому


Фотография
- - - - -

Как подключить произвольную платежную систему в JBZoo (версии до 2.1.x) ?

рецепт платежные системы

В этой теме нет ответов

#1 SmetDenis

SmetDenis

Отправлено 10 October 2014 - 12:16

В первую очередь скажу, что этот пост будет полезен только тем, кто более менее разбирается в PHP.

И так, я вкратце расскажу принцип работы платежных систем в старой версии корзины (до конструктора из 2.2.0)
По многих причинам корзина не может расширяться плагинами поэтому ниже мы будем писать хаки.
 
Допустим у нас есть агрегатор платежей
Начиная отсюда я буду считать, что у меня есть вымышленная(!) классическая платежная система
 
 - Она называется myPayment
 
 - Чтобы создать заказ мне нужно отправить через GET или POST на http://merchant.mypayment.com/ массив
- - логин продавца
 - - номер заказа
 - - сумма
 - - хеш  - цифровая подпись, образованная через md5 ($orderId : $amount, $password)
 
 - После оплаты на сайт зайдет робот и мне нужно сравнить его хеш со своим и если все нормально, то ставим отметку "оплачено".
 


Разбираем payment.php
Основной файл, который отвечает за работу с платежными системами - это jbuniversal\framework\controllers\payment.php
На самом деле это контроллер, которая собрал в себя почти всю логику работы.
Сейчас мы в нем увидим жесткие условия для работы с PayPal, Interkassa, Robokassa
 
Вы можете найти тут такие методы как
_init() - делает минимально необходимые проверки заказа (существование). Так же содержит важную функцию, как определение заказа по внешнему ID
 
index() - отвечает за страницу с выбором платежной системы. Здесь проверяется, включен ли способ оплаты, и если да, то подготавливаются данные и рендерится HTML код формы.
 
paymentCallback() - Метод, который отвечает за валидацию заказа и отметку об оплате. Он нужен только для роботов и вернет что-то только если на него правильно отправить POST запрос.
 
Где хранить настройки ?
Откройте файл jbuniversal\config\basket.xml
 
И по аналогии добавим в низу

    <!-- myPayment-->
    <param name="@spacer-mypayment" type="jbspacer" default="MyPayment"/>
    <param name="mypayment-enabled" type="jbbool" default="0" label="MyPayment"/>
    <param name="mypayment-login" type="text" default="" label="Login" />
    <param name="mypayment-password" type="text" default="" label="Password"/>

Это добавит опции вкл/логин/пароль в настройках каталога корзины.
Сохранятся они будут в базу данных как параметры каталога.

 
Рендеринг формы оплаты
По аналогии с одним из существующих способов добавим код рендеринга

<?php
// myPayment
if ((int)$appParams->get('mypayment-enabled', 0)) { // проверяем, включена ли система
    // готовим данные для HTML-формы 
    $params               = new stdClass();
    
    // берем логин и пароль из настроек и избавляемся от случайных пробелов
    $params->login        = JString::trim($appParams->get('mypayment-login'));
    $params->password     = JString::trim($appParams->get('mypayment-password')); 
    
    // генерируем подпись (смотрите документацию вашего агрегатора)
    $params->hash         = md5(implode(':', array($params->login, $totalSumm, $this->password)));
    
    // прочие не менее важные параметры формы
    $params->amount       = $totalSumm;
    $params->orderId      = $this->orderId;
    $params->summFormated = $totalSummFormated;

    $this->payments['mypayment'] = $this->app->data->create($params);
}
?>

Открываем этот файл (он содержит общую разметку для выбора платежной системы)
jbuniversal\templates\catalog\renderer\payment\_default.php и добавляем

<?php
if ((int)$view->appParams->get('global.jbzoo_cart_config.mypayment-enabled', 0)) {
    echo '<div class="width25">'; // попутно можно подогнать ширину
    echo $this->app->jblayout->render('payment_mypayment', $view->payments['mypayment']);
    echo '</div>';
}
?>

Теперь создаем шаблон для формы jbuniversal\templates\catalog\renderer\payment_mypayment\_default.php
Переменная $data - это объект JSONData, который будет хранить все то что мы подготовили в index()

    <form action="http://merchant.mypayment.com/" method=POST>
        <input type="hidden" name="mypay_login"    value="<?php echo $data->get('login'); ?>">
        <input type="hidden" name="mypay_order_id" value="<?php echo $data->get('orderId'); ?>">
        <input type="hidden" name="mypay_amount"   value="<?php echo $data->get('amount'); ?>">
        <input type="hidden" name="mypay_hash"     value="<?php echo $data->get('hash'); ?>">
        
        <input type="submit" class="add-to-cart"   value="<?php echo JText::_('JBZOO_PAYMENT_BUTTON'); ?>"/>
    </form>

Платежный робот и валидация заказа
Валидация у нас будет с помощью робота, который автомаически заходит на наш сайт по специальному адресу (status)
Адрес этот заранее указан в настройках мерчанта у myPayment

Первое что нам нужно сделать, это определить что робот является именно от myPayment
Для этого в _init() проверяем внешнюю переменную из реквеста, которая отвечает за номер заказа.
Обычно в этом нет никаких проблем, т.к каждая система имеет свое уникальное именование.

Для удобства используем константу

const TYPE_MYPAYMENT = 'MyPayment';

Код определения id оплаченного заказа

<?php
    ...
    // тут я проверяю $_REQUEST['mypay_order_id'], у вас может быть другая.
    } else if ($orderId = (int)$this->_jbrequest->get('mypay_order_id')) {
        $this->systemType = self::TYPE_MYPAYMENT;
        $this->orderId    = $orderId;
    } else if ( ... ) {
    ....
?>

Проверяем данные, с которыми к нам пожаловал робот
Снова по аналогии с другими платежными системами вставляем свой код в paymentCallback()

<?php
if ($this->systemType == self::TYPE_MYPAYMENT) {

    // подготавливаем свои переменные
    $login    = JString::trim($this->appParams->get('global.jbzoo_cart_config.mypayment-login'));
    $password = JString::trim($this->appParams->get('global.jbzoo_cart_config.mypayment-password'));
    $myHash   = md5($login . ':' . $password . ':' . $this->orderId);
    
    // берем
    $merchantHash = $_REQUEST['mypay_hash']; // без Joomla API, чтобы ничего не стереть

    if ($merchantHash === $myHash) { // совпали ли подписи?

        // Все отлично, готовим данные для сохранения в наш заказ
        $args = array(
            'date'            => $this->app->date->create()->toSQL(), // текущая дата
            'system'          => $this->systemType, // имя платежной системы
            'additionalState' => null // сюда можно добавить свои произвольные переменные (массиом)
        );

        // отмечаем заказ как оплаченный
        $this->orderDetails->callback('paymentCallback', $args);
        
        // говорим роботу на его языке, что все отлично и он тоже может быть спокоен
        jexit('OK' . $this->orderId);

    } else {
        
        // прогоняем робота фатальной ошибкой. Валидация не прошла!
        throw new AppException('No valid hash');
    }

}
?>

Вот и все!


И сразу важные замечания.
- Использовал в качестве примера простейшую выдуманную платежную систему. Поэтому у вас будут свои переменные и свои способы валидации. Возможно что и тех и других будет гораздо больше.
- В качестве рабочего примера рекомендую смотреть реализацию Робокассы. Она имеет очень простое API без наворотов.
- Я лишь описал принцип работы, чтобы дать понять с чего начинать.


Т.к довольно большая часть действий происходит в фоне, то рекомендую использовать какой-нибудь логгер переменных в файл.
Это поможет понять что отправляет робот. Зачастую там есть полезная информация вроде конкретного способа оплаты.

Сам я всегда пользуюсь jbdump
Подключаем класс и дампим

jbdump::log($_REQUEST);

Затем смотрим содержимое папки /logs/ рядом с классом.


Так же на форуме есть другие обсуждения. Вот что вспомнил я

(список на самом деле большой, но у меня действительно нет времени. Поиск на форуме работает ;) )
http://forum.jbzoo.c...rivat24-liqpay/
http://forum.jbzoo.c...ziny-jbzoo-160/

 

 


  • 3
JBZoo v4.0 и новый чудный мир Open Source GPL
Отключайте проверку лицензий как можно скорее!



— Есть два типа людей: Кто еще не делает бекапы и кто уже делает бекапы.






Темы с аналогичным тегами рецепт, платежные системы

Click to return to top of page in style!