Интеграция с маркетплейсами на примере Ozon и Wildberries. Как мы это сделали

Всем привет. Меня зовут Татьяна Цикунова, я работаю системным аналитиком в компании МойСклад, в команде eCommerce. Моя команда специализируется на разработке интеграций сайтов с сервисом МойСклад. Мы помогаем бизнесу автоматизировать процессы: учета, продаж, коммуникаций с клиентами, выход на новые торговые площадки. Также мы разрабатываем интеграции с самыми популярными маркетплейсами на рынке России и зарубежных стран У МоегоСклада уже есть решения для селлеров на Ozon, Wildberries, Яндекс Маркете и Мегамаркете, а также для зарубежных маркетплейсов.

В статье я расскажу о том, что такое эти самые интеграции с маркетплейсами на примере сравнения наших решений для Ozon и Wildberries. 

ecb97331b7786a29cdd15bb55e4ee84e.png

Сначала приведу немного статистики от Data Insight. Чтобы понимать, насколько сейчас популярна торговля на маркетплейсах, достаточно взглянуть на слайды ниже. 

8e5b7f615f213bbb6637c0f7cb78335a.png

Сегодня огромное количество селлеров торгуют на маркетплейсах. Многие из них — это достаточно большой бизнес. Им необходимо вести корректный учет своих товаров. Именно эту потребность закрывает команда eCommerce в МоемСкладе. 

В статье мы пройдем основной путь селлера на маркетплейсе, рассмотрим, с какими основными данными он работает и подробнее познакомимся с тем, как мы реализовали интеграции МоегоСклада с WB и Ozon.

Основной путь селлера на маркетплейсе

Итак, какой путь проходит селлер на маркетплейсе, чтобы начать продавать свои товары? Давайте разбираться. На Ozon и WB пути могут немного отличаться, но основные шаги одинаковы.

  1. Определить, какой товар будет продаваться на площадке.

  2. Зарегистрироваться на маркетплейсе.

  3. Принять оферту.

  4. Загрузить товары на маркетплейс, т.е. заполнить карточки товаров информацией, которую в итоге увидит покупатель.

    1. Загрузить цены на товары.

  5. Выбрать схему продажи (со своего склада, со склада маркетплейса и т.д.).

  6. Выбрать склад, с которого будет отгружаться товар.

    1. Добавить остатки по товарам, которые будут продаваться с этого склада.

    2. Оформить поставку товаров на маркетплейс, если продажи будут со склада маркетплейса.

  7. После получения заказа нужно подтвердить и собрать заказ, если селлер торгует со своего склада.

Как выглядят разные схемы работы маркетплейсов на примере Ozon:

FBO (со склада маркетплейса)

FBO (со склада маркетплейса)

FBS (со склада селлера)

FBS (со склада селлера)

Подробнее о том, как начать работать на Ozon и WB, вы можете посмотреть, перейдя по ссылкам: Ozon, WB.

Как мы видим, можно выделить несколько основных направлений, с которыми ежедневно работают селлеры:

  • Товары

  • Заказы

  • Цены

  • Остатки

  • Склады

Чтобы понимать, сколько товаров продается на маркетплейсах, и какой доход и прибыль они принесут селлеру, нужен корректный учет. Если продавец использует несколько площадок для реализации своего товара, то вести учет в одном месте удобнее. Эту потребность продавцов закрывает МойСклад с помощью интеграции со всеми упомянутыми площадками. 

Какие процессы можно реализовать в рамках интеграции с маркетплейсами

Итак, суммируя опыт разработки решений по Ozon и WB, можно сделать вывод, что сначала нужно ознакомиться с документацией к API. Важно понять, как авторизоваться для получения доступа к взаимодействию между системами. 

Для того, чтобы начать работать с API маркетплейсов, нужно взять авторизационные данные из личного кабинета селлера и вызвать один из методов, описанных в документации пользовательского API. Если он ответит успехом, то все хорошо, можно работать. 

Обобщая наш опыт работы с обоими маркетплейсами, первичный процесс авторизации выглядит для пользователя достаточно просто. Пользователь МоегоСклада устанавливает приложение маркетплейса на платформе МойСклад, заходит в интерфейс приложения и вводит свои авторизационные данные. 

