Вопрос с собеса Middle/Senior на 300K+ в ВТБ 💳
Кейс: пользователь отправляет перевод в 1000 рублей через мобильное приложение. Интернет заглючил в момент нажатия «Отправить». Пользователь не понимает, прошел платеж или нет, и нажимает кнопку еще раз.
На бэкенд прилетают два одинаковых запроса на один перевод 🤔
Вопрос: Что должно произойти в системе дальше? И как ты, как аналитик, пропишешь это в требованиях, чтобы не потерять ни деньги, ни клиента?
Меня не раз спрашивали такое на собесах в финтехе – обычно уже после базовых вопросов, когда хотят понять, работал ли я с реальными платежами.
Если коротко – система должна быть идемпотентной. Проще говоря: сколько бы раз ни пришел один и тот же запрос – деньги спишутся только один раз 🫂
Как это должно работать и что писать в ТЗ: 1. При первом запросе Перед отправкой платежа фронтенд (мобильное приложение) генерирует уникальный ключ идемпотентности (idempotency_key). Это как номер чека или штрихкод операции. Ключ привязывается к сумме, получателю и счету списания. Система сохраняет этот ключ и начинает обработку перевода.
Что прописать в ТЗ: • Формат и генерация ключа (например, UUID v4) • Срок жизни (например, 24 часа) • Место проверки
2. При повторном запросе с тем же ключом Когда запрос приходит на бэкенд, система первым делом проверяет: не обрабатывался ли уже запрос с таким же idempotency_key?
Возможные сценарии и реакция системы (прописываем в ТЗ): • Ключ новый, тогда система создает новую транзакцию, резервирует деньги, начинает обработку и сохраняет ключ в статусе «в обработке». • Ключ уже есть, статус «в обработке», тогда система не создает новую транзакцию, а возвращает клиенту ответ: {“status”: “processing”, “message”: “Ваш платеж уже выполняется.”}. • Ключ уже есть, статус «успешно», тогда система не списывает деньги повторно, а возвращает детали успешно проведенной ранее транзакции: {“status”: “success”, “transaction_id”: “12345”}.
Где проверять? ТЗ должно определять точку проверки: например, на уровне API-гейтвея или на уровне самих платежных сервисов.
3. Ответ пользователю Самое страшное – когда пользователь не понимает, списались деньги или нет. Повторный ответ должен однозначно объяснять, что происходит.
Прописываем в ТЗ: • Если перевод уже в работе, показываем «Платеж выполняется, ожидайте» • Если перевод уже прошел, показываем «Перевод успешно завершен [дата, время]» • Никаких 500 Internal Server Error без человеческого объяснения на клиенте
4. Аудит и мониторинг Даже если логика идеальна, нужна перестраховка.
Что заложить в ТЗ: • Логирование всех дублей (ключ, статус, transaction_id) для аудита • Ежедневная сверка сумм и количества транзакций с журналом запросов • Метрика «Количество отклоненных дублей» в дашборде (резкий рост = проблемы со связью)
Почему это так важно?
Без такого механизма банк рискует: 1. Деньгами: возвраты, комиссии, ручные операции 2. Репутацией: клиент, с которого списали дважды, уйдет с негативом 3. Юридическими рисками: нарушение договора об оказании услуг
С того собеса я вынес, что это идеальный фильтр. Мидл скажет про idempotency_key. Сеньор спросит: «А какой у вас SLA на возврат ошибочных списаний и сколько это стоит бизнесу в квартал?».
Потому что важно показать, что понимаешь реальную цену ошибки в деньгах, времени и доверии 😴
Моя формула ответа: Я опишу в ТЗ сквозной механизм идемпотентности на основе ключа, с явными статусами обработки, правилами ответов для фронта и требованиями к аудиту.
Нужно гарантировать, что N одинаковых запросов = 1 успешная операция.
И добавлю требование на ежедневную сверку платежей – на случай, если что-то ускользнет от основной логики.
Опытный аналитик проектирует систему, которая остается надежной даже тогда, когда все идет не по плану. Именно это и стоит 300к+ в серьезном банке 🤱