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

Свой обработчик оплаты - форма, уведомление, отметка платежа

Подключаем платёжную систему, для которой готового обработчика нет: уводим на оплату, принимаем уведомление и отмечаем платёж в заказе.

Решение

Заводим каталог обработчика:

/local/php_interface/include/sale_payment/vendorpay/
.description.php - название и настройки, видимые в админке
handler.php - сам класс обработчика
template/payment.php - форма ухода на оплату
// каталог виден в списке обработчиков платёжной системы после создания
// имя каталога - в нижнем регистре и без слова handler, иначе класс не найдётся
// платформа ищет обработчики в трёх местах, и каталог проекта важнее системного

Обработчик собирается из описания, класса и шаблона. Описание рисует поля настроек в административной части, и ключи платёжной системы задают именно там, а не в коде.

Собираем уход на оплату:

namespace Sale\Handlers\PaySystem;
use Bitrix\Sale\PaySystem;
class VendorpayHandler extends PaySystem\ServiceHandler
{
public function initiatePay(PaySystem\Payment $payment, $request = null)
{
$this->setExtraParams(['SUM' => $payment->getSum(), 'ORDER_ID' => $payment->getOrderId()]);
return $this->showTemplate($payment, 'payment'); // шаблон формы ухода
}
}

Метод начала оплаты собирает форму, а не платёж. Он готовит данные и отдаёт шаблон, а дальше покупатель уходит на сторону платёжной системы, и сайт про него на время забывает.

Принимаем уведомление о платеже:

public function isMyResponse(\Bitrix\Main\Request $request, $paySystemId)
{
return $request->get('shop_id') === $this->getBusinessValue(null, 'VENDORPAY_SHOP');
}
public function getPaymentIdFromRequest(\Bitrix\Main\Request $request)
{
return (int)$request->get('order_id'); // по нему платформа найдёт платёж
}

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

Проверяем и отмечаем платёж:

public function processRequest(PaySystem\Payment $payment, \Bitrix\Main\Request $request)
{
$result = new PaySystem\ServiceResult();
if ($request->get('sign') !== $this->makeSign($request)) {
$result->addError(new \Bitrix\Main\Error('Подпись не сходится'));
return $result; // ничего не отмечаем
}
$result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
return $result;
}

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

Сырое уведомление стоит писать в журнал целиком, вместе с ответом обработчика. Разбор спорного платежа через месяц упирается ровно в это: без записи спор превращается в слово против слова.

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

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

Типичные проблемы

Деньги списаны, заказ не оплачен.

Страница обработчика недоступна снаружи или закрыта авторизацией на входе. Платёжная система приходит на неё сама, без сессии покупателя.

Оплата зачлась дважды.

Обработчик не различает повторное уведомление о том же платеже. Повторы считают нормой и отвечают на них одинаково.

Заказ помечен оплаченным на меньшую сумму.

Сумма из уведомления не сверяется с суммой платежа в заказе. Сверку суммы делают до отметки платежа, вместе с проверкой подписи.

Любой может пометить заказ оплаченным.

Подпись пришедшего уведомления не проверяется обработчиком вовсе, ни в каком виде. Проверка подписи - единственное, что отличает платёжную систему от постороннего.

На боевом сайте платежи уходят в тестовый контур.

В настройках обработчика так и остался включённым его тестовый режим. Режим работы и ключи задают настройками обработчика, а не правкой его кода.

Частые вопросы

Где хранить ключи платёжной системы?

В настройках обработчика в административной части. В коде и в репозитории им не место.

Как проверить обработчик до боевого запуска?

Тестовым контуром платёжной системы и повтором уведомления руками. Второй шаг ловит больше ошибок.

Нужен ли свой обработчик?

Только если готового для этой системы нет. Штатный обработчик получает исправления вместе с продуктом.

Что отвечать платёжной системе?

То, что описано в её документации, и ровно тем кодом ответа. Иначе она будет повторять уведомление сутками.

Смежное

Первоисточник