Чтобы отобразить пользователю результат авторизации, мы вызываем один из основных методов API, например, метод, который возвращает список товаров. Далее логика достаточно проста. Если маркетплейс отвечает успехом, то мы отображаем успешное подключение, если нет — выдаем ошибку. 

Ozon

WB

Доступы

28 категорий доступов. Ключ с доступом Admin дает право на все возможные операции. 

12 разделов, на которые поделены все методы API: Контент, Маркетплейс, Статистика, Аналитика, Продвижение, Рекомендации, Цены и скидки, Вопросы и отзывы.
Можно создать токен с доступом к любой комбинации этих разделов. 

Также можно создать токен только для чтения данных.

После успешной авторизации логичным продолжением является переход к работе с товарами.

Товары

Для любых дальнейших задач нам нужно сделать синхронизацию товаров. Товары — основополагающая сущность в работе маркетплейсов. Возможно 2 кейса. Первый — когда товары уже есть в вашей системе, и вы хотите сопоставить их с товарами из маркетплейса. Второй — у вас нет товаров в системе, и вы хотите их создать по аналогии с заведенными товарами на маркетплейсе. Обращу внимание, что маркетплейсы предоставляют возможность как создавать товары через API, так и получать их. Для создания товаров через API нужно последовательно вызывать набор методов, который вернет все данные с категориями товаров, ограничениями и т.д. И далее отправить в маркетплейс данные по создаваемым товарам. Например, в Ozon эта цепочка будет выглядеть так:  

  • Сначала нужно получить список категорий и типов в виде дерева. Нужно использовать значение последнего уровня выбранной категории;

  • Далее получите характеристики для выбранных категории и типа;

  • Получите список значений для выбранной характеристики;

  • И только после этого можно загружать товары в соответствии с данными маркетплейса.

Также можно получить данные для создания или сопоставления товаров на стороне вашей системы. 

Для того, чтобы работать с товарами, важно сначала получить все товары в нужном нам статусе. Например, товары, которые поместили в архив, или, которые находятся на проверке, нам не подойдут. Далее система должна обработать полученные товары. Как нам понять, есть ли у пользователя такие товары в системе или их нужно создать? Для этого мы использовали сложный алгоритм поиска соответствий и создания связи товаров в нашей системе и маркетплейсом. 

Настройки связей товаров в реализации МоегоСклада

Общий вид настроек для WB

Общий вид настроек для WB

Ozon

WB

Идентификаторы

Можно выбрать сопоставление по Штрихкодам, Артикулам, Код — Артикул

Можно выбрать сопоставление по Штрихкодам, Артикулам Продавца, Артикулам WB

В маркетплейсе есть наборы, комплекты и разные варианты товаров по размеру и цвету. Система может найти соответствие со всеми сущностями, но создает только товары

В маркетплейсе есть наборы, комплекты и разные варианты товаров по размеру и цвету. Наша система может найти соответствие со всеми сущностями, но создает только товары и варианты размеров как модификации товара

Типы цен

Минимальная цена

Цена до скидки

Ваша цена (после скидки)

Цена до скидки (Розничная)

Цена со скидкой

Итак, наша система получила json со списком всех актуальных товаров из маркетплейса. Мы ищем соответствие товаров в нашей системе, используя указанный пользователем идентификатор. Из маркетплейса приходит, как правило, несколько идентификаторов для каждого товара. Там есть артикулы продавца, баркоды, уникальные артикулы маркетплейса и т.д. Если наша система находит соответствие, то делается запись в таблицу связи товаров в нашей БД. Таблица хранит связи товаров, модификаций и комплектов. Если система не нашла совпадений, то такой товар создается на нашей стороне, а также делается запись в таблице связей в БД. К слову, мы используем реляционную БД, что идеально подходит под наши цели. 

Отдельно можно сказать про модификации и комплекты. Сначала уточню, что же такое комплекты. Комплект — это товар, который состоит из нескольких одинаковых товаров или нескольких разных товаров. Комплекты приходят к нам из маркетплейсов как товары, т.е. нет возможности вытащить из json-а информацию о том, из чего состоит комплект. Поэтому мы берем идентификатор такого товара и ищем совпадение, в т.ч. среди комплектов в нашей системе. Таким образом мы можем создать только связь товара из маркетплейса и комплекта в нашей системе. Создавать комплекты по итогу синхронизации пока не представляется возможным. 

