Web-сервис обработки уведомлений по заказам СМ Назначение сервиса 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, причина – отмена СберМаркет» для сборщика и магазина, вернуть СМ код завершения