Выгрузка товаров, цен и складских остатков в Ozon seller

Недавно сдал проект интеграции с ozon seller. Думал небольшая такая задачка, но оказалась — целый квест. И в первую очередь из-за нехватки нормальной документации и нормальной поддержки. Плюс система так устроена, что жуть.

В интернете хватает боли по этой части (например, эта или эта , а вот теперь еще от Леонида Каганова и эта (!)), а я решил добавить свою. Это лонгрид, держитесь.

Задача ставилась так. Сделать загрузку товаров, цен, остатков в ozon из файла Excel, который формировали из какой-то отраслевой старой 1С 8.2. Система не обновлялась и принципиально на старых движках 8.2. Поэтому от нее мы получаем что-то простое, типа выгрузки в Excel или xml

Пример записи ниже

После некоторого размышления я решил, что необходимо разработать простую конфигурацию на 1С 8.3, на БСП.

Общая схема

  • На входе есть файл xml с полями как в Excel (все данные текстовые), который появляется в определенной папке с определенным именем.
  • Система загружает файл xml как строки таблицы, создавая или обновляя карточки номенклатуры/характеристики.
  • В карточке характеристики устанавливаем флаг «Обновить карточку»
  • Далее вызывается процедура выгрузки в Ozon через из их API вызовом REST-сервисов
    • выгрузить/обновить карточку характеристики;
    • выгрузить/обновить цену;
    • выгрузить/обновить складской остаток;
    • выгрузить все.
  • На каждом этапе есть логи в виде регистров сведений

Передача данных в Озон

Коммуникация с Озон строится посредством REST-сервисов Озона, которые приведены в документации, которую я местами перечитывал бесконечно https://api-seller.ozon.ru и новая ее версия https://docs.ozon.ru/api/seller. В ответ тоже получаем данные, которые затем обрабатываем.

Теперь по структуре выгрузки в Озон, так как в этом основная сложность.

Структура карточки в Озон

Для идентификации карточки товара Озон использует offer_id (код поставщика), который поставщик передает в систему. Если карточка успешно загружена, то Озон присваивает карточке product_id (это может занять 3-5 дней пока идет модерация!). В дальнейшем, для идентификации товара можно использовать offer_id или product_id равноправно.

Также, обязательно у товара присутствует Категория товара — category_id, которая не может меняться у карточки (жестко привязывается при первой загрузке). Категория товара в терминах 1С — это Вид номенклатуры. Категория определяет набор Атрибутов товара (Набор свойств в терминах 1С). Атрибуты — могут быть примитивного типа или же это справочник со своим набором значений.

Термин ОзонТермин 1С (БСП, ERP)Сущность 1С
Товар (item)Характеристика номенклатурыСправочник «Характеристики номенклатуры»
АртикулНоменклатураСправочник «Номенклатура»
Категория товара (Category)Вид номенклатурыСправочник «Виды номенклатуры»
Характеристики товара (attributes)Набор свойствПлан видов характеристик «Наборы дополнительных реквизитов и сведений»
Значения (values)Дополнительные значенияПримитивные типы (Строка, число), Справочник «Дополнительные значения»
Соответствия понятий Озон и 1С

У номенклатуры есть набор свойств и у вида номенклатуры есть свой набор свойств. Вид номенклатуры в терминах Ozon — это категория товаров.

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