Модификации тоже добавляют свои сложности. Например, в WB у товара могут быть модификации по размеру и по цвету. Проанализировав примеры ответов от WB, мы пришли к выводу, что можем точно определить модификациями только разные размеры одного товара, так как они имеют одинаковый идентификатор, принадлежащий одному товару, в отличии от товаров разного цвета. Таким образом, мы разработали сложный механизм работы с поиском и созданием модификаций на нашей стороне. Также мы дали возможность пользователям выбирать, как создавать варианты размеров в нашей системе. Хотят ли они создавать размеры одного товара как отдельные товары или они предпочитают создавать размеры как модификации главного товара.  

Часть задокументированных кейсов, которые могут возникнуть при поиске соответствий товаров

Часть задокументированных кейсов, которые могут возникнуть при поиске соответствий товаров

Если пользователь подключает автосинхронизацию товаров, то наша система каждые 15 минут запрашивает товары из маркетплейса и обновляет данные на стороне МоегоСклада. 

Кратко опишу, как работает автосинхронизация в описываемой фиче:

1. Пользователем включается тоггл автосинхронизации.

2. В БД хранится информация о периодичности автозапуска (как часто нужно проводить автосинхронизацию).

3. Система смотрит по логам, когда стартовала последняя синхронизация и прибавляет 15 минут к найденному значению. Далее значение сверяется с текущим временем. Текущая синхронизация запускается по истечении 15 минут после запуска последней синхронизации, но не ранее окончания предыдущей синхронизации. Если время запуска еще не пришло, то через 30 секунд система повторит проверку. 

4. Таким образом, система собрала данные, по каким интеграциям и какой вид синхронизации нужно запустить (товары, остатки, заказы, отчеты, цены).
5. Система отправляет сообщение в очередь (что-то похожее на Kafka, но свое) с информацией о необходимости запустить нужную синхронизацию. На каждую синхронизацию — свой топик.
6. На другой стороне консьюмер вычитывает очередь. Исходя из того, из какого топика пришло сообщение, оно двигается в определенный процессор.
7. Реализованы процессоры под каждый вид синхронизации.
8. Процессор определяет, какому типу интеграции принадлежит сообщение (Ozon, WB и т.д.)…9. Процессор делегирует запуск синхронизации конкретному обработчику (класс с бизнес-логикой) по конкретному типу коннектора, который уже воспроизводит бизнес-логику обращения к маркетплейсу.

Диаграмма BPMN

Диаграмма BPMN

Чтобы пользователь видел, что его товар связан с товаром из маркетплейса, мы отображаем иконки площадки в карточке товара. Мы заранее передаем на фронт информацию о том, что товар связан с товаром из WB или Ozon. Фронт распознает этот признак и отображает иконки.

c1679caa9b93647b4d63e3cab1a1294c.png

Остатки

После того, как система получила данные о товарах, которые есть в маркетплейсе, она может реализовать передачу остатков по этим товарам. В маркетплейсах реализована как возможность передавать и получать остатки по товарам, которые продаются со склада продавца, так и передавать данные об остатках, которые хранятся на складах маркетплейсов и продаются с них же.

Сначала упомяну про остатки по схеме FBO. Селлер может торговать со склада маркетплейса. В таком случае он отгружает товар на склады и далее только отслеживает данные, смотрит на приходящие заказы, следит за остатками. Маркетплейсы предоставляют возможности разработчикам получать данные об остатках товаров на складах через API. 

Можно увидеть, какое количество товара на каких складах хранится. Мы в свою очередь реализовали целый отчет в нашей системе, где показываем количество товаров на складах маркетплейсов, количество товаров в пути, а также считаем, на сколько дней хватит остатков, основываясь на статистике продаж и возвратов за последний месяц.

А теперь поговорим об остатках по системе FBS, когда селлер хранит товары на своих складах и упаковывает заказы сам. 

Ozon

WB

Ссылка на используемый метод

