Решение RollyPay

Приём платежей на сайте

Кнопка оплаты, страница с выбором СБП или карты и подписанный колбэк, по которому открывается заказ. Разработчику хватает одного рабочего дня, а на конструкторе сайта — получаса.

Обсудить мой сценарий

Приём платежей на сайте сводится к трём вещам: кнопка «Оплатить» создаёт платёж на вашем сервере, покупатель выбирает СБП или карту в платёжной форме, а доступ к заказу открывается после подписанного колбэка. Остальное — детали интеграции, и ниже они разобраны по порядку: что выбрать, сколько занимает запуск, где обычно теряются деньги.

Сценарий рассчитан на магазин цифровых товаров, онлайн-школу, SaaS с самостоятельной регистрацией — на любой сайт, где покупатель платит сам, без счёта и переписки в мессенджере. Если сайта ещё нет, начните с платёжных ссылок: оплата там работает вообще без вёрстки.

Что появится на сайте после подключения

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

Вы получаете список платежей с суммой, статусом и вашим order_id — тем же номером, что лежит в вашей базе. Сверять выручку с заказами можно по одному полю, а не по времени и сумме «примерно совпало».

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

Модуль CMS, ссылка или собственный код

Выбор зависит не от размера проекта, а от того, кто у вас правит сайт и насколько сложна логика заказа.

СпособКогда это ваш вариантСколько времени
Кнопка со ссылкой на оплатуОдин-два товара с фиксированной ценой, лендинг на конструкторе, нет разработчика20–40 минут
Плагин или готовый модуль магазинаТоваров десятки, корзина уже считает сумму сама, правки делает контент-менеджерПолдня вместе с тестами
Интеграция по APIДинамическая цена, промокоды, тарифы, выдача доступа сразу после оплатыОдин рабочий день на разработчика

Переход между способами не ломает данные: если вы с самого начала пишете свой order_id в каждый платёж, замена кнопки на API не потребует переносить историю. Именно поэтому первый шаг — не выбор технологии, а нормальная таблица заказов.

Форма оплаты, которую доводят до конца

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

Не заставляйте выбирать способ оплаты дважды. Если вы не передали payment_method, покупатель выберет СБП или карту прямо в форме — этого достаточно. Дублирующий выбор на вашей странице добавляет шаг и снижает конверсию.

Ставьте в description название товара так, как покупатель видел его в каталоге. Это самая дешёвая правка, которая снижает количество вопросов «а за что списали».

Интеграция: порядок действий и код

  1. Создайте кассу и получите ключи. Вам понадобятся X-API-Key кассы и signing_secret для проверки колбэков. Секреты держите в переменных окружения, а не в репозитории.
  2. Сохраните заказ до похода в платёжный сервис. Строка в таблице orders: кто купил, что купил, сумма, status = pending.
  3. Создайте платёж. POST /api/v1/payments с заголовками X-API-Key и X-Nonce — уникальный UUID на каждый запрос, живёт 10 минут. Повтор того же nonce вернёт 401 nonce already used.
  4. Отправьте покупателя на pay_url. Это адрес вида https://pay.rollypay.io/pay/<token> из ответа.
  5. Обработайте колбэк и только после него переведите заказ в оплаченный.
POST /api/v1/payments
X-API-Key: <ключ кассы>
X-Nonce: 3f0c1c2e-77d4-4a1b-9f2e-b0c15d9ab112

{
  "amount": "1490.00",
  "payment_currency": "RUB",
  "order_id": "web-10473",
  "description": "Курс по вёрстке, тариф Базовый",
  "success_redirect_url": "https://example.ru/thanks?order=10473",
  "metadata": {"user_id": 8814}
}

В ответе придут payment_id, status, pay_url и expires_at. Поле metadata вернётся к вам в колбэке нетронутым — удобно класть туда идентификатор пользователя, чтобы не искать его по сумме. Подробный разбор запросов есть в статье про API приёма платежей.

