Интеграция Paysera в Symfony

Сегодня сложно представить себе серьезный проект, где не понадобилась бы интеграция с платежными системами. Не смотря на то что существует множество популярных систем и аггрегаторов, таких как PayPal, RBKMoney, Paymentwall, Robokassa и т.д., я хочу рассказать о Paysera. Это еще одна, довольно новая платежная система. Они позиционируют себя как выгодных с точки зрения комиссий за их услуги. Paysera позволяет вашим пользователям расплачиваться карточками, SMS и т.д. Интеграция довольно простая, однако имеет некоторые неочевидные моменты, которые я и хочу осветить.

Прежде всего необходимо зарегистрироваться в Paysera.

Включаем необходимые услуги

После того, как вы создали аккаунт, необходимо открыть страницу Управления услугами и включить некоторые из них. Т.к. нам необходима возможность оплаты через интернет, то необходимо включить следующие:

- Сбор платежей через интернет, через эл. банкинг и другие системы

- Сбор платежей через интернет платежными картами

- Сбор платежей через операторов (СМС)

Paysera - управление серсисами

После этого у вас в меню появится дополнительный пункт - Сбор платежей.

Чтобы создать проект, даже демо, необходимо иметь уровень аккаунта не ниже Basic. Для этого необходимо подтвердить email, телефон и отправить копию паспорта. Лично мне не нравится такой подход. Даже чтобы протестировать их систему в тестовом режиме без реальных денег, все равно необходимо отправлять какие-то документы. Есть гораздо более дружелюбные подходы по отношению к пользователям, например просто запрещать вывод денег из системы или же поддерживать только тестовый режим для всех проектов пока личность не подтверждена.

С этого момента я исхожу из того, что вы подтвердили свою личность и имеете аккаунт уровня не ниже Basic.

Создаем демо проект

Теперь мы можем создать демо проект. Необходимо открыть Сбор платежей / Управление проектами. Вам необходимо будет заполнить базовую информацию о проекте и как только вы с этим закончите, то проект появится в списке:

Paysera - добавление проекта

Обратите внимание на номер проекта (projectid), он понадобится нам позже. Также не забудьте указать URL проекта на вкладке Основная информация по проекту:

Paysera - URL проекта

Нам также понадобится пароль к проекту. Его можно найти или сгенерировать на вкладке Общие настрокий проекта: 

Paysera - общие настройки проекта

Включаем тестовый режим

Всегда необходимо тестировать результаты интеграции перед обновлением production сервера. Именно поэтому нам необходимо включить тестовый режим. Это можно сделать на вкладке настроек услуг сбора платежей. Выберите следующие пункты:

- Разрешить тестовую оплату (для оплаты без денег)

- Позволить принимать поступления от любой информационной системы (т.к. мы будет осуществлять запросы с локального сервера)

Paysera - тестовый режим

Настройка на стороне Paysera завершена. Давайте перейдем к программированию.

PHP библиотека для Paysera

Если вы не используете Symfony, вы можете воспользоваться одним из плагинов для вашего фреймворка/CMS или же установить библиотеку с помощью Composer'a:

composer require webtopay/libwebtopay

Paysera Symfony2 бандл

Давайте рассмотрим как интегрировать Paysera в ваш проект на Symfony.

Установка

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

composer require webtopay/webtopay-bundle

Настройка

Далее необходимо добавить бандл в AppKernel:

<?php