https://api-seller.ozon.ru/v2/products/stocks

https://suppliers-api.wildberries.ru/api/v3/stocks/{warehouseId}*

*Идентификатор склада передается в path параметре

Пример json

{

  "stocks": [

    {

      "offer_id": "PH11042",

      "product_id": 313455276,

      "stock": 100,

      "warehouse_id": 22142605386000

    }

  ]

}

{

  "stocks": [

    {

      "sku": "BarcodeTest123",

      "amount": 10

    }

  ]

}

Ответ

Возвращается развернутый ответ по каждому товару, переданному в запросе. Может точно сказать, какие результаты по каждому товару.

Возвращается общий ответ с кодом 204ok, если все хорошо или 4хх/5хх, если произошла ошибка. (спросить у разработчиков, что делаем если ошибка)

Как выглядит настройка синхронизации в МоемСкладе

Как выглядит настройка синхронизации в МоемСкладе

МойСклад является мастер-системой для ведения учета товара, иными словами, мы агрегируем все изменения в разных каналах продаж и выводим пользователю его актуальные остатки. Поэтому очень удобно, что наша система знает об актуальных (реальных) остатках на складах пользователя и может передавать эти данные в маркетплейс. 

Итак, для того, чтобы передать остатки на маркетплейс, нам нужно провести следующие операции:

  1. Понять, с какого склада на какой нужно передать данные. Для этого пользователь сопоставляет склады в системе МоегоСклада в настройках синхронизации. Мы в свою очередь храним эти данные в отдельной таблице в БД.

  2. Понять, по каким товарам нужно передать остатки. Для этого у нас есть таблица связи товаров. 

  3. Подсчитать в нашей системе, сколько каждого товара осталось на выбранном складе.

  4. Инициировать вызов метода API и передать данные в требуемом виде.

Отдельно стоит остановиться на том, как мы организовали передачу остатков по комплектам. Если система обнаруживает, что ей нужно передать остаток по товару, который является комплектом в системе МойСклад, то производится расчет, исходя из остатков комплектующих этого комплекта. Например, в комплект входят два мяча и 1 корзина. На складе есть 3 мяча и 5 корзин. Следовательно, мы можем собрать только 1 комплект из этих остатков. Система передает в маркетплейс остаток в количестве 1. 

Если пользователь включает автосинхронизацию остатков, то система передает в маркетплейс информацию об изменившихся остатках каждые 5 минут.

Как итог, у маркетплейса теперь есть актуальные данные о товарах, поэтому можем переходить к заказам. 

Заказы

У Ozon есть два основных способа передачи заказов. Первый, это вебхуки, которые позволяют интегрирующимся системам получать информацию о заказах, не запрашивая каждый раз данные через вызов методов API. 

Если настроить интеграцию по данной схеме, то маркетплейс сам будет отправлять вашей системе уведомления о новых заказах и об изменениях в уже созданных заказах. 

Есть и вторая схема, на которой мы остановимся подробнее. Для того, чтобы получить информацию о новых заказах, система должна запросить данные о заказах с помощью вызова API методов.

Пример ответа c заказом от WB

{
  "orders": [
    {
      "address": null,
      "deliveryType": "fbs",
      "user": null,
      "orderUid": "22558161_20279080578355735",
      "article": "2222",
      "rid": "20279080578355735.0.0",
      "createdAt": "2023-06-14T15:24:32Z",
      "offices": [
        "Москва"
      ],
      "skus": [
        "2037984989340"
      ],
      "id": 875410111,
      "warehouseId": 754386,
      "nmId": 165229335,
      "chrtId": 275157918,
      "price": 4600,
      "convertedPrice": 4600,
      "currencyCode": 643,
      "convertedCurrencyCode": 643,
      "isLargeCargo": false
    }
  ]
}

Пример ответа с заказом от Ozon

