Когда возврат по подписке не отключает доступ, пользователь получает деньги назад, но продолжает пользоваться платным функционалом. Это проблема не только денег, но и контроля прав.
Нужно связать три сущности: платеж, возврат и доступ. Если одна из них обновляется отдельно и без надежного 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.