Web-сервис обработки уведомлений по заказам СМ
- Назначение сервиса
- Обработка события order.created (создание заказа)
- Обработка события order.changed (изменение заказа)
- Обработка события order.paid (оплата заказа)
- Обработка события order.received (передача заказа в доставку)
- Обработка события order.delivered (доставка заказа)
- Обработка события order.cancelled (отмена заказа)
Назначение сервиса
Web-сервис предназначен для обработки уведомлений, которые СМ отправляет в Домино, и с помощью которых передаётся информация о создании, изменении состояния и отмене заказа со стороны СМ. Сервис реализуется в виде Домино web-сервера, при необходимости масштабирования при увеличении нагрузки может быть развернут пул из нескольких однородных web-серверов с балансировкой нагрузки через nginx proxy.
Web-сервис работает с данными БД Домино от имени специального пользователя SberMarketOrdersHook.
Сервис реализуется через единую точку доступа (хук), http- адрес которой партнёр передаёт в СМ. Так же партнёр генерирует и передаёт в СМ авторизационный токен для доступа к сервису. СМ для аутентификации в каждом запросе к сервису передаёт этот токен параметром заголовка Client-token. Cервис должен проверить полученный токен, и вернуть http-код 403 forbidden в случае ошибки.
Адрес точки доступа для отправки уведомлений по заказам со стороны СМ: https://компания.ru/sbermarket/orders/hook/
Спецификация Sbermarket Orders API Partner's WebHooks API находится здесь: https://docs.sbermarket.ru/api-products/other/orders/partners-webhooks . Данные о событии передаются в теле запроса в json формате. Тип события передаётся атрибутом event-type.
Сервис обрабатывает следующие уведомления о событиях СМ
- Создание заказа (order.created).
- Изменение заказа (order.changed).
- Оплата заказа (order.paid).
- Передача заказа курьеру (order.received).
- Доставка заказа (order.delivered).
- Отмена заказа (order.cancelled).
При обработке уведомлений нужно учитывать специфические особенности протокола СМ. Тайм-аут на ответ составляет 5 секунд. Если в течении этого времени не будет ответа или вернётся статус 4хх или 5хх, то у СМ начнут отрабатывать ретраи – сообщение будет отправляться повторно 7 раз с увеличивающимся интервалом. Если и это не поможет (для хука order.created), то система автоматически отменит заказ. Таким образом, может возникнуть ситуация, когда заказ в Домино создан, но СМ не дождался подтверждения и повторно отправил заказ. Web- сервис должен распознать эту ситуацию, и отправить СМ положительный ответ по уже созданному с Домино заказу, а не пытаться создать новый.
По всем уведомлениям, кроме order.created, сервис должен возвращать только http- код завершения. Содержание ответа (content) отсутствует.
Обработка события order.created (создание заказа)
Уведомление информирует ИС партнёра о появлении нового заказа в СМ. Результатом его обработки является создание нового документа «Заказ СМ» в БД Домино.
Алгоритм обработки:
- по номеру заказа СМ проверить существование документа «Заказ СМ» в БД Домино, если заказ существует, то завершить обработку с кодом 200 и вернуть номер созданного заказа,
- открыть транзакцию,
- по идентификатору магазина найти структурное и внутреннее подразделения,
- создать документ «Заказ СМ», статус документа «Новый», заполнить реквизиты шапки документа данными заказа,
- создать товарные строки документа «Заказ СМ», по идентификатору товара (SKU) найти товар Домино и сохранить его UID в строке,
- массивы кодов маркировки, если они есть, не обрабатываются,
- если любой из шагов внутри транзакции завершился с ошибкой, то откатить транзакцию,
- зафиксировать транзакцию (commit),
- записать в очередь телеграмм-уведомлений сообщения «Создан новый заказ NN» для магазина и всех его активных сборщиков,
- вернуть СМ номер созданного заказа и код 200 ОК
Структура ответа на уведомление order.created
{
"status" : "created",
"number" : "123456"
}
Обработка события order.changed (изменение заказа)
Уведомление может быть обработано при любом состоянии заказа, кроме «Доставлен» и «Отменен». Если заказ находится в статусе «Новый», и данные уведомления содержат информацию о товарах payload.positions, то состав заказа должен быть изменен. Во всех остальных случаях меняются реквизиты заказа, но не его состав.
Алгоритм обработки:
- открыть транзакцию
- найти документ заказа по идентификатору заказа СМ, заблокировать его от изменений
- если документ заказа с таким номером не найден, завершить обработку с кодом 404
- проверить статус заказа, если статус заказа равен «Доставлен» или «Отменен», то завершить обработку с кодом 200
- если статус заказа «Новый», и в уведомлении есть информация о товарах payload.positions, то заново загрузить состав заказа аналогично уведомлению order.crtated,
- обновить реквизиты шапки заказа, если они изменились,
- если любой из перечисленных выше шагов внутри транзакции завершился с ошибкой, то выполнить откат транзакции
- фиксировать транзакцию
- вернуть СМ код завершения
Обработка события order.paid (оплата заказа)
Уведомление может быть обработано при состоянии заказа «Собран» или «Передан курьеру». В остальных статусах это уведомление игнорируется. В уведомлении передается итоговая информации о ценах и суммах по позициям заказа - с учетом изменений по количеству и ассортименту, которые были сделаны в процессе сборки. В результате обработки уведомления в заказе устанавливается признак «Оплачен».
Алгоритм обработки:
- открыть транзакцию
- найти документ заказа по идентификатору заказа СМ, заблокировать его от изменений
- если документ заказа с таким номером не найден, завершить обработку с кодом 404
- проверить статус заказа, если статус заказа не равен «Собран» или «Передан курьеру», то завершить обработку с кодом 200
- записать в строки заказа итоговые цены и суммы из payload.positions, установить в шапке признак «Оплачен»,
- если любой из перечисленных выше шагов внутри транзакции завершился с ошибкой, то выполнить откат транзакции
- фиксировать транзакцию
- вернуть СМ код завершения
Обработка события order.received (передача заказа в доставку)
Уведомление может быть обработано только при состоянии заказа «Собран». В остальных статусах это уведомление игнорируется. В результате обработки заказ переводится в состояние «Передан курьеру», в поле «Дата передачи курьеру» записываются текущие дата-время.
Алгоритм обработки:
- открыть транзакцию
- найти документ заказа по идентификатору заказа СМ, заблокировать его от изменений
- если документ заказа с таким номером не найден, завершить обработку с кодом 404
- проверить статус заказа, если он не равен «Собран» - завершить обработку с кодом 200
- изменить статус заказа на «Передан курьеру», установить в шапке заказа дату передачи курьеру
- если любой из перечисленных выше шагов внутри транзакции завершился с ошибкой, то выполнить откат транзакции
- фиксировать транзакцию
- вернуть СМ код завершения
Обработка события order.delivered (доставка заказа)
Уведомление может быть обработано при состоянии заказа «Собран» или «Передан курьеру». В остальных статусах это уведомление игнорируется. В результате обработки заказ переводится в состояние «Доставлен», в поле «Дата доставки/отмены» записываются текущие дата-время. Если поле «Дата передачи курьеру» пусто, то оно устанавливается равным дате доставки. Если признак оплаты заказа не установлен, то он устанавливается, и в строки заказа прописываются итоговые суммы и цены из payload.positions - аналогично order.paid.
Алгоритм обработки:
- открыть транзакцию,
- найти документ заказа по идентификатору заказа СМ, заблокировать его от изменений
- если документ заказа с таким номером не найден, завершить обработку с кодом 404,
- проверить статус заказа, если он не равен «Собран» или «Передан курьеру» - завершить обработку с кодом 200,
- изменить статус заказа на «Доставлен», установить в шапке заказа дату доставки/отмены,
- если поле дата передачи курьеру не заполнено, то записать в него дату доставки,
- если не установлен признак «Оплачен», то записать в строки заказа итоговые цены и суммы из payload.positions, установить признак «Оплачен»,
- если любой из перечисленных выше шагов внутри транзакции завершился с ошибкой, то выполнить откат транзакции,
- фиксировать транзакцию,
- вернуть СМ код завершения
Обработка события order.cancelled (отмена заказа)
Это уведомление может быть обработано при любом состоянии заказа, кроме «Доставлен»
Алгоритм обработки:
- открыть транзакцию
- найти документ заказа по идентификатору заказа СМ, заблокировать его от изменений
- если документ заказа с таким номером не найден, завершить обработку с кодом 404
- проверить статус заказа, если статус заказа «Доставлен», то завершить обработку с кодом 422
- если статус заказа «Отменен», то завершить обработку с кодом 200
- изменить статус заказа на «Отменен», установить в шапке заказа дату доставки/отмены
- если любой из перечисленных выше шагов внутри транзакции завершился с ошибкой, то выполнить откат транзакции
- фиксировать транзакцию
- если статус заказа «В сборке» или «Собран», то записать в очередь телеграмм-уведомлений сообщения «Отменен заказ NN, причина – отмена СберМаркет» для сборщика и магазина,
- вернуть СМ код завершения