{
  "result": {
    "postings": [
      {
        "posting_number": "31669659-0036-1",
        "order_id": 20315567579,
        "order_number": "31669659-0036",
        "status": "awaiting_packaging",
        "delivery_method": {
          "id": 23970565018000,
          "name": "Доставка Ozon самостоятельно, Москва",
          "warehouse_id": 23970565018000,
          "warehouse": "Домашний склад",
          "tpl_provider_id": 24,
          "tpl_provider": "Доставка Ozon"
        },
        "tracking_number": "",
        "tpl_integration_type": "Ozon",
        "in_process_at": "2023-06-20T09:43:41Z",
        "shipment_date": "2023-06-30T06:00:00Z",
        "delivering_date": null,
        "cancellation": {
          "cancel_reason_id": 0,
          "cancel_reason": "",
          "cancellation_type": "",
          "cancelled_after_ship": false,
          "affect_cancellation_rating": false,
          "cancellation_initiator": ""
        },
        "customer": null,
        "products": [
          {
            "price": "480.000000",
            "offer_id": "5432654",
            "name": "Тай Пин Хоу Куй зеленый крупнолистовой чай",
            "sku": 741323263,
            "quantity": 1,
            "mandatory_mark": [],
            "currency_code": "RUB"
          }
        ],
        "addressee": null,
        "barcodes": null,
        "analytics_data": {
          "region": "Москва",
          "city": "Москва",
          "delivery_type": "PVZ",
          "is_premium": false,
          "payment_type_group_name": "Картой онлайн",
          "warehouse_id": 23970565018000,
          "warehouse": "Домашний склад",
          "tpl_provider_id": 24,
          "tpl_provider": "Доставка Ozon",
          "delivery_date_begin": "2023-07-02T18:00:00Z",
          "delivery_date_end": "2023-07-02T19:00:00Z",
          "is_legal": false
        },
        "financial_data": {
          "products": [
            {
              "commission_amount": 0,
              "commission_percent": 0,
              "payout": 0,
              "product_id": 741323263,
              "old_price": 600,
              "price": 480,
              "total_discount_value": 120,
              "total_discount_percent": 20,
              "actions": [
                "СуперХиты. О!Распродажа"
              ],
              "picking": null,
              "quantity": 1,
              "client_price": "",
              "item_services": {
                "marketplace_service_item_fulfillment": 0,
                "marketplace_service_item_pickup": 0,
                "marketplace_service_item_dropoff_pvz": 0,
                "marketplace_service_item_dropoff_sc": 0,
                "marketplace_service_item_dropoff_ff": 0,
                "marketplace_service_item_direct_flow_trans": 0,
                "marketplace_service_item_return_flow_trans": 0,
                "marketplace_service_item_deliv_to_customer": 0,
                "marketplace_service_item_return_not_deliv_to_customer": 0,
                "marketplace_service_item_return_part_goods_customer": 0,
                "marketplace_service_item_return_after_deliv_to_customer": 0
              },
              "currency_code": "RUB"
            }
          ],
          "posting_services": {
            "marketplace_service_item_fulfillment": 0,
            "marketplace_service_item_pickup": 0,
            "marketplace_service_item_dropoff_pvz": 0,
            "marketplace_service_item_dropoff_sc": 0,
            "marketplace_service_item_dropoff_ff": 0,
            "marketplace_service_item_direct_flow_trans": 0,
            "marketplace_service_item_return_flow_trans": 0,
            "marketplace_service_item_deliv_to_customer": 0,
            "marketplace_service_item_return_not_deliv_to_customer": 0,
            "marketplace_service_item_return_part_goods_customer": 0,
            "marketplace_service_item_return_after_deliv_to_customer": 0
          },
          "cluster_from": "",
          "cluster_to": "Москва ЮАО 1"
        },
        "is_express": false,
        "requirements": {
          "products_requiring_gtd": [],
          "products_requiring_country": [],
          "products_requiring_mandatory_mark": [],
          "products_requiring_rnpt": [],
          "products_requiring_jw_uin": []
        },
        "parent_posting_number": "",
        "available_actions": [
          "cancel",
          "ship"
        ],
        "multi_box_qty": 1,
        "is_multibox": false,
        "substatus": "posting_created",
        "prr_option": ""
      }
    ]
  }
}

Итак, чтобы получить заказы нужно вызвать определенные методы API. Но как же организовать процесс так, чтобы не пропустить ни одного заказа? Давайте рассмотрим, как такой процесс организовали мы.

