Я не люблю интеграции, которые начинаются со слов «просто отправь запрос». С Ozon всё именно так и выглядит, пока не откроешь документацию. А там — категории, типы товаров, обязательные атрибуты, справочники с пагинацией. И если сделать шаг в неправильном порядке, импорт вернёт ошибку, смысл которой придётся разгадывать.
Я прошёл через это. Не один раз. И сейчас расскажу последовательность, которая работает. Без лишних движений и без «попробуй ещё раз, может, пройдёт».
Что нужно до первого запроса
Два ключа. Client-Id и Api-Key. Оба выдаются в личном кабинете продавца Ozon, в разделе с API-ключами. Client-Id — это число, идентификатор магазина. Api-Key — секретная строка, которую нужно беречь как пароль.
Запросы отправляются на адрес api-seller.ozon.ru. Оба ключа передаются в заголовках с теми же именами: Client-Id и Api-Key. Если хотя бы один не тот, ответ будет 401 или ошибка о неверном Client-Id.
Это база. Дальше начинается то, из-за чего интеграция с Ozon сложнее, чем кажется.
Последовательность, которую нельзя нарушать
Импорт товара — это не один запрос. Это цепочка. Если пропустить шаг, следующий не сработает.
Шаг первый: получить дерево категорий
Метод /v1/description-category/tree возвращает все категории и типы товаров Ozon. Вам нужны два значения: description_category_id (категория второго уровня) и type_id (тип товара). Без них импорт не начнётся.
Это дерево большое. Категорий много, типов ещё больше. В первый раз я потратил час, чтобы найти нужную ветку. Совет: выгрузите дерево один раз, сохраните в файл и работайте с ним локально. Повторные запросы только тратят время.
Шаг второй: выгрузить атрибуты
У каждой категории и типа свой набор атрибутов. Метод /v1/description-category/attribute возвращает их список. Здесь важно смотреть на два параметра.
is_required — если true, атрибут обязателен. Без него импорт вернёт ошибку. dictionary_id — если больше нуля, атрибут имеет справочник значений. Это значит, что нельзя передать произвольную строку. Нужно сначала выгрузить справочник и взять оттуда dictionary_value_id.
На этом этапе я потерял больше всего времени. Казалось бы, «цвет» — что сложного? Но у Ozon это справочник. И если вы передадите «красный» вместо идентификатора из справочника, импорт не пройдёт.
Шаг третий: выгрузить справочники
Метод /v1/description-category/attribute/values возвращает значения для конкретного атрибута. Здесь есть пагинация. В одном запросе можно получить до пяти тысяч значений. Если справочник больше — передаёте последнее значение в last_value_id и запрашиваете следующую порцию.
Отдельная история — бренды. Справочники для атрибутов 85 и 31 (бренды) могут возвращать значения, которые не относятся к запрошенной категории. Это особенность Ozon. Приходится выгружать полностью и фильтровать вручную.
Сам импорт
Когда категории, атрибуты и справочники собраны, можно отправлять товар. Метод /v3/product/import принимает массив товаров.
Вот минимальная структура запроса на PHP:
{ "items": [ { "name": "Кроссовки беговые", "offer_id": "SKU-001", "price": "4990", "currency_code": "RUB", "description_category_id": 123456, "type_id": 789, "attributes": [ { "id": 85, "values": [ { "dictionary_value_id": 12345, "value": "Nike" } ] }, { "id": 10096, "values": [ { "value": "42" } ] } ] } ] }Обратите внимание: у каждого атрибута свой id. Для справочных атрибутов передаётся dictionary_value_id и value. Для обычных — только value. Если перепутать, импорт вернёт ошибку валидации.
Ответ содержит task_id. Это не значит, что товар загружен. Это значит, что задача создана. Статус нужно проверять отдельным методом, обычно /v1/product/import/info. Я видел, как люди ждут мгновенного результата, получают task_id и идут пить кофе. А потом выясняется, что задача упала с ошибкой, которую никто не проверил.
Грабли, на которые я наступил
Первая: обязательные атрибуты. Их не всегда очевидно. В документации метод возвращает is_required, но если смотреть на список атрибутов в кабинете Ozon, он может отличаться. Доверяйте ответу метода, а не интерфейсу.
Вторая: цена. Передаётся строкой, а не числом. Если отправить 4990 как число, некоторые версии API возвращают ошибку. Мелочь, но она стоит времени.
Третья: обновление товара. Для обновления используется тот же метод, но с заполненным offer_id. Если товар уже существует, Ozon обновит его. Если нет — создаст новый. Это удобно, но требует аккуратности: случайная опечатка в offer_id создаст дубль.
Четвёртая: лимиты. Ozon не приветствует массовые запросы без пауз. При выгрузке тысяч товаров я добавлял задержку между запросами и разбивал каталог на порции. Это медленнее, но надёжнее, чем получать блокировку на час.
Стоит ли писать с нуля
Если у вас десять товаров и вы планируете загружать их раз в месяц — можно и руками. Если каталог на сотни позиций и цены меняются часто — интеграция окупается.
Писать с нуля имеет смысл, если у вас нестандартная логика: свои правила формирования offer_id, сложная связь с учётной системой, специфические атрибуты. В остальных случаях готовые модули для Битрикс берут эту рутину на себя. Они не идеальны, но экономят недели разработки.
Я выбрал свой код, потому что мне нужен был контроль над каждым шагом. Но это не единственный правильный путь. Это просто мой.
А вы писали интеграцию с Ozon сами или использовали готовое решение?