Почему заказ нельзя открывать по редиректу

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

Правда о деньгах живёт в колбэке на ваш callback_url. В заголовке X-Signature приходит HMAC-SHA256 hex от строки X-Timestamp + "." + сырое тело запроса, ключ — signing_secret кассы. Считайте подпись до разбора JSON и сравнивайте её constant-time сравнением, иначе проверка бесполезна.

События бывают трёх видов: payment.paid, payment.canceled, payment.expired. Обрабатывайте их идемпотентно — повторная доставка одного и того же payment.paid не должна отправлять покупателю второй ключ. Как устроена проверка, подробно показано в материале о проверке подписи webhook.

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

Статус продавца, чеки и возвраты

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

Фискальная часть остаётся за продавцом. Самозанятый выбивает чек в приложении «Мой налог» и следит за годовым лимитом 2,4 млн ₽; ИП и компании работают со своей кассой по 54-ФЗ. Правила возврата пропишите на сайте до запуска, а не после первого спора — покупатели цифровых товаров читают эту страницу чаще, чем кажется.

Пять ошибок, которые стоят выручки

  • Заказ создаётся после оплаты. Тогда при сбое непонятно, кому вы должны товар. Пишите строку в базу до создания платежа.
  • Сумма считается на фронтенде. Открытая консоль браузера превращает цену в любую другую. Считайте на сервере.
  • Один X-Nonce на все запросы. Второй платёж просто не создастся, а покупатель увидит ошибку без объяснений.
  • Колбэк отвечает 500 из-за упавшей рассылки. Сначала подтвердите приём события, отправку письма унесите в очередь.
  • Нет страницы «оплата не прошла». Человек с отклонённой картой должен сразу увидеть кнопку «попробовать снова», иначе он уходит навсегда — что делать в таких случаях, разобрано в статье о непрошедших платежах.

Чек-лист запуска

  1. Оферта, описание товара и правила возврата опубликованы на сайте.
  2. Ключ кассы и signing_secret лежат в переменных окружения.
  3. Таблица заказов пишется до обращения к платёжному API.
  4. Колбэк проверяет подпись и переживает повторную доставку без второй выдачи.
  5. Страницы «спасибо» и «не получилось» существуют и открываются на телефоне.
  6. Тестовый платёж проведён с реального смартфона, а не только из десктопного браузера.

Когда эти шесть пунктов закрыты, сайт можно открывать на трафик. Дальше настраивается только то, что действительно приносит деньги: причины отказов, скорость выдачи и удобство формы.

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

Сколько занимает подключение оплаты к сайту?

Кнопка со ссылкой на оплату ставится за 20–40 минут и не требует разработчика. Интеграция по API занимает примерно один рабочий день: создание платежа, обработка колбэка и тестовый прогон. Отдельно закладывайте время на модерацию — категорию проекта и условия подтверждают до запуска.

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

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

Можно ли считать заказ оплаченным, когда покупатель вернулся на страницу «спасибо»?

Нет. Адрес из success_redirect_url открывается в браузере покупателя, его можно скопировать из истории, а можно не открыть совсем — например, если оплата шла в приложении банка. Статус меняйте только по событию payment.paid с проверенной подписью X-Signature.

Что произойдёт, если колбэк придёт дважды?

Повторная доставка — штатная ситуация, сервис перепосылает событие, если не получил подтверждения. Ищите заказ по своему order_id и меняйте статус только из состояния pending. Тогда второй колбэк ничего не сломает и покупатель не получит второй ключ.

Кто выдаёт чек покупателю?

Чек — обязанность продавца, а не платёжного сервиса. Самозанятый формирует его в приложении «Мой налог» и следит за годовым лимитом 2,4 млн ₽, ИП и компании используют собственную кассу по 54-ФЗ. Платёжный сервис отвечает за техническую часть: приём денег и уведомление о результате.