Каталог решений - Интеграция с API WIldberries. Что нового в 2022 во взаимодействии 1С и Вайлдберриз

Интеграция с API WIldberries. Что нового в 2022 во взаимодействии 1С и Вайлдберриз

Интеграция с API WIldberries. Что нового в 2022 во взаимодействии 1С и Вайлдберриз

В наличии

Демонстрация взаимодействия системы учета на 1С и АПИ Вайлдберриз. Готовое решение, которое можно доработать под ваши запросы. Новая версия API 1.0.2, расскажу, как получить supplierID, как создать карточки товара на вайлдберриз, как получить остатки и задать цены.

Категория:

Описание

Всем привет!

Прошлую статью по интеграции с Wildberries я писал в конце 2020 и с тех пор многое поменялось. Работа с API стала чуть проще, однако нюансы взаимодействия с Вайлдберриз никуда не делись. В этой статье я покажу как взаимодействовать с АПИ из 1С и представленную мной обработку можно взять за пример и доработать. 

Если вы предприниматель и продавец на Wildberries: в конце статьи есть возможность скачать обработку (платформа 8.3.14 , 8.3.8). В ней есть лишь несколько базовых функций (получение остатков, получение и обновление цен, создание карточки товара и получение списка карточек уже созданных). Для доработки остальных функций можно отдать обработку вашему программисту или написать мне в телеграм, поискав меня по имени.

Если вы программист: Здравствуйте, коллега! В статье расскажу некоторые нюансы схемы данных у WB и дам примеры кода. У Вайлдберриз теперь есть для тестирования запросов Swagger, и по сути главное для интеграции правильно сформировать JSON на стороне 1С. Но будьте аккуратны, тестовой среды больше нет и все запросы сразу попадают в продакшн и в ЛК вашего Заказчика. Не забудьте поставить плюсик статье!

 

1. Получение токена АПИ и supplierId для запросов.

Токен для АПИ получить легко. В разделе "настройки" в ЛК есть вкладка "доступ к новому API" где этот токен и получается. Токен нужно передавать в каждом запросе в HTTP заголовке Authorization

 

 

Как получить supplierId в личном кабинете Wildberries

Проще всего для этого в ЛК открыть список ваших юрлиц в правом верхнем углу (там где в меню Профиль и Настройки), кликнуть правой кнопкой мыши и нажать "просмотреть код" в Chrome.

 

 

Там сразу в HTML коде видна метка "FOR" где прописан ваш идентификатор supplierID. 

 

 

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

Этот самый идентификатор нужен для многих запросов к АПИ, хотя некоторые запросы и без него работают — видимо, есть связь между Токеном доступа к АПИ и supplierID. 

 

2.  Получение списка существующих карточек

 