Чтобы создавать заказы, которые пользователь увидит и обработает, система периодически запрашивает данные у маркетплейса. Схема работы с заказами похожа на то, что мы видели в описании работы с товарами. Так же, как и в товарах, у нас есть таблица связи, которая хранит данные о том, что заказ, созданный в МоемСкладе пришел к нам из конкретного маркетплейса.

Давайте рассмотрим на примере WB:

  1. Вызываем метод, который возвращает только новые заказы.

  2. Проверяем, есть ли заказ с таким идентификатором в нашей системе.

    1. Если есть —  пропускаем данный заказ (он уже создан).

    2. Если нет — создаем такой заказ и делаем запись в таблицу связи.

  3. В заказах есть товары, поэтому мы включили в процесс импорта заказов в том числе  импорт товаров.

  4. Система проверяет, есть ли товары, которые пришли в заказах, в МоемСкладе.

    1. Если нет, то система дополнительно вызывает методы, которые возвращают данные по нужным товарам, чтобы создать их. В противном случае мы не сможем создать актуальный заказ

    2. Если есть, то все ок.

Еще мы столкнулись с проблемой пропуска некоторых заказов. В маркетплейсах у заказов есть своя схема статусов. Мы строили наш процесс так, чтобы забирать только новые заказы. Это облегчает и ускоряет процесс импорта заказов. Однако за время между автосинхронизациями (когда мы запрашиваем заказы у маркетплейса), селлер может перевести заказ в другой статус, поэтому в списке новых заказов мы его не увидим и не создадим в нашей системе. Выход был очевиден — мы расширили процесс импорта заказов и теперь создаем заказы и в других статусах, чтобы не сбивать правильный учет пользователей. 

Пример таблицы связей для заказов:  

Поле

Тип

Ограничения

Описание

id

uuid

NOT NULL

ntype

int4

NOT NULL

Тип сущности, задаваемый числовым значением

entity_id

uuid

NOT NULL

Ссылка на операцию, которую необходимо связать с внешним уникальным идентификатором

external_id

varchar (255)

NOT NULL

Внешний уникальный идентификатор

account_id

uuid

NOT NULL

Аккаунт, владеющий данными

connector_id

uuid

NOT NULL

Идентификатор коннектора

Для того, чтобы не превышать лимиты по вызову методов маркетплейса, мы реализовали работу с рейтлимитами. В МоемСкладе есть сервис, который проверяет отправляемые запросы на частоту и количество. При разработке устанавливается лимит, который будет соблюдаться для конкретного метода. Если частота запроса превышает этот лимит, то такой вызов блокируется. Система ожидает условий для возобновления работы и продолжает пропускать запросы.  Данный подход мы применяем для каждого вызываемого метода с рейтлимитом. Алгоритм очень схож с Leaky Bucket. Почитать подробнее можно в книге «System Design. Подготовка к сложному интервью» Сюй Алекс.

Развивая синхронизацию заказов, мы также реализовали обмен статусами: как из маркетплейса в нашу систему, так и наоборот. Теперь пользователи могут получать этикетки и собирать заказы с помощью листа подбора. 

Мы с вами уже разобрали 3 основные сущности, в которые мы регулярно добавляем новые фичи. Однако, обмен товарами, остатками и заказами были бы бесполезны, если бы цены не менялись на протяжении всего времени. Именно поэтому четвертой важной сущностью обмена являются цены. 

Цены

Маркетплейсы позволяют получать актуальные цены товаров и передавать новые цены. Получив новые данные, маркетплейсы обновляют цены, проводя валидацию на своей стороне.

Ozon

WB

Типы цен

Ваша цена

Обязательная цена в нашей интеграции. 

Цена, по которой продавец собирается продавать товар. Это не конечная цена продажи, т.к.могут быть применены акции, а также скидка от Ozon, за которые маркетплейс начисляет баллы селлеру. 

Розничная цена

Обязательная цена в нашей интеграции. 

Цена, которую покупатель видит зачеркнутой. 

Цена до скидки

Цена, которую покупатель видит зачеркнутой. От нее считается скидка в процентах. 

Цена со скидкой

Цена, по которой продавец собирается продавать товар.

Минимальная цена

Цена, ниже которой товар не будет продаваться.

Методы API

