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

Нужно связать три сущности: платеж, возврат и доступ. Если одна из них обновляется отдельно и без надежного webhook, статусы быстро расходятся.

Коротко: что сделать

  • Проверить событие возврата от платежной системы
  • Найти подписку и текущий статус доступа пользователя
  • Проверить обработчик webhook refund
  • Проверить очередь фоновых задач
  • Проверить, есть ли ручные возвраты вне системы

Основные причины

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

  • Webhook возврата не обрабатывается
  • Возврат меняет платеж, но не меняет подписку
  • Доступ кешируется и не обновляется сразу
  • Есть отдельная таблица прав, не связанная с подпиской
  • Событие возврата пришло раньше события обновления платежа

Пошаговая диагностика

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

  • Сравнить статус платежа в платежной системе и в базе
  • Посмотреть логи webhook по payment_id
  • Проверить, какой код выдает доступ к платным разделам
  • Проверить фоновую очередь отключения доступа
  • Проверить ручной сценарий частичного и полного возврата

Как исправить проблему

Исправление должно закрывать первопричину, а не только маскировать симптом. Если затронуты доступы, платежи, данные клиентов или серверные настройки, сначала сделайте резервную копию и проверьте правку на тестовом сценарии.

  • Добавить обработчик refund.succeeded или аналога
  • Связать возврат со статусом подписки и правами
  • Сбросить кэш доступа после возврата
  • Сделать обработку webhook идемпотентной
  • Добавить аудит изменения доступа

Безопасный план решения

Не отключайте всем доступ массово. Выберите один тестовый аккаунт, проведите возврат в песочнице или на минимальной сумме и проверьте весь путь: webhook, статус, права, UI.

Чего не стоит делать

  • Не полагаться только на кнопку ручного возврата в админке
  • Не удалять подписку без истории платежей
  • Не отключать доступ по любому событию платежа без проверки типа события
  • Не игнорировать частичные возвраты

Что подготовить перед исправлением

  • Платежная система
  • ID платежа и подписки
  • Логи webhook
  • Правила доступа после полного и частичного возврата

FAQ

Нужно ли отключать доступ при частичном возврате?

Это зависит от правил сервиса. Логику нужно явно описать и реализовать, иначе будут спорные ситуации.

Почему webhook не пришел?

Может быть ошибка URL, подписи, таймаут, 500 ответ, неверный режим sandbox/production или выключенное событие.

Что такое идемпотентность webhook?

Повтор одного события не должен дважды менять данные или ломать состояние подписки.

Когда стоит обратиться за помощью

Обратиться стоит, если подписка связана с платным контентом, кабинетом, курсами, API или SaaS-доступом.

Итог

Проверьте webhook возврата, связь платежа с подпиской и сброс прав. Если нужно настроить надежное отключение доступа после возврата, пишите в Telegram @rabotator_support.