Чаще всего бывает так, что карточки товара уже созданы вручную или загружены из Ексель, и их надо получить на стороне 1С. Делаем для этого запрос "/card/list" к АПИ. Важно убрать все из параметра filter и поставить limit побольше. Впрочем, я в обработке сделал пример где limit 100 и получение идет в цикле, увеличивая offset. Вот код в функции СписокКарточекВБ:

  &НаКлиенте
  Функция СобратьЗапросКарточек(Лимит,ОФсет)
  	СтруктураЗ = Новый Структура;
  	СтруктураЗ.Вставить("id",1);
  	СтруктураЗ.Вставить("jsonrpc","2.0");
  	СтрПарам = Новый Структура;//Params
  	СтрФильтра = Новый Структура;
  	СтрФильтра.Вставить("filter",Новый Массив);
  	СтрФильтра.Вставить("find",Новый Массив);
  	СтрОрдер = Новый Структура;
  	СтрОрдер.Вставить("column","");
  	СтрОрдер.Вставить("order","");
  	
  	СтрФильтра.Вставить("order",СтрОрдер);
  	
  	СтрПарам.Вставить("filter",СтрФильтра);
  	
  	СтрЗапроса = Новый Структура;
  	СтрЗапроса.Вставить("limit",Лимит);//max 100
  	СтрЗапроса.Вставить("offset",ОФсет);
  	СтрПарам.Вставить("query",СтрЗапроса);
  	СтрПарам.Вставить("isArchive", ЛОЖЬ);
  	СтрПарам.Вставить("supplierID",Объект.supplierID);
  	СтрПарам.Вставить("withError", ЛОЖЬ);
  	
  	СтруктураЗ.Вставить("params",СтрПарам);
  	
  	Возврат СтруктураЗ;
  КонецФункции
  
  &НаКлиенте
  Процедура СписокКарточекВБ(Команда)
  	СтруктураЗ = СобратьЗапросКарточек(100,0);
  	//json
  	СериализованнаяСтрока = СтруктураВJson(СтруктураЗ);
  	
  	ЖсонОтправка = СериализованнаяСтрока;
  	
  	Адрес = "/card/list";
  	СоответствиеОтветАПИ = ВыполнитьМетодАПИ(СериализованнаяСтрока,Адрес,"POST");
  	Если НЕ СоответствиеОтветАПИ=Неопределено Тогда
  		
  		Рез = СоответствиеОтветАПИ.получить("result");
  		Курсор = Рез.Получить("cursor");
  		
  		ВсегоНоменклатурыУВБ = Курсор.Получить("total");
  		
  		ВыданоСейчас = Курсор.Получить("limit");
  		Смещение = Курсор.Получить("offset");
  		
  		КартыМассив = Рез.Получить("cards");
  		сообщить("найдено артикулов="+ВыданоСейчас+ " шаг=0");
  		//СОПОСТАВИТЬ с 1С
  		СопоставитьНом1С(КартыМассив);
  		Лимит = 100;
  		счШага = 1;
  		Пока ВсегоНоменклатурыУВБ > ВыданоСейчас + Смещение Цикл
  			Смещение = Смещение+100;
  			счШага = счШага + 1;
  			//получим остальные страницы
  			Если ВсегоНоменклатурыУВБ - Смещение < 100 Тогда
  				СтруктураЗ = СобратьЗапросКарточек(ВсегоНоменклатурыУВБ - Смещение,Смещение);
  			Иначе
  				СтруктураЗ = СобратьЗапросКарточек(100,Смещение);
  			КонецЕсли;
  			СоответствиеОтветАПИ = ВыполнитьМетодАПИ(СериализованнаяСтрока,Адрес,"POST");
  			Если НЕ СоответствиеОтветАПИ=Неопределено Тогда
  				
  				Рез = СоответствиеОтветАПИ.получить("result");
  				Курсор = Рез.Получить("cursor");
  				
  				ВыданоСейчас = Курсор.Получить("limit");
  				Смещение = Курсор.Получить("offset");
  				КартыМассив = Рез.Получить("cards");
  				//СОПОСТАВИТЬ с 1С
  				СопоставитьНом1С(КартыМассив);
  				
  			Иначе
  				Сообщить("Неверный код ответа card/list");
  				
  			КонецЕсли;
  			сообщить("найдено артикулов="+ВыданоСейчас+ " шаг="+счШага);
  		КонецЦикла;
  		
  	Иначе
  		Сообщить("Неверный код ответа card/list");
  		//ПоказатьПредупреждение(, "Ошибка соединения с Wildberries");
  		Возврат;
  	КонецЕсли;
  	
  	
  КонецПроцедуры

 

На вкладке "служебное" всегда можно посмотреть отправленный и полученный текст JSON 

 

 

3. Сопоставление данных Вайлдберриз и 1С. Нюансы схемы данных.

У Wildberries есть следующие сущности: Карточка (Card) и ее идентификатор imtId и supplierVendorCode (Артикул Поставщика), Номенклатура (массив nomenclatures в карточке) и ее идентификатор nmId и vendorCode (Артикул Цвета). 
Еще у Карточки есть дополнения (addin) где указывается Бренд и ТНВЭД. 
А у Номенклатуры есть variations где указывается Размер (идентификатор chrtId) и его Штрихкоды (barcodes). Внутри variations есть еще addin где указывается цена товара (целое число без копеек). 

