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

Когда это становится проблемой

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

Что проверяю в первую очередь

  • Где проверяется баланс: frontend или backend
  • Используются ли транзакции и блокировки в базе
  • Что происходит при повторном запросе списания
  • Есть ли журнал начислений и списаний
  • Как обрабатываются отмены и возвраты

Как исправляю

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

  • Переношу финальную проверку баланса на сервер
  • Добавляю транзакции и блокировку строки баланса
  • Делаю списание идемпотентным по заказу
  • Исправляю отмены, возвраты и пересчет баланса

Что важно не сломать

Нельзя доверять сумме скидки, пришедшей с фронтенда. Пользовательский интерфейс можно изменить, а backend должен проверять все заново.

Что будет после исправления

  • Бонусы не списываются сверх доступного баланса
  • Повторные запросы не создают двойное списание
  • Есть журнал операций для разбора спорных случаев
  • Заказы получают корректную скидку

Что подготовить перед обращением

  • Пример клиента или заказа с ошибкой
  • Правила программы лояльности
  • Доступ к коду и базе
  • Логи списаний и начислений

Вопросы и ответы

Можно ли исправить без полной переделки?

Да, но нужно аккуратно поправить текущие балансы и закрыть причину, иначе ошибка вернется.

Сколько времени занимает диагностика?

Диагностика зависит от сложности бонусной системы. Финансовую логику нужно проверять тестами.

Нужна похожая задача?

Напишите в Telegram @rabotator_support и коротко опишите проблему. Я посмотрю симптомы, предложу понятный план работ и скажу, какие доступы нужны для безопасного исправления.