Как подключить рекуррентные платежи: пошаговый разбор для разработчика

2026-07-21 15:51:13 Время чтения 9 мин 108

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

Разберём, как это работает на практике.

Рекуррентный платеж — это сохраненные данные карты и автоматическое списание по расписанию. Без звонков клиенту, без «скиньте ссылку на оплату», без просроченных подписок из-за человеческого фактора. Технически требуется несколько API-запросов, токенизация карты и логика повторных попыток при неуспешном списании.

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

Начнём с того, что обычно понимают неправильно еще до первой строки кода.

Шаг 1. Разберитесь, что именно вы хотите автоматизировать

Рекуррентные платежи подключают двумя способами. Технически они отличаются. Первый — фиксированное автосписание. Одна сумма снимается в один день каждого периода. Подходит для подписок с единой ценой: SaaS-тариф, доступ к курсу, ежемесячный сервисный сбор. 

Второй — гибкое автосписание. Сумма каждый раз разная, карта клиента уже сохранена и не требует повторного ввода. Нужно интернет-магазинам с переменными корзинами, маркетплейсам и сервисам с потреблением по факту.

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

Шаг 2. Получите токен карты при первом платеже

При первой оплате клиент вводит данные карты в платежной форме. Провайдер возвращает не номер карты, а токен (строку вида card_tok_xxxxxx). Этот токен сохраняете в базе и используете для всех последующих списаний.

Процесс выглядит так. Клиент нажимает «Оплатить», завершает первый платеж. В вебхуке payment.succeeded вы получаете объект с полем payment_method.id или аналогичным (зависит от провайдера). Это и есть токен. Храните его в зашифрованном виде (требование PCI DSS, игнорировать которое нельзя).

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

Шаг 3. Настройте расписание списаний на своей стороне

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

Надежный инструмент для этого cron-задача или очередь задач (Celery, Bull, Sidekiq,  зависит от стека). Логика процесса простая. В нужную дату достаете из базы все активные подписки, у которых next_billing_date ≤ сегодня, и отправляете запрос на списание по сохраненному токену.

Предусмотрите состояния: pending, charged, failed, retry. Без них не получится корректно обработать неудачное списание. Типичная причина отказа в недостатке средств. В первые 24 часа после неудачного списания около 30% повторных попыток проходят успешно. Логика повторной попытки напрямую влияет на поступление выручки. 

Шаг 4. Обработайте сценарии с неудачным списанием

Отказ по карте не какое-то там исключение, а вполне штатная ситуация. Карта заблокирована, лимит исчерпан, банк требует подтверждения. Такое происходит у каждого сервиса с подписками. Без обработки этого сценария вы просто теряете платёж.

Минимальная рабочая схема повторной попытки: первый раз через 24 часа, второй через 72 часа, третий через 7 дней. После трёх отказов клиент должен получить уведомление с просьбой обновить карту или оплатить вручную. Здесь пригодятся вебхуки: провайдер отправляет событие payment.failed, вы ловите его, обновляете статус в базе и отправляете письмо или push-уведомление.

Не блокируйте доступ к сервису после первого отказа. Дайте клиенту grace period в 3–7 дней. Резкое отключение увеличивает отток сильнее, чем неоплаченный период.

Шаг 5. Настройте вебхуки и проверку подписи

Работать без вебхуков технически можно, но это плохая практика. Polling — запросы к API каждые N секунд нагружают и вашу инфраструктуру, и сторону провайдера. Вебхук сам приходит в нужный момент.

Базовая настройка такая: укажите endpoint в личном кабинете провайдера, убедитесь, что он доступен по HTTPS, реализуйте проверку подписи запроса. Подпись передается в заголовке X-Signature или X-Webhook-Token (алгоритм верификации описан в документации). Без проверки подписи любой может имитировать успешный платеж, отправив POST-запрос на ваш адрес.

Отвечайте на вебхук HTTP 200 в течение 5 секунд. Тяжелую логику (начисление баллов, отправку письма, обновление доступа) выносите в очередь, иначе получите таймаут и повторную доставку того же события.

Шаг 6. Проверьте соответствие требованиям перед запуском

Несколько обязательных пунктов, которые часто пропускают. Клиент должен явно согласиться на автосписания (чекбокс с текстом «Я разрешаю сохранить карту и списывать средства автоматически» на форме оплаты). Это требование платёжных систем, а не просто рекомендация.

Пользователь должен иметь возможность отменить подписку самостоятельно, без звонков в поддержку. Отсутствие этой функции нарушает правила Visa и Mastercard и часто приводит к чарджбэкам.

Токены карт храните только в зашифрованном виде. Большинство платежных провайдеров хранят токены у себя и отдают вам только идентификатор (самый безопасный вариант).

Шаг 7. Протестируйте полный цикл в песочнице

Тестирование в sandbox должно охватить четыре сценария: успешное первое списание и получение токена, успешное повторное списание по токену, отказ по карте и корректная отработка retry-логики, отмена подписки и прекращение дальнейших попыток списания.

Выкатить интеграцию в продакшн без этих четырёх проверок, значит гарантированно получить инциденты в первый расчетный день. Провайдеры с нормальной документацией (URLPAY, например) прямо указывает на необходимость тестирования сценария failed payment (предоставляют sandbox, который полностью повторяет поведение боевого API).

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

Шаг 8. Мониторьте метрики после запуска

После запуска нужны три цифры: процент успешных списаний (benchmark для SaaS 85–92%), процент восстановленных платежей после повторной попытки и показатель involuntary churn (отток из-за технических отказов по карте, не по желанию клиента).

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

URLPAY передает продавцам данные по статусам транзакций в реальном времени через те же вебхуки. Это позволяет строить аналитику на своей стороне без дополнительных запросов к API.

Итог

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

Если не хочется собирать это из трёх разных провайдеров, посмотрите на URLPAY. Один API закрывает карты, СБП, QR и платёжные ссылки, подключение продавца занимает от одного дня, документация с примерами запросов на urlpay.io/docs/api. Работает с ИП и самозанятыми без долгого онбординга.

Посмотреть, как все устроено изнутри, можно тут urlpay.io. Вопросы по интеграции направляйте в бот поддержки @url_pay_help_bot.