Для примера рассмотрим поиск по штрихкоду, а затем если не нашли, по артикулу номенклатуры (vendorCode) в базе 1С. Вот код:

  &НаСервере
  Процедура СопоставитьНом1С(КартыМассив)
  	счч=0;
  	Для Каждого КартаСоотв Из КартыМассив Цикл
  		//ид карты, в карте может быть несколько номенклатур
  		мИдВБ = КартаСоотв.Получить("imtId");//не используется далее
  		Номенклатуры =  КартаСоотв.Получить("nomenclatures");//массив, в массиве соответствия
  		Для Каждого СоотвНом ИЗ Номенклатуры Цикл
  			//нужно для обмена остатками
  			nmId = СоотвНом.Получить("nmId");//ид конкретной номенклатуры
  			Артикул1С = СоотвНом.Получить("vendorCode");//артикул конкретной номенклатуры
  			//размеры
  			//у номенклатуры может быть несколько variations с разными ид chrtId
  			Вариации = СоотвНом.Получить("variations");
  			стрРазмеров="";//запишем через точку с запятой размеры
  			НайденоПОШК = Ложь; 
  			Для Каждого СоотвВар Из Вариации Цикл
  				Баркод = СоотвВар.Получить("barcode");
  				Если Баркод=Неопределено Тогда
  					массивШК = СоотвВар.Получить("barcodes");
  					Для Каждого шк из массивШК Цикл
  						Баркод = шк;
  					КонецЦикла;					
  				КонецЕсли;	
  				chrtId = СоотвВар.Получить("chrtId");//число
  				ЭддИны = СоотвВар.Получить("addin");
  				//Размер = Эддины.Получить(1).Получить("params").Получить(0).Получить("value");
  				//chrtid = СтрЗаменить(Строка(chrtId)," ","") + "_" + СокрЛП(Размер);
  				стрРазмеров = стрРазмеров + Строка(chrtId) + ";" ;
  				//поищем номенклатуру по ШК
  				Если НЕ ПустаяСтрока(Баркод) Тогда
  					Номенклатура1С = ПоискПоШК(Баркод); 
  				КонецЕсли;
  			КонецЦикла;
  			
  			Если НайденоПОШК = Ложь Тогда
  				//поищем номенклатуру
  				Номенклатура1С = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул",Артикул1С);
  			КонецЕсли;
  			
  			
  			Если НЕ Номенклатура1С.Пустая() Тогда
  				//запишем доп свойства
  				
  				//ЗаписатьДопСвойство(Номенклатура1С,"wb_chrtid",стрРазмеров);
  				ЗаписатьДопСвойство(Номенклатура1С,"wb_nmid",nmId);
  				счн=счн+1;
  			Иначе
  				Сообщить("артикул не найден <"+Артикул1С+">");
  			КонецЕсли;
  			
  		КонецЦикла;				
  		счч = счч+1;
  		
  	КонецЦикла;
  	Сообщить("Обработано Карт "+счч);
  КонецПроцедуры
  
  Функция ПоискПОШК(Баркод)
  	//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
  	// Данный фрагмент построен конструктором.
  	// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
  	
  	Запрос = Новый Запрос;
  	Запрос.Текст = 
  	"ВЫБРАТЬ
  	|	ШтрихкодыНоменклатуры.Штрихкод КАК Штрихкод,
  	|	ШтрихкодыНоменклатуры.Номенклатура КАК Номенклатура,
  	|	ШтрихкодыНоменклатуры.Характеристика КАК Характеристика,
  	|	ШтрихкодыНоменклатуры.Упаковка КАК Упаковка
  	|ИЗ
  	|	РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
  	|ГДЕ
  	|	ШтрихкодыНоменклатуры.Штрихкод = &Штрихкод";
  	
  	Запрос.УстановитьПараметр("Штрихкод", Баркод);
  	
  	РезультатЗапроса = Запрос.Выполнить();
  	
  	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
  	
  	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
  		Возврат ВыборкаДетальныеЗаписи.Номенклатура; 
  	КонецЦикла;
  	
  	//}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
  	Возврат Справочники.Номенклатура.ПустаяСсылка();
  КонецФункции
  

Запишем идентификаторы nmId в регистр Дополнительные сведения, чтобы связать с номенклатурой 1С. Вот код:

  &НаСервере
  Процедура ЗаписатьДопСвойство(НоменклатураСсылка,ИмяСвойства,ЗначениеСвойства)
  	ПВХСвойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию(ИмяСвойства,Истина);
  	Если ПВХСвойство.Пустая() Тогда
  		ПВХ = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.СоздатьЭлемент();
  		ПВХ.Наименование = ИмяСвойства;
  		ПВХ.Заголовок = ИмяСвойства;
  		ПВХ.ТипЗначения = Типзнч(ЗначениеСвойства);
  		ПВХ.Записать();
  		ПВХСвойство = ПВХ.Ссылка;
  	КонецЕсли;
  	Набор = РегистрыСведений.ДополнительныеСведения.СоздатьМенеджерЗаписи();
  	Набор.Период = ТекущаяДата();
  	Набор.Объект = НоменклатураСсылка;
  	Набор.Свойство = ПВХСвойство;
  	Набор.Значение = ЗначениеСвойства;
  	Набор.Записать(Истина);
  	
  КонецПроцедуры

 

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

 

4. Получение цен

 

 

Делаем GET Запрос на ресурс АПИ "/public/api/v1/info?quantity=0". В запросе нам возвращаются идентификаторы номенклатуры nmId, поэтому важно на шаге 3 понять как эти nmId сопоставлены с вашей базой 1С. Я в своей обработке предположил, что сначала получаются Карточки, и поэтому делаю поиск по табличке которая там есть. Цены беру в регистре ЦеныНоменклатуры. Поля discount и promoCode я не использую в расчете, просто храню и отображаю их в таблице в обработке.

 

 

