Бронирование мест с оплатой в песочнице
На мероприятие «Клуба» продаются места через учебного платёжного провайдера. Пока пользователь проходит оплату, место временно удерживается за ним. Однако ответ об оплате может прийти после окончания удержания или повториться несколько раз. Спроектируйте процесс так, чтобы система не обещала одно место двум людям и могла разобраться в неизвестном исходе платежа.
Реальные деньги не используются. Все суммы, уведомления и действия провайдера относятся к песочнице; числа нагрузки заданы для учебного проектирования.
Ограничения
Есть 500 мест, пиковый поток — 300 попыток бронирования в секунду. Временное удержание места, hold, действует 10 минут. Провайдер присылает уведомление на сервер, webhook; такое уведомление может дублироваться и приходить после истечения удержания. Нельзя считать порядок прихода уведомлений достоверным порядком бизнес-событий.
Что подготовить
Запишите инварианты — правила, которые должны сохраняться после любого допустимого действия. Например, число подтверждённых и ещё действующих временных бронирований не должно превышать вместимость. Уточните, какие состояния учитываются в этом ограничении.
Постройте схему состояний удержания, оплаты и подтверждения места. Для каждого перехода укажите инициатора, проверяемое условие, сохраняемые данные и поведение при повторе. Выберите ключи идемпотентности: идентификаторы, позволяющие узнать повтор того же действия и не выполнить его эффект второй раз.
Опишите сверку с провайдером: как система найдёт платежи с неизвестным результатом и сопоставит их с бронированиями. Разберите отдельно потерянный ответ на запрос и потерянное уведомление.
Подсказка
Проследите гонку между истечением удержания и подтверждением платежа. Вызов внешнего сервиса не становится атомарным вместе с вашей базой. Компенсация, например учебный возврат платежа, создаёт новое бизнес-действие и сохраняет историю произошедшего.
Как проверить решение
Одновременные запросы и повторы не должны приводить к продаже лишних мест. Поздний платёж должен попадать в определённый процесс: компенсацию либо ручной разбор с явным статусом для пользователя. Покажите, что вызов провайдера не объявлен частью локальной SQL-транзакции. Проверьте сбой между сохранением оплаты и отправкой подтверждения, а также повтор самой компенсации.
Усложнение
Уведомление об оплате потеряно навсегда, но статус доступен через API провайдера. Определите расписание сверки, предел ожидания и действия после получения окончательного результата.
Как оформить ответ
Сохраните состояния, инварианты и несколько трасс событий в тетради. Сравните варианты обработки позднего платежа и объясните продуктовый выбор. Здесь нет автоматической экспертной оценки архитектуры.
Запишите ход рассуждений, расчёты и вопросы. Сохраните текст перед уходом со страницы. После входа в аккаунт ответ участвует в общей синхронизации прогресса. Автоматической оценки архитектуры здесь нет.