Интеграция сервиса Яндекс.Касса с CMS MODx Revolution

Для сайта www.stamp-collection.ru расширяя доступные варианты оплаты заказов было принято решение подключить сервис Яндекс.Касса

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

Сейчас попытаюсь описать алгоритм подключения сервиса, с учетом того, что интеграция происходила на систему управления CMS MODx Revolution

Подключение к сервису начинается с заполнения анкеты.

yandex.kassa.anketa

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

yandex.kassa.1

Фактически в этот же день пришло сообщение о том, что можно зайти в Личный кабинет, скачать договор, подписать его и отправить копию, обратно через Личный кабинет

yandex.kassa.1.1

Из Личного кабинета, скачиваете и подписываете оферту ( contract.pdf ), сформированную на основании данных заполненной вами ранее анкеты. Скан оферты отправляется через Личный кабинет обратно менеджеру на проверку

004

После проверки, приходит сообщение о выборе метода подключения.

kassa.yandex.1.3

Моим вариантом подключения был выбор готового модуля для CMS MODx Revolution

yandex.kassa.cms

Готовый модуль представляет из себя набор скриптов на github https://github.com/yandex-money/yandex-money-cms-modx в стандартном репозитории MODx Revo он не доступен. Поэтому для установки пакета требуется выполнить ряд условий

  • Загрузить пакет yandexmoney-*.transport.zip в папку \core\packages
  • Перейти в меню Система - Управление пакетами и выбрать вкладку Пакеты
  • Выполнить локальный поиск пакетов, щелкнув по Искать пакеты локально (кнопка Загрузить дополнения)
  • В списке пакетов выбрать YandexMoney и нажать "Установить"
  • Следовать инструкциям на экране

То есть установка пакета происходит вручную, а не из репозитория. Основную работу выполняют два сниппета YandexMoney и YandexMoneyHook

yandex.money.snippets

Инструкция для работы с модулем содержит следующие пояснения по настройке

После установки модуля необходимо:

1. В чанке формы заказа, в списке способов оплаты указать

[[!YandexMoney?&action=`showMethods` ]]

Т.е., например, в чанке shopOrderForm будет:

  1. <select name="payment">
  2. <option value="При получении">При получении</option>
  3. [[!YandexMoney? &action=`showMethods` ]]
  4. </select>

Этот код подгрузит варианты оплаты

2. В чанке страницы заказа, в список хуков FormIt добавить YandexMoneyHook

Т.е., например, чанк orderform_page

[[!FormIt?
&hooks=`spam,shk_fihook,YandexMoneyHook,email,FormItAutoResponder,redirect`
&submitVar=`order`
&emailTpl=`shopOrderReport`
&fiarTpl=`shopOrderReport`
&emailSubject=`В интернет-магазине "[[++site_name]]" сделан новый заказ`
&fiarSubject=`Вы сделали заказ в интернет-магазине "[[++site_name]]"`
&emailTo=`[[++emailsender]]`
&redirectTo=`25`
&validate=`address:required,fullname:required,email:email:required,phone:required`
&errTpl=`
[[+error]]`]]

3. Создать 2 страницы: для успешно завершенного платежа и неуспешно завершенного. Указать их ID документа в параметрах сниппета YandexMoney

( если выбрали динамические страницы успешного и неуспешного завершения платежа, то не требуется )

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

Примерно столько велась переписка с техподдержкой, по вопросам настройки готового модуля

yandex.kassa.messages

Итак, после заполнения анкеты, подписания договора, настройки модуля вам выдают тестовые настройки вашего магазина. Они представляют из себя два числа shopId ( идентификатор магазина ) и scid ( номер витрины ) и demo urlhttps://demomoney.yandex.ru/eshop.xml ) на который осуществлять submit формы

yandex.kassa.demo

Отмечу основные проблемы, которые возникли при настройке. Будем исходить из того, что все написанное выше вам понятно, и вопросов как установить пакет на MODx Revolution руками, а не из репозитория, и подключить вызовы 2х сниппетов в разных частях шаблонов Shopkeeper у вас не возникает ( в любом случае вся инструкция по подключению сниппетов от авторов пакета выше )

А теперь по порядку основные проблемы:

  1. Изначально, просто подключенные голые сниппеты, не передают параметры shopId ( идентификатор магазина ), scid ( номер витрины ), customerNumber ( уникальный номер заказа ) и sum ( общая сумма заказа) и password ( пароль аккаунта, заданный вами при регистрации ).Возможно эти параметры нужно было передать через вызов сниппета, но в инструкции этого не было указано, поэтому я действовал иначе. В идеальном случае вы должны отправить на url
    https://demomoney.yandex.ru/eshop.xml POST запросом форму следующего вида:

    1. <form name="ShopForm" method="POST" action="https://demomoney.yandex.ru/eshop.xml">
    2. <input type="hidden" name="shopId" value="111111" />
    3. <input type="hidden" name="scid" value="111111" />
    4. <input type="hidden" name="sum" value="1.00" id="sum" />
    5. <input type="hidden" name="customerNumber" value="abc000" />
    6. <input name="paymentType" value="AC" type="hidden" checked="checked">
    7. <input type=submit value="Оплатить"><br>
    8. </form>

    В просто подключенных голых снипетах практически все параметры приходят пустыми. Что делать?

    Для настройки передачи нужных параметров отредактировал класс компонента /core/components/yandexmoney/model/yandexmoney.class.php

    Присвоил публичным полям класса значения по-умолчанию, равные значениям  shopid и scid также прописал им присвоение значений внутри конструктора класса $this->shopid $this->scid и $this->password передал пароль аккаунта, потребовался в дальнейшем

      public $shopid = '111111';
      public $scid = '111111';

