
В нашей компании принято устраивать звонки-знакомства — на них клиенты могут напрямую пообщаться с командами, которые будут им помогать или сопровождать. Во время таких встреч поднимается множество вопросов, в том числе связанных с интеграцией. Чаще всего вопросы одни и те же, поэтому я даже имею заготовленный спич, который позволяет на пальцах объяснить принцип работы нашей интеграции и быстро оценить сложность её реализации на своей стороне. Спич долго был только в моей голове, но для Хабра я решил изложить его в письменном виде и поделиться с вами.
? Сначала материал не разрешили публиковать — сочли его рекламным. Но когда узнали все детали — что через наш API можно формировать до 500 запросов в сутки бесплатно (а этого по опыту хватает в среднем на обработку 50 заказов), — «дали зеленый свет» и попросили указать все это в начале материала. Что я и делаю ? Заявку на подключение доступа можно оформить на сайте компании через форму обратной связи.
Шаг 1. Обновление цен и стоков
Первый поток данных, который нужно запустить. Информация о ценах и остатках должна транслироваться из системы клиента во все маркетплейсы. Инициатором обмена выступает система клиента — именно в ней происходит изменение цен и стоков.
Алгоритм работы сильно зависит от возможностей системы клиента, обычно реализуются следующие варианты:
Мгновенное обновление при событии
В учётной системе клиента произошло изменение цены или стока.
Учётная система клиента отслеживает это событие и в тот же момент вызывает методы передачи цены или стока (в зависимости от того, что изменилось) и отправляет новые значения в XWAY API.
XWAY API доставляет данные до маркетплейсов.
Таким образом, время, прошедшее с момента изменения данных в учётной системе клиента до обновления данных на маркетплейсе, составляет сотни миллисекунд, максимум 1-2 секунды. Это самый правильный сценарий, к которому стоит стремиться. Так сказать, идеальный мир интеграции ?
Запуск рекуррентного обновления по времени
У многих наших клиентов учётная система не может отследить изменение цены или стока, а значит, не может мгновенно запустить обмен и передать новые данные на маркетплейс. Поэтому они реализуют следующую логику:
Раз в N минут (параметр целиком и полностью зависит от конкретной системы) запускается сборщик, который пробегает по всей базе и выделяет массив товаров, где изменилась цена или сток за последние N минут.
Для найденных массивов товаров формируются соответствующие запросы на обновление цен или стоков и передаются в XWAY API.
XWAY API доставляет данные до маркетплейсов.
Очевидным минусом такого подхода является его дискретность. По опыту, наши клиенты, использующие данную схему, осуществляют отправку данных раз в 5 минут и реже. Если сделать чаще, то появляется высокая нагрузка на учётную систему клиента. Если сделать реже — увеличится вероятность продажи большего количества товаров, чем есть на складе.
Запуск полного обновления по времени
Самый печальный случай. Учётная система клиента по тем или иным причинам не может выделить товары, в которых произошли изменения цены или стока, поэтому производится отправка всего массива информации о товарах, ценах и остатках.
Раз в N минут (параметр целиком и полностью зависит от конкретной системы) запускается обмен по всем товарам, которые есть у клиента.
Для всех товаров формируются соответствующие запросы на обновление цен или стоков и передаются в XWAY API.
XWAY API доставляет данные до маркетплейсов.
Конечно же, дикие объемы передаваемых данных. Естественно, такой обмен невозможно сделать быстрым, хотя бы потому, что тут же начинаем упираться в лимиты по запросам маркетплейсов. Но если по другому нельзя, то можно и так сделать ?
Примеры методов
Обновление цен
Возможны 2 модели асинхронного взаимодействия, с использованием Webhook и без него.
Если используется Webhook:
В запросе продавец передаёт URL своего эндпоинта в параметре request_url.
{ "request_url": "https://seller.com/webhook/", "shop_id": 2145, "items": [ { "external_id": "204245576795", "price": 99987, "discount_price": 95000, "available": true, "batch_count": 1 }, { "external_id": "204245576797", "price": 39342, "discount_price": 30999, "available": false, "batch_count": 1 } ] }
После обработки запроса на указанный эндпоинт продавца придёт request_id.
Используя метод https://seller-api.xway.ru/api/v2/requests/{request_id} продавец получает результат выполнения запроса.
Если не используется Webhook:
В запросе продавец не передаёт параметр request_url.
{ "shop_id": 2145, "items": [ { "external_id": "204245576795", "price": 99987, "discount_price": 95000, "available": true, "batch_count": 1 }, { "external_id": "204245576797", "price": 39342, "discount_price": 30999, "available": false, "batch_count": 1 } ] }
В ответе на запрос продавец сразу получает request_id
Используя метод https://seller-api.xway.ru/api/v2/requests/{request_id} продавец получает результат выполнения запроса.
? В одном запросе нельзя передавать цену на один и тот же товар более одного раза.
? В одном запросе нельзя передавать массив более чем из 500 элементов.
Шаг 2. Получение заказов
Следующий поток данных, который нам нужно организовать для полноценной работы с маркетплейсами по схеме FBS — обмен информацией о заказах. Чем быстрее продавец получит заказ с маркетплейса и его обработает (зарезервирует товар под этот заказ), тем быстрее он сможет протранслировать новые значения остатков для товаров, которые были в заказе. И тем меньше вероятность оверсейла (продажи большего числа товара, чем есть на складе).
Однако зачастую маркетплейсы не выступают инициатором обмена и ждут, когда учётная система продавца обратится к ним за новыми заказами. Мы поддерживаем несколько схем получения заказа.
Продавец запрашивает новые заказы по расписанию
Продавец при разработке интеграции реализует в своей учётной системе метод, который с определённой периодичностью обращается к XWAY API и получает список новых заказов. То есть в качестве инициатора обмена выступает система продавца.
Понятно, что такая схема приводит к задержкам, напрямую зависящим от частоты запросов.
Если сделать частоту запросов слишком большой, то задержка уменьшится, но при этом увеличится нагрузка как на учётную систему продавца, так и на сервер XWAY API.
Если сделать частоту запросов слишком низкой, то задержка увеличится, что приведёт к оверсейлам.
Запрос на получение списка заказов достаточно простой. Это GET запрос, в котором можно с помощью параметров добавить дополнительную фильтрацию, например, по дате создания, дате изменения, статусу заказа и так далее.
Пример запроса на получение списка заказов для магазина с id 6414 и статусом delivered:
curl --request GET \ --url 'https://seller-api.xway.ru/api/v2/orders/?shop_id=6414&status=delivered' \ --header 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGci587IUzI1NiJ9.eyJ1c2VyX2lkIjo2MDQ1LCJ1c2VyX2d1aWQiOiI2ZWQzNDE2Yy03YmQzLTQyNTctYmQzYi1hZjRlNTYzNzE2OGEiLCJleHAiOjE2OTI4MDQyNTgsImF1dGhfbWV0aG9kX3R5cGUiOiJFTUFJTCIsImFjY291bnRzIjp7IlBBU1NQT1JUIjo2MDQ1LCJVTklDT1JOIjo1NTY2fSwicGVybWlzc2lvbnMiOnt9LCJpc194d2F5X2VtcGxveWVlIjpmYWxzZX0.Qf63EQ_kF-ZwIzJYIdC_izro1uTsh6q1zJslxsGcpuc' \ --header 'content-type: application/json
В ответ на подобный запрос XWAY API выдаст список заказов для данного магазина:
{ "meta": { "request_id": "a4a17610-9ee9-48f5-a33d-e888eb1846d2", "message": null }, "result": { "orders": [ { "id": 34511146, "shop_id": 6414, "order_id": "107586281", "marketplace_code": "beru", "created_at": "2022-04-27T03:00:00.000000Z", "modified_at": "2022-05-01T13:24:01.165000Z", "status": "delivered" }, { "id": 34511144, "shop_id": 6414, "order_id": "107857757", "marketplace_code": "beru", "created_at": "2022-04-29T03:00:00.000000Z", "modified_at": "2022-05-01T13:10:49.838000Z", "status": "delivered" } ] }, "pagination": { "limit": 100, "offset": 0, "total": 482 } }
Продавец получает информацию о новых заказах на webhook
Продавец при разработке интеграции реализует в своей учётной системе дополнительный эндпойнт (урл, webhook), адрес которого прописывается в XWAY API. Как только в XWAY API появляется информация о том, что у продавца на любом из маркетплейсов появился новый заказ, в тот же момент XWAY API отправляет уведомления на webhook продавца и селлер тут же вызывает метод получения нового заказа.
Такая схема работы чуть более сложна в реализации для продавца (ему нужно делать отдельный webhook и писать дополнительный обработчик), но обладает рядом важных преимуществ:
Оптимизация трафика между двумя системами. Обмен начинается только в том случае, если поступил заказ.
Ускорение обмена между двумя системами. Как только пришёл новый заказ, в тот же момент XWAY API отправляет соответствующее уведомление учётной системе продавца и запускается обмен информацией по заказу. Задержка между появлением заказа в XWAY API и в системе продавца уменьшается до 1 секунды.
Получения полной информации о заказе
Независимо от того, каким образом продавец получает информацию о новом заказе, в ней не содержится полная информация. XWAY API отдаёт только базовую информацию о том, что появился заказ или произошло изменение в существующем. Для получения полной информации продавец должен вызвать метод получения полной информации о заказе:
curl --request GET \ --url 'https://seller-api.xway.ru/api/v2/orders/34511146?shop_id=6414' \ --header 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJ589GciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo2MDQ1LCJ1c2VyX2d1aWQiOiI2ZWQzNDE2Yy03YmQzLTQyNTctYmQzYi1hZjRlNTYzNzE2OGEiLCJleHAiOjE2OTI4MDQyNTgsImF1dGhfbWV0aG9kX3R5cGUiOiJFTUFJTCIsImFjY291bnRzIjp7IlBBU1NQT1JUIjo2MDQ1LCJVTklDT1JOIjo1NTY2fSwicGVybWlzc2lvbnMiOnt9LCJpc194d2F5X2VtcGxveWVlIjpmYWxzZX0.Qf63EQ_kF-ZwIzJYIdC_izro1uTsh6q1zJslxsGcpuc' \ --header 'content-type: application/json'
В ответ XWAY API отдаст подробную информацию о заказе:
{ "meta": { "request_id": "d1268645-be96-4634-b814-07933c2dc819" }, "result": { "id": "42486407", "shop_id": 2848, "marketplace_code": "SMM", "order_id": "747378127", "created_at": "2022-08-01T11:56:45.000000Z", "modified_at": "2022-08-01T11:59:10.670598Z", "status": "delivered", "antifraud_status": null, "total_amount": 95.0, "memo": null, "order_items": [ { "id": 43273407, "xway_offer_id": 22763052, "external_id": "84.140", "sku_code": "22763052", "seller_price": 718.0, "buyer_price": 95.0, "subsidy": 623.0, "currency_code": "RUB", "name": "Антимоскитная сетка \"Герберы\" для дверного проема 2,1х1,0м", "quantity": 1, "is_cancel": false, "memo": null, "properties": [] } ], "buyer_info": { "name": null, "phone": null }, "delivery": { "delivery_status": null, "service_type": "fbs", "shipment_date": "2022-08-04T15:00:00+00:00", "warehouse_id": null, "delivery_price": 0.0, "delivery_type": null, "delivery_service": "delivery_by_goods", "customer": { "name": "Мина Мария", "phone": null, "address_full": "г Киров, ул Пушкина, д 15А", "address_detail": null }, "delivery_interval": { "from_date": "2022-08-07", "to_date": "2022-08-07", "from_time": "21:00", "to_time": "21:00", "timezone": "UTC+0" }, "shipments": [] }, "requirements": { "gtd": [], "country": [], "mandatory_mark": [], "rnpt": [] } } }
Шаг 3. Обработка заказа
Ну что же, заказ получили — теперь его нужно обработать :) Если бы вы делали интеграцию с каждым маркетплейсом отдельно, то тут бы было множество алгоритмов обработки заказа, каждый из которых бы зависел от конкретного маркетплейса.
Забудьте как страшный сон!
Мы всё уже сделали: свели все методы к единому набору, а все статусы — к единой статусной модели.
Вам без разницы, заказ с какого маркетплейса вы хотите обрабатывать. Просто всегда делайте одну и ту же последовательность шагов на складе и одну и ту же последовательность вызовов XWAY API:
Подтверждаем или отменяем товары в заказе.
Собираем заказ.
Получаем наклейку на упакованное отправление.
Создаём поставку.
Получаем документы на поставку.
ВСЁ! ?
Всего пять шагов, всегда стандартные пять шагов ?
Конечно, я мог бы далее расписать каждый из шагов, привести примеры кода…но мне кажется, это уже лишнее. Если вам действительно интересны технические детали, вы можете ознакомиться с ними в нашей документации https://seller-api.xway.ru/redoc
В заключении хочется выразить простую мысль, которую я хотел донести в этой статье:
Интеграция может быть простой и понятной.
Забудьте об особенностях каждого маркетплейса, о куче методов, механизмов авторизации, множестве ключей и кредов для каждого маркетплейса, о разных айди, каждый из которых называется по-своему и каждый из которых надо передавать в свои методы и в свои параметры. Просто сделайте одну интеграцию — и работайте спокойно, а всю эту головную боль можно делегировать экспертам :) Если у вас есть вопросы, буду рад ответить на них в комментариях или в Телеграм @anton_batashov
