Заказ маркетплейса выглядит для покупателя единым, но исполняется несколькими продавцами, складами и доставками. Если статус хранится только на уровне общего order, действие одного продавца распространяется на чужие позиции и запускает каскадные возвраты, уведомления и отмены отгрузки.
Создайте тестовый заказ из двух продавцов и отмените одну позицию до и после подтверждения второй. Проследите, какие сущности изменились: order, seller order, строки, платежи, shipments, чеки и seller ledger. Отдельно проверьте, кто имеет право вызвать каждое изменение.
Что проверить в первую очередь
Для проблемы «отмена одним продавцом переводит в отменённое состояние весь заказ» сначала зафиксируйте один воспроизводимый пример: точное время, идентификатор объекта, пользователя или операции, входные данные, версию приложения и фактический результат. Отдельно запишите ожидаемое поведение: каждая часть заказа управляется своим продавцом и жизненным циклом, а общий статус является вычисляемым итогом, а не командой для всех позиций. Это не формальность. Без исходной точки легко принять временное совпадение за исправление, изменить сразу несколько условий и потерять возможность доказать настоящую причину сбоя.
Проверку начинайте с чтения состояния и журналов. Не запускайте массовый перерасчёт, повторную отправку, удаление записей или изменение прав на рабочей системе, пока не подготовлены резервная копия и способ отката. Секреты, токены, персональные данные и содержимое заказов в диагностические выгрузки не включайте.
- Уточните, существует ли отдельный seller order или fulfillment group.
- Проверьте, передаёт ли endpoint отмены item ID, seller order ID или общий order ID.
- Сверьте права продавца на каждую затрагиваемую строку.
- Посмотрите, как считается общий статус при смеси cancelled, processing и delivered.
- Проверьте, какие суммы уже зарезервированы, списаны или включены в выплату продавцу.
Почему возникает проблема
Видимый симптом обычно находится в конце цепочки. Пользователь видит неверный статус или отказ, хотя первичная ошибка могла произойти в API, фоновой задаче, кеше, очереди, внешнем сервисе либо при проверке доступа. Основной риск этого сценария: покупатель теряет товары других продавцов, возникают ошибочные возвраты, отмена доставки и неверные расчёты выплат. Поэтому исправление только интерфейса или ручная правка итоговой записи часто скрывает проблему, но не устраняет её.
Разбирайте события по хронологии и ищите первую точку, где фактические данные перестают соответствовать бизнес-правилу. В распределённой системе одинаково важны успешный ответ, повтор запроса, задержка события, параллельное выполнение и восстановление после временного отказа.
- Поле status общего заказа обновляется напрямую из кабинета продавца.
- Фоновая задача применяет событие seller_cancelled ко всем строкам с одним order ID.
- Оплата и доставка не разделены на компоненты по продавцам.
- Общий статус используется как причина отменить все shipment.
- Уведомление покупателю формируется без списка реально отменённых позиций.
Пошаговая диагностика
Создайте безопасный тестовый сценарий, максимально похожий на проблемный, но не затрагивающий реальные списания, рассылки и клиентские данные. Присвойте операции единый correlation ID и проследите его через входящий запрос, бизнес-логику, базу, очередь и внешние интеграции. Для каждого этапа фиксируйте вход, результат, код ответа, время выполнения и номер версии записи.
Сначала подтвердите сам факт расхождения, затем последовательно исключайте уровни. Сравните рабочий и ошибочный случаи по одним и тем же полям. Проверьте часовой пояс, формат идентификаторов, порядок событий, права сервисной учётной записи и актуальность конфигурации на каждом экземпляре приложения. Если результат зависит от повторного запроса, задержки или конкретного узла, это важная часть причины, а не случайный шум.
- Сопоставьте actor seller ID с owner seller ID каждой order item.
- Проследите доменное событие отмены и всех его consumers.
- Проверьте условие перехода общего заказа после частичной отмены.
- Сверьте refund amount только по отменённым строкам и их доле скидки.
- Проверьте уже собранные или переданные перевозчику части заказа.
Как моделировать составной заказ маркетплейса
Покупательский order является контейнером. Исполнение хранится на уровне seller order, shipment и item, а агрегированный статус рассчитывается по состоянию дочерних частей с учётом явной таблицы переходов.
Надёжная реализация хранит бизнес-состояние явно и не пытается восстановить его только по экрану, случайному логу или последнему webhook. У каждого значимого действия должен быть стабильный идентификатор, понятный владелец, версия правила и проверяемый переход статуса. Повторная доставка одного события не должна создавать второе действие, а запоздавшее событие не должно возвращать объект в невозможное состояние.
- Продавец изменяет только принадлежащий ему seller order и позиции.
- Отмена создаёт событие с item IDs, количеством, причиной и actor ID.
- Возврат платежа рассчитывается по отменённой части и сохранённому распределению скидок.
- Доставка отменяется только для связанного shipment, если он ещё допускает отмену.
- Общий статус различает частичную отмену, частичную доставку и полностью завершённый заказ.
Как исправить проблему
Исправление разделите на небольшие обратимые изменения. Сначала устраните подтверждённую первопричину, затем восстановите повреждённые данные отдельной контролируемой процедурой. Не смешивайте выпуск нового кода и массовую коррекцию истории в одном непрозрачном запуске: для них нужны разные отчёты, критерии успеха и планы отката.
Если затронуты существующие записи, сначала сформируйте dry-run: список объектов, старое значение, предлагаемое новое значение и основание для изменения. Обновление должно быть идемпотентным, ограниченным точной выборкой и сопровождаться аудитом. Для финансовых данных, прав доступа и персональной информации предпочтительны компенсирующие записи, а не переписывание истории.
- Введите seller order или fulfillment group как границу прав и статусов.
- Запретите продавцу прямое изменение общего order и проверяйте ownership на сервере.
- Перепишите consumers так, чтобы они обрабатывали список конкретных позиций.
- Рассчитывайте общий статус функцией без разрушительных побочных действий.
- Исправьте исторические заказы компенсирующими статусами и возвратами после сверки.
Безопасный порядок внедрения
- Сохраните конфигурацию, связанные записи и необходимые журналы; отдельно проверьте, что резервную копию действительно можно восстановить.
- Воспроизведите проблему на тестовом объекте и сохраните результат до изменения, чтобы после выпуска сравнить одинаковые сценарии.
- Внесите минимальное изменение под системой контроля версий, опишите причину, ожидаемый эффект, ограничения и точный способ отката.
- Прогоните нормальный сценарий, ошибочный ввод, повтор одного запроса, два параллельных запроса и временную недоступность зависимости.
- Выпустите изменение на ограниченную долю трафика или один процесс, если архитектура это позволяет, и сравните метрики со старой версией.
- Только после стабильного наблюдения выполните контролируемое исправление исторических данных и сохраните итоговый отчёт.
Как проверить результат
Один успешный пример недостаточен. Проверьте основную операцию повторно, крайние значения, одновременные действия, перезапуск процесса и восстановление после краткого сбоя сети. Результат подтверждайте не только экраном пользователя, но и состоянием базы, очереди, внешнего сервиса и журналом аудита. Особое внимание уделите тому, что система делает при повторной доставке уже обработанного события.
Критерии приёмки сформулируйте до выпуска. Каждый пункт должен давать однозначный ответ «выполнено» или «не выполнено», а не субъективную оценку. Если тест невозможно повторить автоматически, оставьте короткий регрессионный чек-лист с тестовыми данными и ожидаемыми статусами.
- Отмена продавца A не меняет processing и shipment продавца B.
- Покупатель получает уведомление с точным списком отменённых и продолжающих обработку товаров.
- Возврат равен только отменённой части с корректной скидкой и доставкой.
- Продавец не может передать item ID другого продавца вручную.
- Повтор события отмены не создаёт второй возврат и не меняет завершённую доставку.
Типичные ошибки при исправлении
- Использовать общий status как команду всем дочерним процессам.
- Доверять seller ID из запроса вместо авторизованного владельца.
- Пересчитывать скидку по текущему составу после частичной отмены без сохранённого правила.
- Отменять общий платёж целиком при частично исполненном заказе.
- Скрывать оставшиеся активные позиции после уведомления об одной отмене.
Опаснее всего исправление, которое убирает заметный симптом ценой отключения проверки, ослабления прав или потери аудита. Такое изменение может сделать интерфейс «зелёным», но увеличить ущерб при следующем сбое. Если временный обход всё же необходим, ограничьте его срок, пользователей и область действия, добавьте мониторинг и заранее назначьте дату удаления.
Как предотвратить повторение
Профилактика строится вокруг явных контрактов, идемпотентных обработчиков, наблюдаемости и повторяемых релизов. Система должна не только корректно работать сейчас, но и быстро показывать нарушение правила после обновления, роста нагрузки или отказа интеграции. Ошибку, которая уже привела к потере времени, денег, данных или заявок, стоит закрепить автоматическим тестом.
Настройте мониторинг полного пользовательского пути, а не только доступности отдельных серверов. Техническая метрика должна быть связана с бизнес-результатом: заказ завершён, доступ выдан, файл восстановлен, событие обработано один раз, данные изолированы. Порог оповещения задавайте по нормальному профилю нагрузки и проверяйте, что уведомление содержит достаточно контекста для первого решения.
- Число общих заказов со смесью активных и отменённых seller order.
- Каскадные изменения строк другого продавца после одного события.
- Расхождение refund и суммы отменённых компонентов.
- Ошибки отмены shipment, уже переданных перевозчику.
- Обращения покупателей о пропавших товарах после частичной отмены.
Что подготовить для технического разбора
- Короткое описание ожидаемого и фактического поведения с точной последовательностью действий.
- Время возникновения, идентификатор тестового объекта и версии всех затронутых компонентов.
- Обезличенные фрагменты журналов до и после ошибки с единым correlation ID.
- Список последних изменений, результаты уже выполненных проверок и условия, при которых симптом исчезает.
- Безопасный доступ к тестовой среде либо минимальный пример, не содержащий паролей, токенов и персональных данных.
Частые вопросы
Какой статус показывать общему заказу?
Лучше вычислять понятный статус вроде частично отменён или выполняется частично, сохраняя детали каждой части.
Можно ли разделить платёж после оплаты?
Да, если модель хранит суммы компонентов и платёжный провайдер поддерживает частичный возврат; расчёт должен идти из снимка заказа.
Что делать с общей доставкой?
Нужна отдельная модель shipment: одна доставка может содержать товары нескольких продавцов, поэтому правила отмены зависят от фактической группировки.
Когда нужна помощь специалиста
Если действие одного продавца отменяет весь заказ, я могу разделить границы статусов, прав, платежей и доставок и добавить тесты изоляции. Для оценки нужны схема order и order items, примеры событий и правила расчёта общего статуса.