Добрый день, хочу описать опыт интеграции с API WB (Wildberries) в части создания карточки товаров (спецификации).
Сама задача состояла в том, чтобы была возможность работать со своего склада, управлять остатками через API , а не через личный кабинет, и использовать все возможности API для автоматизации процесса.
Здесь уже есть статьи по интеграции с WB, а именно получение токенов для интеграции, поэтому получение токенов опишу вкратце.
Для интеграции используется три API
1. Для работы с карточками.
2. Для управления остатками на своем складе и получения заказов на сборку
3. Сервис статистики: загрузка заказов, продаж, поставок, отчета по продажам
Для каждого из вариантов используется свои ключ/токен.
Для работы с карточками необходимо получить основной токен, с помощью которого получаем Cookie, который используем в запросах. Для получения основного токена необходимо выполнить шаги, которые указаны по ссылке https://suppliers.wildberries.ru/remote-wh-site/api-content.html. Для регистрации нужно использовать основной номер, на который была регистрация. Отмечу, что обновление Cookie понадобится в том случае, если вы долгое время не делали запросов.
Для управления остатками на своем складе токен для работы получаем на странице https://suppliers.wildberries.ru/marketplace-pass/warehouses при первом запросе доступа к API. Если токены (их два: основной и тестовый) не сохранились, то для получения необходимо создать заявку на Service Desk. Тестовый url и тестовый токен у меня были не доступны, поэтому для тестирования использовала рабочие. Здесь отмечу, что метод обновления стоков и цен обновляет только стоки, цены на момент написания статьи пока не меняет.
Для работы с сервисом статистики необходимо создать заявку на Service Desk. Есть отдельная категория для этого: Заявка на API content. В моем случае пришлось ждать около недели для получения ответа на заявку. Само описание сервиса статистики нашла в разделе Обучение в личном кабинете.
Далее подробно опишу свой опыт интеграции с API по работе с карточками.
Получение списка карточек
Получение списка карточек не вызвало трудностей. Описание работы с API можно прочитать здесь https://suppliers.wildberries.ru/remote-wh-site/api-content.htm. Обращаю внимание на параметр offset, это не следующая страница, а количество записей, которое надо пропустить, это написано в описании, но сначала не обратила на это внимания.
Запрос отправляла без отборов, вида:
SupplierID получаем на странице
В заголовке запроса указываем куки:
Куки указываем во всех последующих запросах по работе с карточками товаров.
Получаем в результате JSON вида:
Создание карточки товара
Здесь оказалось не все так просто. Для формирования структуры запроса для отправки на создание карточки необходимо выполнить кучу дополнительных запросов.
Структура карточки, если описать словами:
Верхняя структура – карточка и ее свойства, подструктура – номенклатура карточки (массив) и свойства номенклатуры, подструктура номенклатуры – вариации(массив) и его свойства. И свойство может иметь массив параметров.
Часть свойств обязательна и, причем, некоторые свойства заполняются из определенного списка (предопределенного), часть числового формата с указанием свойства units, часть строкового типа.
Пример JSON для отправки запроса на создание карточки (addIn – это свойства, постаралась показать что имела ввиду под свойствами карточки, свойства номенклатуры и свойства вариации).
Для создания карточки понадобится:
- Предварительная загрузка фотографии с сохранением ID файла
- Получение категории карточки, здесь не получится вариант указать свой, нужно выбрать из предопределенного набора.
- Получение свойств по категории, получение свойств по номенклатуре, получение свойств по вариации, которые необходимо заполнить.
- Получение предопределенных значений по свойствам (не по всем).
Загрузка файла
Для загрузки файла в описании API написано, что можно использовать два метода:
Create. https://content-suppliers.wildberries.ru/card/create
Update. https://content-suppliers.wildberries.ru/card/update
Описание https://content-suppliers.wildberries.ru/card/update не нашла, использовала ту же структуру, что и для метода create, но в итоге не обновляет, а работает также как метод create, поэтому использовала только метод https://content-suppliers.wildberries.ru/card/create.
Для начала нужно файл/фото загрузить на сайт. Фотография должна быть вертикальная, размер не менее 900x1200, расширение или jpg или png.
В API описание загрузки следующее:
В 1С у меня формирование файла для отправки выглядит следующим образом
Вырезки кода по формированию файла для отправки:
Самое главное, это IDFile, который у меня равен Строка(Новый УникальныйИдентификатор) ( можно и по-своему, главное сохранить формат "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"), его нужно сохранить, так как он используется при создании карточки.
В тэге photos указываем сохраненные ID файлов.
Получение категории товара
В структуре JSON на верхнем уровне обязательны к заполнению тэги object, countryProduction, supplierVendorCode.
Про supplierVendorCode, в поддержке пишут, в дальнейшем будет упразднен, сейчас заполняю его равным VendorCode в структуре «nomenclatures»,
countryProduction – это значение из справочника countries (dictionary = countries, ниже описано как получить значения из этого справочника, это пункт «Получение значений по свойствам»),
object – категория товара, выбирается из определенного набора значений, который получаем следующим образом:
Отправляем запрос get https://content-suppliers.wildberries.ru/ns/characteristics-configurator-api/content-configurator/api/v1/config/get/object/list?pattern=игр&lang=ru, где в url запроса pattern – подстрока по категории. Указание обязательно, если не указать, то не получится получить весь список категорий, получаем пустой массив.
В ответ получаем JSON следующего вида:
Получение свойств по категории
Затем необходимо найти , какие свойства указать для выбранной категории, для этого отправляем запрос на адрес GET https://content-suppliers.wildberries.ru/ns/characteristics-configurator-api/content-configurator/api/v1/config/get/object/translated?name=Кроссовки&lang=ru , где name в запросе – это Наименование категории, что параметр регистрозависимый.
Получаем JSON вида
В итоге получаем набор свойств, который необходимо заполнить для выбранной категории, набор свойств номенклатуры и набор свойств для вариации номенклатуры.
Необходимо обратить внимание на следующие тэги:
type – это само свойство,
required – обязательность заполнения,
dictionary – тег указывает на то, что значения необходимо брать из указанного справочника,
isNumber – указывает, что это число, и указывать надо число и заполнять тэг count, в противном случае value в структуре карточки товара (пример JSON вначале),
units – это единица измерения, если тэг указан, то при создании карточки необходимо указать этот тэг свойства и указать значение,
maxCount – это максимально возможное указанное значения count.
Здесь обязательными к заполнению являются помимо прочего свойства вариации:
type: «Розничная цена», units: «рублей», count: «ЗначениеЧисло»;
type: «Размер», value: «0».
Получение значений по свойствам
И наконец, для получения значений по свойствам, по которым указан тэг dictionary, отправляем запрос GET https://content-suppliers.wildberries.ru/ns/characteristics-configurator-api/content-configurator/api/v1/directory/brands?pattern=nike&lang=ru&top=50
.
В этом примере brands – это значение dictionary, pattern – это подстрока значения, top – количество элементов.
В ответ получаем JSON вида
Значения – это тэг translate.
Если все обязательные свойства указаны, структура сформирована верно, то в ответ получаем код состояния 200 и примерно такой JSON
Если все верно, то на сайте в Спецификации New появляется карточка со статусом Создан.
Если статус «На проверке», то, скорее всего, состояние перейдет в состояние «Ошибки» (по крайней мере в моем случае так и было).
Остались нерешенные проблемы с загрузкой файла, указывала как описано в API, и в свойствах номенклатуры как тип «Фото», пробовала разные варианты, но или карточка совсем перестает открываться и без поддержки ее не открыть, или отображение в виде двоичного кода. Запросы в поддержку пока не дали результата. Если у кого есть ответ на этот вопрос, то буду признательна.
Надеюсь, что сумела донести мысль, задавайте, пожалуйста, вопросы, если таковые возникли.
Дополнение от 11.02.2021
Появилось обязательное заполнение поля Код ТНВЭД. Чтобы получить значения нужно указать запрос get вида https://content-suppliers.wildberries.ru/ns/characteristics-configurator-api/content-configurator/api/v1/directory/tnved?subject=Термосы. Если вашего значения кода нет, то нужно создать инцидент на Service Desk.
Дополнение от 02.03.2021
Победила загрузку файла, оказалось, что файл не кодированный.
Кусок кода для загрузки фото на сайт, надеюсь кому поможет , спасибо статье
http://infostart.questa.ru/public/20017/
Boundary = "boundaryImage";
ИмяФайлаОтправки = КаталогВременныхФайлов() + "post.txt";
МассивФайловДляОбъединения = Новый Массив;
//Формируем начальный фрагмент файла POST-запроса
ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.ANSI, Символы.ПС, Ложь);
//Определяем раздел двоичных данных
ФайлОтправкиНачало.ЗаписатьСтроку("--" + Boundary);
ФайлОтправкиНачало.ЗаписатьСтроку("Content-Disposition: form-data; name=""uploadfile""; filename=""photo.jpg""");
ФайлОтправкиНачало.ЗаписатьСтроку("");
ФайлОтправкиНачало.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
//Копируем файл для загрузки во временный и добавляем в массив файлов для объединения
ИмяФайлаДляЗагрузкиВременный = ПолучитьИмяВременногоФайла("jpg");
КопироватьФайл(ПутьКНашемуФайлу, ИмяФайлаДляЗагрузкиВременный);
МассивФайловДляОбъединения.Добавить(ИмяФайлаДляЗагрузкиВременный);
ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
ФайлОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.ANSI, Символы.ПС, Ложь);
//Завершение раздела двоичных данных
ФайлОтправкиКонец.ЗаписатьСтроку(символы.ПС + "--" + Boundary + "--");
ФайлОтправкиКонец.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);
//Теперь сформированные фрагменты сообщения для сервера объединяем в один файл POST-запроса
ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
ОтветАПИ = di_HTTPService.ПолучитьСоединениеHTTP_POST_File(Справочники.di_Методы.ЗагрузитьФайл,Объект.supplierID,Объект.IDFile,ИмяФайлаОтправки);
Если ОтветАПИ <> неопределено Тогда
СтрокаJSON = Строка(ОтветАпи.КодСостояния) + " " + ОтветАпи.ПолучитьТелоКакСтроку();
КонецЕсли;
И добавлять надо в свойства номенклатуры, в итоге вот так должно выглядеть ( это кусок только)
"addin": [
{
"type": "Фото",
"params": [
{
"value": "e3ee6410-a09b-4dfe-a84b-ce8946abc521",
"units": "images/jpeg"
}
]
}