// app/AppKernel.php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{    
    public function registerBundles()
    {
        $bundles = array(
            //...
            new Evp\Bundle\WebToPayBundle\EvpWebToPayBundle(),
        );

//...

И настроить его:

# app/config/config.yml

# Paysera
evp_web_to_pay:
   credentials:
       project_id: %paysera_project_id%
       sign_password: %paysera_project_password%

Готово.

Высокоуровневая архитектура платежных систем

Если вы хотите понять общую картину того как работают платежные шлюзы, советую прочитать мой предыдущий блог пост - высокоуровневая архитектура платежных систем. Начиная с этого момента я предполагаю что у вас есть базовое понимание принципов взаимодействия с платежными шлюзами. Во всех дальнейших примерах будут освещены только те моменты, которые непосредственно относятся к Paysera.

Упрощенный контроллер

<?php

// ...

class OrderController extends Controller
{
    /**
    * @Route("/pay/{hash}", name="OrderView") 
    * @Method({"GET"}) 
    */
    public function payOrderAction($hash)
    {
        $order = // получить заказ по хешу или ID

        $url = $this->get('evp_web_to_pay.request_builder')->buildRequestUrlFromData([
            'orderid' => // ID заказа в вашей системе
            'amount' => // стоимость в ЦЕНТАХ
            'currency' => // USD, EUR и т.д.
            'paytext' => // текст, который будет виден пользователю в некоторых платежных системах
            'accepturl' => $this->generateUrl('OrderThankYou', ['id' => $order->getId()]),
            'cancelurl' => $this->generateUrl('Home'),
            'callbackurl' => $this->generateUrl('PaymentCallback'),
            'p_email' => // email пользователя
            'test' => // тестовый режим, boolean
        ]);

        return new RedirectResponse($url);
    }    

    /**
    * @Route("/thank-you/{id}", name="OrderThankYou", requirements={"id": "\d+"})
    * @Method({"GET"})
    * @Template()
    */
    public function thankYouAction($id)
    {
        return [
            'id' => $id,
        ];
    }

    /**
     * @Route("/paymentcallback/custom-super-secret-endpoint", name="PaymentCallback")
     */
    public function callbackAction(Request $request)
    {
        // логирование запроса

        $data = $this->get('evp_web_to_pay.callback_validator')->validateAndParseData($request->query->all());
        if ($data['status'] == 1) {
            // предоставление сервиса пользователю
        }

        return new Response('OK');
    }
}

Итак, у нас есть три главных метода:

1. Pay order.

Здесь мы формируем ссылку для пользователя. Перейдя по ней он попадет на страницу выбора способов оплаты. Несколько моментов требуют внимания:

- amount - в центах. Если вы храните стоимость у себя по другому, не забудьте умножить ее, привести к центам.

- paytext - этот текст будет виден пользователю. Вы должны использовать в нем два маркера:

[order_nr] - ID заказа в вашей системе
[site_name] - название вашего сайта

Например: 

$paytext = $orderTitle . ' Заказ [order_nr] на сайте [site_name]';

accepturl - устанавливаем ссылку на страницу с благодарностью. Я также указываю здесь ID заказа в качестве параметра, чтобы была возможность показать больше информации пользователю.

cancelurl - в моем случае просто указывает на домашнюю страницу.

callbackurl - для ответных запросов со стороны платежного шлюза.

test - использовать тестовый режим или нет. Позволяет тестировать систему без денег.

По задуму EvpWebToPayBundle  предоставляет удобный способ для тестирования платежей - sandbox режим. Если вы настроете его, то все запросы будут отправляться на  sandbox.paysera.com вместо paysera.com. Это отличная идея, но увы их sandbox сервер не работает должным образом. На момент интеграции было невозможно подтвердить аккаунт, т.к. приходили битые письма:

2. Thank you

Т.к. мы не можем воспользоваться sandbox сервером, то нам необходимо немного модифицировать наш ThankYou метод:

<?php

// ...
/**
 * @Route("/thank-you/{id}", name="OrderThankYou", requirements={"id": "\d+"})
 * @Method({"GET"})
 * @Template()
 */
public function thankYouAction($id)
{
    if ($this->container->getParameter('kernel.debug')) {
        $data = $this->get('evp_web_to_pay.callback_validator')->validateAndParseData($request->query->all());
        if ($data['status'] == 1) {
            // предоставляем сервис пользователю
        }
    }

    return [
        'id' => $id,
    ];
}

Таким образом мы можем тестировать платежи локально в dev окружении с включенным тестовым режимом в Paysera. 

3. Callback

Здесь вы обрабатываете результаты платежа. Если status равен 1 - значит платеж прошел успешно и вы должны предоставить сервис пользователю. При этом не забудьте вернуть правильный ответ - 200 OK. Вы также можете инициализировать свои события, а затем добавлять к ним слушателей, например для отправки email'ов, обновления статистики и т.д.

Плюсы

  • документация находится в актуальном состоянии. Это важно. Почему? Потому что у меня был опыт с некоторыми платежными сервисами, владельцы и разработчики которых были достаточно ленивы и не обновляли документацию. Приходилось общаться с их программистами напрямую и выяснять почему все что описано в документации не работет
  • поддержка работает 7 дней в неделю

Минусы

  • у них есть sandbox, но он не работает
  • даже для тестов вам прийдется отправить копию паспорта
  • нет поддержки рекуррентных платежей
  • не представлен в http://payum.org
  • техническая поддержка работает только в рабочие дни

Выводы

Если Вам не нужны рекуррентные платежи, то Paysera вполне может быть вашим выбором, в противном случае стоит посмотреть на другие платежные системы.

Читайте также:

Docker установка и настройка

При разработке используется множество технологий. К примеру данный блог использует php(Symfony 2), mongodb, elastic, nginx это основные но также используется nodejs к примеру для минификации css, js. При разработке приходится настраивать все технологии как показано в статье. Но что делать если проектов несколько или они используют разные технологии, например другой проект использует MySQL, или еще могут использовать разные версии php или других библиотек. Для разработки и поддержки проектов на разных технологиях можно использовать Виртуальную машину и поставить на нее к примеру centos, но это не совсем удобно, надо все равно настраивать подобное окружение как на сервере и на других машинах разработчиков. Мы будет использовать контейнеры, такие как Docker. Настроем блог разработчиков чтобы использовать Docker для разработки.

Как использовать произвольное хранилище пользователей в FOSUserBundle

Практически все используют FOSUserBundle в своих Symfony проектах т.к. он ускоряет разработку и обладает хорошим набором функциональности для управления пользователями. Бандл предоставляет несколько готовых реализаций хранилищ данных: Propel и несколько для Doctrine (ORM и ODM). Это здорово, но иногда возникает необходимость работы с другими хранилищами данных. FOSUserBundle достаточно гибок и позволяет реализовать, и использовать произвольное хранилище. Для того, чтобы использовать все возможности FOSUserBundle Вам достаточно будет написать свой менеджер пользователей под конкретного провайдера.

Настройка php, MySQL, nodejs, nginx и mongodb в OS X El Capitan

Недавно вышла OS X El Capitan, давайте обновим систему. Систему будем устанавливать с usb-flash. Из рабочего окружения мы поставим  php, nginx, mariadb, mongodb, elasticsearch, nodejs используя brew и настроем проект на symfony2.

Создание сайта “Обратный отсчет” на Symfony2

Мы иногда видим сайты с обратным отсчетом, проект стартует через … Его сделать достаточно просто, и не займет много времени. Мы воспользуемся проектом fdevs/coming-soon, который основан на Symfony2. Также будем сохранять введеный пользователями адреса электронной почтой в базу данных MongoDB. У нас есть настроенное рабочее окружение Osx, о настройке можно прочитать в статье Yosemite настройка рабочего окружения. Но главное версия php не меньше 5.4. В проекте можно также использовать реляционную базу данных типа MySQL. По умолчанию в проекте вообще не используется база данных, а введеный email отправляется на почту.

Автоматический deploy Symfony 2 используя Capifony

При разработке, и тем более поддержке действующего проекта на Symfony 2 одной из задач, которые приходится постоянно делать, это выгрузка изменений на сервер: рабочей или тестовой. Но так как программисты народ достаточно ленивый, чтобы автоматизировать повторяющиеся монотонные задачи, есть достаточное количество инструментов для облегчения данного процесса. Для Symfony2 мы используем Сapifony. Он основан на Capistrano но оптимизирован для Symfony.