{«items»:
[{
«complex_attributes»: [],
«attributes»: [{
«complex_id»: 0,»id»: 85,»values»: [{«dictionary_value_id»: 5592388,»value»: «Brandname»}]},
{«complex_id»: 0,»id»: 4194,»values»: [{
«dictionary_value_id»: 0,»value»: «https://Brandname.ru/components/com_jshopping/files/img_products/051az_kb.jpg»}]},
{«complex_id»: 0,»id»: 5309,»values»: [{«dictionary_value_id»: 527117518,»value»: «Золото красное»}]},
{«complex_id»: 0,»id»: 5315,»values»: [{«dictionary_value_id»: 25661,»value»: «585»}]},
{«complex_id»: 0,»id»: 5326,»values»: [{«dictionary_value_id»: 39261,»value»: «18.5»}]},
{«complex_id»: 0,»id»: 5352,»values»: [{«dictionary_value_id»: 0,»value»: «4,41»}},
{«complex_id»: 0,»id»: 8229,»values»: [{
«dictionary_value_id»: 92590,»value»: «Кольцо»}]},
{«complex_id»: 0,»id»: 9048,»values»: [{
«dictionary_value_id»: 0,»value»: «Кольцо 010051 Аз»}]},
{«complex_id»: 0,»id»: 10289,»values»: [{
«dictionary_value_id»: 0,»value»: «010051 Аз»}]},
{«complex_id»: 0,»id»: 4180,»values»: [{
«dictionary_value_id»: 0,»value»: «Кольцо 010051 Аз»}]},
{«complex_id»: 0,»id»: 4191,»values»: [{
«dictionary_value_id»: 0,»value»: «Кольцо 051Аз выполнено из золота 585 пробы и украшено натуральными вставками: 1 Аметист зеленый триллион 12 мм на 12 мм, вес 5.71 карат Средний вес украшения — 4,41 грамм.»}]},
{«complex_id»: 0,»id»: 4195,»values»: [{
«dictionary_value_id»: 0,»value»: «https://Brandname.ru/components/com_jshopping/files/img_products/051/051az_kb1.jpg»}]},
{«complex_id»: 0,»id»: 4383,»values»: [{
«dictionary_value_id»: 0,»value»: «4,41»}]},
{«complex_id»: 0,»id»: 4384,»values»: [{
«dictionary_value_id»: 0,»value»: «украшение, бирка, коробочка»}]},
{«complex_id»: 0,»id»: 4389,»values»: [{
«dictionary_value_id»: 90295,»value»: «Россия»}]},
{«complex_id»: 0,»id»: 5289,»values»: [{
«dictionary_value_id»: 0,»value»: «Аметист зеленый»}]},
{«complex_id»: 0,»id»: 9024,»values»: [{
«dictionary_value_id»: 0,»value»: «Кольцо 051Аз»}]},
{«complex_id»: 0,»id»: 9163,»values»: [{
«dictionary_value_id»: 22881,»value»: «Женский»}]},
{«complex_id»: 0,»id»: 9233,»values»: [{
«dictionary_value_id»: 0,»value»: «true»}]},
{«complex_id»: 0,»id»: 9461,»values»: [{
«dictionary_value_id»: 970685248,»value»: «Золото кольцо со вставками женское»}]}],
«barcode»: «2200002013000»,
«category_id»: 78910355,»name»: «Золотое кольцо c Аметистом зеленым Brandname 585 пробы»,
«offer_id»: «Кольцо 051Аз 18.5»,
«height»: 10,»depth»: 40,»width»: 50,»dimension_unit»: «mm»,
«weight»: 4,»weight_unit»: «g»,
«images»: [«https://Brandname.ru/components/com_jshopping/files/img_products/051/051az_kb1.jpg»],
«file_name»: «https://Brandname.ru/components/com_jshopping/files/img_products/051az_kb.jpg»,
«vat»: «0»,
«price»: «53560»
}]}

В начале идет раздел с атрибутами. Возможны комплексные атрибуты (complex_attributes), но у нас их не было, передаю пустой массив. В разделе атрибутов — указывается complex_id — 0 (если нет), id — код справочника со значениями самого озона (их надо будет предварительно загрузить, я это опишу далее), далее — массив самих значений, у нас — только одно, не могу представить, почему тут может быть массив. Массив значений — тоже в виде кода значения справочника и представления его значения.

Например, для некого бренда- его код — 5592388, и определенное значение (это тоже надо будет предварительно загрузить, я это опишу далее). И так по каждой характеристике (Набору свойств). Если значение характеристики примитивного типа — только код справочника и значения. Например «Средний вес изделия, гр» — код справочника id = 5352, dictionary_value_id =0, значение ставим текстовое «4,41». После раздела с массивом характеристик — данные собственно карточки — категория, код поставщика, штрихкод, и проч.
Важно учесть, что некоторые характеристики обязательные, а некоторые — можно не заполнять.

Важно! Невероятно, но факт! В терминах 1С номенклатура является в Озоне как самостоятельная сущность отсутствует, является виртуальной сущностью, объединяемых общим Артикулом. То есть, чтобы связать товары в Озон необходимо, чтобы у товаров был одинаковый Артикул, а это специальная характеристика.

{«complex_id»: 0,»id»: 10289,»values»: [{
«dictionary_value_id»: 0,»value»: «010051 Аз»}]},

.

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

В 1С карточки характеристики и номенклатуры выглядят так:

Категория товара и его характеристики (атрибуты)

У каждой товара есть набор обязательных атрибутов

Помимо этого, есть категория товаров, которая определяет еще некий набор характеристик (у каждой категории — свой набор) со своими значениями. Например, для ювелирных изделий — проба (с фиксированным списком значений — «585», «925» и т.д.), обязательное поле, для других категорий, вообще не применимое.

Для загрузки использовался метод /v2/category/attribute, который возвращает необходимые нам атрибуты и их тип. После чего, если тип — справочник — нам необходимо загрузить их значения методом /v2/category/attribute/values. Это очень важная разовая процедура, причем разработчики озона предупреждают, что значения и даже состав характеристик может меняться без предупреждения. Так что держите ухо востро.

Загрузка в 1С из внешней системы

Теперь, когда мы научились формировать json для товаров, опишем как работает система в целом.

  1. Сначала обработка загружает карточки номенклатуры (и характеристик), используя файл xml, который лежит по определенному пути (на ftp). В файле присутствует вся информация о товаре, ценах и складских остатках. Реализована как внешняя обработка, запускается по расписанию, определяемым администратором.
  2. Затем обработка формирует запросы в ozon. Обработка загрузки была создана одна, но с 4 разными командами:
    • выгрузить карточки в ozon;
    • выгрузить цены в ozon;
    • выгрузить остатки в ozon.
  3. Все команды работают по своему расписанию
  4. Все пишется в журнал импорта. Важно хранить текст запроса и ответ озона. Для разбора проблем это очень важно

Изображения

Во-первых, есть требования по изображениям. А вот по формату передачи ссылок на изображения — в документации все нечетко написано, неоднозначно и без примеров. Вот фрагмент из документаци:

Но основной нюанс с изображениями с точки зрения формирования данных: это то в массиве изображений должно присутствовать «основное изображение», иначе выйдет ошибка при загрузке. Сразу даю живой пример, как должно быть в основном разделе:

И еще в разделе атрибутов- основное изображение (id 4194 «Изображение»)

И еще массив в разделе атрибутов — id 4195 «Изображения»

Короче, с картинками пришлось долго мучиться

Еще нюансы

Модерация проходит долго, несколько дней или дольше. Например, при отправке товара вы получаете в ответ номер задачи на создание. После чего через некоторое время получаете статус pending — товар на модерации. Через некоторое время (3 рабочих дня, иногда быстрее или дольше) получаете статус imported или ошибку и список ошибок. С ними еще придется научиться их понимать.

Техподдержка сильно перегружена и не всегда сама хорошо знает api ozon. Некоторые кейсы разбирали вместе долго и упорно. Готовьтесь и вы, запасайтесь терпением. Админ сайта до сих пор (уже 3 месяца!) пытается разобраться с отдельными ошибками (я подглядываю в их общий чат)

Выгрузка цен

Тут все просто, выгружаем массив по 1000 значений (ограничение Озона) с кодами поставщика и ценой со скидкой и без. Метод /v1/product/import/prices

Выгрузка остатков

Тут тоже все просто, выгружаем массив по 100 значений (ограничение Озона) с кодами поставщика и остатками. Метод /v1/product/import/stocks

Выводы

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

Если есть желание получить данное решение для экономии времени — пишите pavel.pche@gmail.com — о цене договоримся

UPD 05/09/2021

Появилось расширение от Озона, которое решает поставленные задачи для УТ11/КА2/ERP.
Вот описание (с загрузкой внутри) https://seller-edu.ozon.ru/docs/work-with-goods/zagruzka-1c.html

Я уже изучаю и настраиваю людям — напишу как будет материал

UPD 14/09/2021

Вот человек написал примерно то, что и я думал. Почитайте, не пожалеете

http://lleo.me/dnevnik/2021/09/11_1

Пару цитат для затравочки:

«Простите, вы там вообще наркоманы упоротые?

Мало того, что вы отключили старый API и нарушили работу систем всех своих партнеров.

Мало того, что ваш новый API чудовищно непрофессионально спроектирован и заставляет делать сотни тысяч обращений к серверам чтобы локально вытянуть кучу гигантских словарей и узнать, каким сраным временным индексом в своих грёбаных внутренних базах вы сегодня обозначили нужное value. Так у вас еще и эти базы битые, содержат взаимно противоречащие дубли?!!»

….

«Вы вообще что ли ничего не умеете, даже индексы строить?! Вас по итогам районной олимпиады трудоустроили в корпорацию? Может вам всем отделом уже пойти на курсы какие-нибудь по программированию и базам данных? Господи Кришна, на что я бл@ть, простой писатель-фантаст, трачу своё сука время, помогая другу с автоматизацией его неведомого склада, который я ему наладил год назад и забыл нах!й, а теперь вы бл@ть всё поломали. Да будьте вы прокляты, е4анаты хтонические!»

Вам также может понравиться

About the Author: Павел Пчелинцев