Для обновления цен https://api-seller.ozon.ru/v1/product/import/prices

Для обновления цен товаров без размеров https://discounts-prices-api.wb.ru/api/v2/upload/task

Для обновления цен товаров с размерами 

https://discounts-prices-api.wb.ru/api/v2/upload/task/size

Проверить состояние загрузки https://discounts-prices-api.wb.ru/api/v2/history/tasks

Получить детализацию загрузки https://discounts-prices-api.wb.ru/api/v2/history/goods/task

Пример тела запроса Ozon для передачи цен по товару

{
  "prices": [
    {
      "auto_action_enabled": "UNKNOWN",
      "currency_code": "RUB",
      "min_price": "800",
      "offer_id": "",
      "old_price": "0",
      "price": "1448",
      "price_strategy_enabled": "UNKNOWN",
      "product_id": 1386
    }
  ]
}
Hidden text

Пример тела запроса WB для передачи цен по товару

{
  "data": [
    {
      "nmID": 123,
      "price": 999,
      "discount": 30
    }
  ]
}

В этом разделе я подробнее расскажу про наш опыт работы с ценами. В МоемСкладе есть существенная разница между реализацией обмена в Ozon и в WB. Тут, как говорится, первый блин…(зачеркнуто). Первые цены мы делали в Ozon, поэтому там без наворотов, и все достаточно лаконично реализовано. Мы взяли все основные типы цен из маркетплейса и перенесли их на наш UI, чтобы пользователь мог сопоставить тип цены из Ozon и тип цены в МоемСкладе. МойСклад является мастер-системой, поэтому цены передаются из нашей системы в маркетплейс. Мы называем это экспортом цен. Цены передаются только по тем товарам, по которым произошли изменения со времени последней синхронизации. В МС реализована функциональность массового обновления разных типов цен, поэтому пользоваться изменением цен в нашей системе и передавать эти данные в маркетплейс  достаточно удобно. 

b94cb0679dc4d2d12069479a5c396d9b.png

Связи типов цен мы также храним в базе данных в таблице с настройками синхронизаций. 

WB мы делали следом за Ozon, поэтому подошли к этой задаче уже с бэкграундом. Нашей целью было сделать синхронизацию по аналогии с Ozon, но усовершенствовать функциональность. 

Мы реализовали не только экспорт цен, но и дали пользователям возможность обновлять цены в нашей системе по ценам маркетплейса. В итоге у нас получился следующий набор опций по работе с ценами в WB:  

  • Запись актуальных цен из маркетплейса при синхронизации товаров;

  • Импорт цен из маркетплейса в нашу систему;

  • Экспорт цен из нашей системы в маркетплейс в любой момент времени;

  • Автоэкспорт цен из нашей системы в маркетплейс с периодичностью в 15 минут.

Пользователь может остановиться на любой из этих опций. В зависимости от того, какой функциональностью пользуется селлер в данный момент, мы показываем разные состояния экрана настройки синхронизации цен. Для того, чтобы определять, какое состояние экрана показать, мы храним настройку в базе со следующими вариантами:

Выдуманное_название_поля — Состояние таба импорта/экспорта цен в Wildberries;

  • 0 — импорта/экспорта цен не было, импорт доступен;

  • 1 — таб цен в состоянии импорта цен (он в процессе/успешен/с ошибками/…);

  • 2 — доступен экспорт цен с рекомендацией о предварительном импорте;

  • 3 — состояние после импорта и до экспорта без рекомендаций;

  • 4 — состояние после первого экспорта.

Ранее ВБ не разрешал устанавливать разные цены на размеры одного товара (модификации в системе МойСклад), но недавно правила изменились. Теперь вы можете зайти на сайт маркетплейса и увидеть у некоторых товаров с разными размерами разные цены. В API также реализована возможность передавать разные цены для размеров на определенные категории товаров. 

Склады

Еще одной важной сущностью при работе с маркетплейсами являются склады. Их может быть более одного как в интегрирующейся системе, так и в маркетплейсе. Склады важно учитывать при передаче остатков из системы в маркетплейс, а также при получении заказов, так как товары из заказов резервируются не в воздухе, а на конкретных складах, отгружаются и принимаются тоже на какой-то склад. 