5.  Изменение цен

Для примера я взял УТ 11 на платформе 8.3.18, где цены лежат в регистре ЦеныНоменклатуры. Для своей конфигурации можно модифицировать запрос цен нужным образом. Отправляется POST запрос на ресурс "/public/api/v1/prices". Из таблички на форме отправляю те строки, где есть цена 1С и стоит галочка "Обновить цену". Чтобы не отправлять HTTP запрос по каждой строке с ценами, собираю в JSON запрос массив номенклатур. 

 

 

Пример кода:

  &НаСервере
  Процедура ЗадатьЦеныИз1СНаСервере()
  	//задаем цены в ВБ из 1С - Таблички на форме
  	Адрес = "/public/api/v1/prices";
  	МассивЗапроса = Новый Массив;
  	Для Каждого СтрТ из Объект.Товары Цикл
  		Если СтрТ.ОбновитьЦену Тогда
  			СтруктураЦены = Новый Структура;
  			СтруктураЦены.Вставить("nmId",СтрТ.nmID);//число!
  			СтруктураЦены.Вставить("price",СтрТ.Цена1С);
  		КонецЕсли;
  	КонецЦикла;
  	
  	Жсон = СтруктураВJson(МассивЗапроса);
  	ОтветАПИ = ВыполнитьМетодАПИ(Жсон,Адрес,"POST");
  	
  КонецПроцедуры
  

 

6. Получение и обновление остатков

Для получения остатков — делаем GET Запрос на ресурс АПИ "/api/v2/stocks?skip=0&take=1000". Кстати, по примеру видно что программисты в Вайлдберриз фанаты Властелина колец. Их пример:

 

 

Для обновления же остатков нужен POST запрос на ресурс "/api/v2/stocks" и там еще надо знать warehouseId. Где же его взять? Только из предыдущего запроса по получению остатков, либо сделать GET запрос к АПИ "/api/v2/warehouses". 

 

 

7. Получение списка заказов

Делаем GET Запрос на ресурс АПИ "/api/v2/orders?date_start=2022-01-01T13:00:00Z&status=2&take=10&skip=0". Тут главное форматировать дату по RFC3339 в формате "yyyy-MM-ddTHH:mm:ssZ". Пример, который должен получиться из ответа АПИ:

 

 

Для обработки 1С я предполагаю, что структура заказа такая же, как в примере у Вайлдберриз. Нюанс обработки заказов в том, что Вайлдберриз выдают очередные левые идентификаторы в описании OrdersAPIResponse вместо привычного уже идентификатора номенклатуры nmID выдают идентификатор размера chrtId, ну и штрихкод тоже есть.

Как реализовать поиск в 1С заказов по данным штрихкода и chrtId оставляю на ваше усмотрение. Лично я решил в процессе получения карточек (вкладка 2 Карточки ВБ) записывать для Номенклатуры все ее ид размеров chrtId в регистр ДопСведений. И, таким образом, есть сопоставление chrtId и Номенклатуры 1С. Можно еще искать по Штрихкоду в регистре штрихкодов, но у ВБ могут быть свои штрихкоды, отличные от 1С.

 

 

8. Остальные функции

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

Также в конце статьи приведу список ошибок АПИ, с которыми я сталкивался в процессе тестирования, для того чтобы их могли найти в поисковике и прочитать эту статью. Обычно эти ошибки были следствием некорректного JSON, хотя иногда я был уверен что и баги в АПИ тоже есть.

Ошибки:

list of cards: (BadValue) $and must be an array 

Следующие комбинации характеристик \"Артикул поставщика\" и \"Бренд\" уже используются

validation error, errorValidation

failed get card by imt id: unexpected end of JSON input cause: map[Внутренняя ошибка:None] card.cardByImtID

Характеристика: tech_size. Ошибка: Артикул с таким размером уже создан! Удалите позицию из спецификации и загрузите на нее баркод в разделе Загрузки — Загрузки баркодов

update card cause: map[err:get origin card: Internal Server Error]

Следующие комбинации характеристик \"Артикул поставщика\", \"Артикул цвета\" и \"Бренд\" уже используются

batch create error cause: map[err:Нет карточек для добавления. Карточки товара с штрихкодом уже созданы

Такая комбинация бренда  и артикула поставщика уже используется

Характеристика: sa_nm. Ошибка: Артикул принадлежит другому поставщику

Ошибка: Артикул удален

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

Удаление номенклатуры невозможно, ввиду наличия поставок по ней

Благодарю за прочтение! 

has been added to your cart:
Оформление заказа