Рубрики
Технологии

OrderPaid пришёл, а заказ уже отменён. Кто принимает…

OrderPaid пришёл, а заказ уже отменён. Кто принимает решение?

Разработчик пишет в чат: «Технически всё работает». Очередь жива, сообщение валидное, обработчик отработал без ошибок.

Но есть нюанс: пока событие OrderPaid шло по брокеру, заказ уже успели отменить.

Деньги куда-то надо девать. Возврат? Игнор? Ручная разборка? Если это заранее не согласовали в требованиях, финансовое решение принимает код. Не бизнес. Не аналитик. А случайный if в обработчике, написанный в пятницу вечером.

Как это выглядит на практике На одном из проектов отмена уходила синхронно (холд снят, статус CANCELLED), а успех от внешнего шлюза прилетал асинхронно, с задержкой в минуту.

Утром поддержка видела картину: в админке заказ «Отменён», а в финансовой витрине по нему висит «Успешная оплата». Клиент звонит со скриншотом списания.

Фраза «пусть утренняя сверка разберётся» здесь не работает. Сверка приходит Т+1, а клиент звонит сразу. Поддержка видит «Отменён» и говорит, что платежа не было. Клиент присылает выписку. Доверие потеряно, тикет эскалирован.

Что я теперь фиксирую в спецификации до кода Опыт подсказывает, что happy path работает только в презентациях. В проде деньги и статусы всегда пытаются разойтись. Поэтому в разделе интеграции я больше не пишу абстрактное «Обработать событие OrderPaid».

Там появляются конкретные правила:

  1. Источник истины. Если на момент получения OrderPaid статус заказа = CANCELLED, система НЕ меняет его на PAID.

  2. Фиксация расхождения. Вместо этого создаётся запись в таблице или топике payment_discrepancies (payment_id, order_id, время отмены, время события).

  3. Владелец и SLA. Чётко указано, кто и в какой срок разбирает эту очередь (автовозврат, если дорога открыта, или ручной чек оператора).

  4. Идемпотентность. Отдельной строкой: повторное получение того же OrderPaid с тем же ключом не плодит новые тикеты и не инициирует повторные движения денег.

Хорошая постановка задачи — это описание не только того, как система работает по плану, но и того, как она ведёт себя, когда всё идёт не по плану.

А как у вас решается эта гонка состояний: доверяете автоматике, отдаёте на откуп сверке или строите отдельный контур ручного разбора?