Поэтому перед тем, как сделать экспорт остатков из системы в маркетплейс, пользователю нужно выбрать, с какого на какой склад передавать остатки.

Ozon

WB

Методы для получения списка складов с МП

https://api-seller.ozon.ru/v1/warehouse/list

https://suppliers-api.wildberries.ru/api/v3/warehouses

Возможности АПИ в разделе Склады

Получить список всех складов

Получить список методов доставки

Получить все склады ВБ

Получить все склады продавца

Создать, обновить, удалить склад продавца

Как выглядит наш раздел с настройками связи складов:

bc47f0b931438939c31c2161b7273032.png

И да, для сопоставления складов у нас тоже есть таблица в БД, где мы храним выбор продавца. Селектор со складами маркетплейса работает стандартно. При открытии страницы мы подгружаем из маркетплейса через вызов метода API список активных складов и отображаем его в дропдауне. Пользователь может сопоставить несколько складов из маркетплейса нескольким складам в МС. 

Как отслеживать изменения в партнерском API маркетплейсов

Итак, мы рассмотрели основные моменты базовой интеграции системы с маркеплейсами. Но остается вопрос, как же поддерживать и развивать то, что сделано в базовой версии. 

Работать с внешним API достаточно сложно. Почти каждый спринт мы сталкиваемся в той или иной степени с изменениями, которые влекут доработки на нашей стороне. Приведу примеры:

  • Подняли версию метода;

  • Внесли изменение в запрос или ответ;

  • Удалили метод и порекомендовали перейти на другой;

  • Метод не работает долгое время;

  • Переход на новые токены для большей безопасности;

  • Изменение лимитов на вызовы методов.

Все эти изменения требуют ежедневного мониторинга. Есть большие риски пропустить новости и нарваться на дедлайн, после которого вся ваша интеграция сломается. Именно поэтому мы тщательно следим за новостями маркетплейсов. Ниже оставлю полезные ссылки на источники новостей.

После того, как «сталкер» увидел новость об изменении, которое затрагивает и может сломать интеграцию, информация об этом доносится до команды разработки. Далее принимается решение, что с этим делать. Как правило, мы заводим задачу: аналитик пишет описание  (что изменилось и что нужно сделать), продакт ставит приоритет, и далее задачу берутразработчики. Иногда маркетплейс публикует новость с конкретным дедлайном, до которого нам нужно внести изменения в нашу систему. Тогда все этапы работы над изменениями планируются в такие сроки, чтобы успеть к дедлайну. 

Наши планы

В статье описаны не все фичи, которые реализованы в наших синхронизациях с МП. Я затронула только основные пользовательские сценарии. Однако, несмотря на то, что интеграции имеют уже достаточно развитую функциональность, остается много работы. Вот что мы планируем внедрить в нашу работу в ближайшем будущем:

  • Переход на пуш-уведомления. Объясню на примере заказов. Сейчас все наши синхронизации построены на принципе polling, когда мы запрашиваем данные у маркетплейса, как бы все время пингуем, есть ли что-то новое. Пуш-уведомления позволяют не запрашивать данные вхолостую, магазин будет сам присылать их нам. Например, заказы, как только они появляются в системе маркетплейса.

  • Развитие схемы работы по FBO. Сейчас наши интеграции нацелены на пользователей, которые собирают заказы на своих складах и отправляют их в маркетплейс для доставки покупателю. Но есть и другая схема работы. Когда селлер заранее отправляет товары на склад маркетплейса, и заказы собираются именно там. Сейчас мы уже реализовали отображение остатков на складах маркетплейса через ежедневную автосинхронизацию. В дальнейшем мы будем развивать наши интеграции, добавляя в эту схему работы новые фичи.

  • Развитие нашей основной функциональности. 

Итак, друзья, я считаю, что описала все основные моменты в работе над созданием интеграции с такими маркетплейсами, как Ozon и Wb. Оставляйте вопросы и комментарии под этим постом.

В тг-канале МоегоСклада публикуются новости для предпринимателей, реальные кейсы, ошибки и лайфхаки в учете, инструменты продвижения, обновления сервиса МойСклад.

Habrahabr.ru прочитано 1611 раз