Изменил функцию конструктора класса, также для, того чтобы значениям параметров класса присваивались нужные числовые значения

  1. function __construct(modX &$modx,$config = array()) {
  2.  
  3. $this->org_mode = ($config['mode'] == 2);
  4. $this->test_mode = ($config['testmode'] == 0);
  5. //$this->shopid = ($config['testmode'] == 1);
  6.  
  7. $this->shopid = 111111;
  8. $this->scid = 111111;
  9. $this->password = '1111111111';
  10.  
  11. }

В функции формирующей xml ответ от клиента серверу, указал статически номер shopId так как были проблемы, почему-то в xml ответе не передавалось значение shopId (хотя должно было)

yandex.kassa.error

Изначально, shopId в xml коде ответа был задан таким образом shopId="'.$this->shopId.'"

  1. public function sendCode($callbackParams, $code){
  2. header("Content-type: text/xml; charset=utf-8");
  3. $xml = '<?xml version="1.0" encoding="UTF-8"?>
  4. <checkOrderResponse performedDatetime="'.date("c").'" code="'.$code.'" invoiceId="'.$callbackParams['invoiceId'].'"
  5. shopId="111111"/>';
  6. echo $xml;
  7. }

Дальше в коде сниппета YandexMoneyHook при создании экземпляра класса ( объекта ) $ym добавил значения следующим полям объекта $ym->orderId ( передал значение "u".$order_id ) , $ym->orderNumber,  $ym->shopid, $ym->password

  1. if ($order_id && $_POST['order']){
  2.  
  3. $ym->userId = $modx->getLoginUserID('web') ? $modx->getLoginUserID('web') : "u".$order_id;
  4. $ym->orderId = $order_id;
  5.  
  6. // add this
  7. $ym->orderNumber = $_SESSION['shk_lastOrder']['id'];
  8. $ym->shopid = 111111;
  9. $ym->scid = 11111;
  10. $ym->password = '11111111';
  11. // add this
  12.  
  13. ...
  14. }

После этих итераций на тестовый url уже уходили все необходимые параметры.

2. Служба поддержки уверяла меня в том что она ловит 301 редирект при обращении к /assets/components/yandexmoney/connectors_result.php который вы указываете как постоянную ссылку для обработки кодов ответа

yandex.kassa.error.2

Я проверил POST запросы на этот URL и никакого 301 там не было, всегда было 200 ок.

yandex.kassa.post

Но спорить с поддержкой Яндекс.Кассы было бесполезно. Поэтому в коде connectors_result.php я нашел следующее и закоментировал. В дальнейшем убрал комментарии, так как планирую писать обработчик.

  1. /*
  2. if ($_GET['fail'] == 1){
  3.   if ($res = $modx->getObject('modResource', $config['fail_page_id'])) {
  4.   $modx->sendRedirect($modx->makeUrl($config['fail_page_id'],'','','full'));
  5.   }
  6.   exit;
  7. }elseif($_GET['success'] == 1){
  8.   if ($res = $modx->getObject('modResource', $config['success_page_id'])) {
  9.   $modx->sendRedirect($modx->makeUrl($config['success_page_id'],'','','full'));
  10.   }
  11.   exit;
  12. }*/

Долгое время отлаживая ошибки, я ловил вот такое сообщение

yandex.kassa.card.no

Если видите подобное, не ломайте голову, пишите сразу в support. Серьезно, я до сих пор понимаю откуда они взяли проблему с 301 редиректом, и по какой причине они ее сняли. Но если бы не написал, то потратил еще больше времени разбираясь.

Но потом, после исправления некоторых багов, окошко изменилось на такое

yandex.kassa.ok

Данные для проведения тестового платежа находятся по этой ссылке https://tech.yandex.ru/money/doc/payment-solution/examples/examples-test-data-docpage/

После того, как тестовый платеж прошел, я написал об этом в поддержку, и мне заменили номер витрины с тестовой на боевую. Так же изменился url для отправления POST запроса. Все соответствующие настройки я внес в файл yandexmoney.class.php заменой scid на боевое значение и тестового режима с 1 на 0 ( url в таком случае выбирается автоматически )

        $this->test_mode = ($config['testmode'] == 0);
        //$this->shopid = ($config['testmode'] == 1);

 

Теперь вы можете принимать платежи. Отчеты о платежах будут приходить на ваш почтовый ящик, а также видны в личном кабинете.

yandex.kassa.reestr

Возврат платежей можно делать или при подключении мерчанта ( MWC ), но для этого нужно оформлять дополнительный договор и заверять ключ цифровой подписи. Или платежными поручениями в банк, на возврат. Для себя я выбрал второй вариант. Шаблон платежного поручения на возврат вы можете запросить у менеджера в службе поддержки или скачать по ссылке.

Вот так я потратил один день на подключение Яндекс.Кассы. В переключателе непонятно/вроде работает сейчас выбрана вторая опция ( это была шутка про программистов ). Ура, Яндекс.Касса подключена.

yandex.kass