REST API Wildberries + 1С:УТ: заказы за 20 минут

Коротко: Интернет-магазин электроники подключил REST API Wildberries к 1С:Управление торговлей 11.5 через HTTP-сервис с автоматической загрузкой заказов, обновлением остатков и синхронизацией статусов. Время обработки одного заказа сократилось с 4 часов до 20 минут, количество ошибок ручного ввода упало на 94%, а операционные расходы на обработку снизились на 60%.
С чего всё началось: боль ручной обработки заказов
Представьте типичный день менеджера интернет-магазина, торгующего на Wildberries. Утро начинается с открытия личного кабинета маркетплейса, ручного копирования заказов в Excel, затем переноса данных в 1С, проверки остатков, формирования заданий на сборку и отправки статусов обратно. Четыре часа монотонного труда — и это только утренняя смена. При пиковых нагрузках (акции, распродажи) количество заказов вырастало до 300–500 в день, и команда физически не справлялась.
Именно с такой ситуацией столкнулся наш клиент — интернет-магазин электроники из Екатеринбурга с ассортиментом около 2 000 SKU. До интеграции процесс выглядел так:
- Менеджер вручную скачивал отчёт из WB каждые 2–3 часа;
- Переносил данные в 1С:УТ 11.5 вручную или через промежуточный Excel;
- Проверял наличие товара на складе;
- Формировал заказы поставщику при нехватке;
- Вручную обновлял статусы в личном кабинете WB;
- Дублировал информацию в мессенджер для склада.
Ошибки были неизбежны: пересортица, задвоение заказов, опоздания с обновлением статусов, штрафы от Wildberries за просрочку сборки. Решение было очевидным — полная автоматизация через REST API Wildberries и нативную интеграцию с задачи по 1С:ERP и 1С:УТ.
Как устроен REST API Wildberries: что нужно знать разработчику?
Wildberries предоставляет открытый REST API, документация к которому доступна на портале openapi.wb.ru. API разделён на несколько блоков, каждый из которых закрывает свою бизнес-задачу:
| Блок API | Назначение | Ключевые методы |
|---|---|---|
| Marketplace | Управление заказами FBS | /api/v3/orders, /api/v3/orders/new |
| Statistics | Отчёты по продажам | /api/v1/supplier/orders, /api/v1/supplier/sales |
| Content | Карточки товаров | /content/v2/get/cards/list |
| Prices | Управление ценами и скидками | /public/api/v1/info, /public/api/v1/prices |
| Warehouses | Остатки на складах | /api/v3/warehouses, /api/v3/stocks/{warehouseId} |
Аутентификация осуществляется через Bearer-токен, который генерируется в личном кабинете WB в разделе «Настройки → Доступ к API». Токен передаётся в заголовке каждого запроса: Authorization: Bearer {ваш_токен}.
Важные особенности API, которые нужно учесть при проектировании интеграции:
- Rate limiting: большинство методов имеют ограничение 60–300 запросов в минуту;
- Пагинация: заказы возвращаются порциями, нужно обрабатывать поле
nextдля курсорной пагинации; - Идемпотентность: повторный запрос на создание поставки с тем же ID не создаст дубль;
- Формат дат: RFC 3339 (например,
2024-01-15T10:30:00Z).
Архитектура решения: как связать WB API и 1С:УТ?
Перед написанием кода команда разработчиков спроектировала архитектуру интеграции. Было рассмотрено три варианта:
- Прямая интеграция через HTTP-запросы из 1С — 1С сама опрашивает API WB по расписанию;
- Промежуточный брокер сообщений — отдельный сервис получает вебхуки от WB и кладёт их в очередь;
- Внешняя обработка + планировщик Windows — COM-объект запускается по расписанию.
Был выбран первый вариант как наиболее простой в поддержке: регламентное задание в 1С каждые 5 минут вызывает API WB, получает новые заказы и обрабатывает их. Для обновления остатков используется отдельное задание с интервалом 15 минут. Схема потоков данных:
1С:УТ (регламентное задание) → GET /api/v3/orders/new → парсинг JSON → создание документов «Заказ клиента» → резервирование товара → POST /api/v3/orders/stickers (получение этикеток) → обновление статуса сборки → PATCH /api/v3/orders/{orderId} (подтверждение).
Для хранения токена и настроек создали отдельный регистр сведений «НастройкиИнтеграцииWB» с полями: Токен, URLБазовый, ИдСклада, РежимОтладки, ДатаПоследнейЗагрузки. Это позволяет менять параметры без изменения кода.
Пошаговая реализация: код загрузки заказов из WB в 1С
Рассмотрим ключевые фрагменты реализации. Начнём с базового модуля HTTP-взаимодействия с API Wildberries.
Шаг 1. Функция выполнения HTTP-запроса к API WB
// Модуль: ОбщийМодуль.ИнтеграцияWildberries
// Функция выполняет HTTP-запрос к API Wildberries и возвращает десериализованный JSON
Функция ВыполнитьЗапросWB(Метод, МетодHTTP = "GET", ТелоЗапроса = Неопределено) Экспорт
// Получаем настройки из регистра сведений
Настройки = РегистрыСведений.НастройкиИнтеграцииWB.ПолучитьПоследнее();
Если НЕ ЗначениеЗаполнено(Настройки.Токен) Тогда
ВызватьИсключение "Токен API Wildberries не заполнен в настройках интеграции";
КонецЕсли;
БазовыйURL = "https://marketplace-api.wildberries.ru";
Токен = Настройки.Токен;
// Формируем HTTP-соединение
ЗащищённоеСоединение = Новый ЗащищённоеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(
"marketplace-api.wildberries.ru",
443,
,
,
,
30,
ЗащищённоеСоединение
);
// Формируем заголовки запроса
Заголовки = Новый Соответствие();
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("Accept", "application/json");
// Создаём объект запроса
Запрос = Новый HTTPЗапрос(Метод, Заголовки);
// Если есть тело запроса — устанавливаем его
Если ТелоЗапроса <> Неопределено Тогда
Запрос.УстановитьТелоИзСтроки(
ФорматJSON(ТелоЗапроса),
КодировкаТекста.UTF8,
ИспользованиеByteOrderMark.НеИспользовать
);
КонецЕсли;
// Выполняем запрос
Попытка
Если МетодHTTP = "GET" Тогда
Ответ = Соединение.Получить(Запрос);
ИначеЕсли МетодHTTP = "POST" Тогда
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ИначеЕсли МетодHTTP = "PATCH" Тогда
Ответ = Соединение.Записать(Запрос);
ИначеЕсли МетодHTTP = "PUT" Тогда
Ответ = Соединение.Записать(Запрос);
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации(
"ИнтеграцияWB.ОшибкаЗапроса",
УровеньЖурналаРегистрации.Ошибка,
,
,
ОписаниеОшибки()
);
Возврат Неопределено;
КонецПопытки;
// Проверяем код ответа
Если Ответ.КодСостояния <> 200 И Ответ.КодСостояния <> 204 Тогда
ТекстОшибки = "API WB вернул код: " + Ответ.КодСостояния
+ ". Метод: " + Метод
+ ". Тело: " + Ответ.ПолучитьТелоКакСтроку();
ЗаписьЖурналаРегистрации(
"ИнтеграцияWB.ОшибкаОтвета",
УровеньЖурналаРегистрации.Предупреждение,
,
,
ТекстОшибки
);
Возврат Неопределено;
КонецЕсли;
// Десериализуем JSON-ответ
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Результат = ПрочитатьJSON(ЧтениеJSON);
Возврат Результат;
КонецФункции
// Вспомогательная функция сериализации объекта в JSON-строку
Функция ФорматJSON(Объект)
ЗаписьJSON = Новый ЗаписьJSON();
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Объект);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
Шаг 2. Загрузка новых заказов и создание документов в 1С:УТ
// Процедура загружает новые заказы WB и создаёт документы «Заказ клиента» в 1С:УТ
Процедура ЗагрузитьНовыеЗаказыWB() Экспорт
// Получаем список новых заказов (статус "new")
ОтветAPI = ИнтеграцияWildberries.ВыполнитьЗапросWB("/api/v3/orders/new");
Если ОтветAPI = Неопределено Тогда
Возврат;
КонецЕсли;
МассивЗаказов = ОтветAPI["orders"];
Если МассивЗаказов = Неопределено ИЛИ МассивЗаказов.Количество() = 0 Тогда
// Новых заказов нет — выходим
Возврат;
КонецЕсли;
КоличествоСоздано = 0;
КоличествоПропущено = 0;
Для Каждого ДанныеЗаказа Из МассивЗаказов Цикл
ИдЗаказаWB = Строка(ДанныеЗаказа["id"]);
// Проверяем — не загружен ли уже этот заказ
Если ЗаказУжеСуществует(ИдЗаказаWB) Тогда
КоличествоПропущено = КоличествоПропущено + 1;
Продолжить;
КонецЕсли;
// Создаём документ «Заказ клиента»
Попытка
СоздатьЗаказКлиентаИзWB(ДанныеЗаказа);
КоличествоСоздано = КоличествоСоздано + 1;
Исключение
ЗаписьЖурналаРегистрации(
"ИнтеграцияWB.ОшибкаСозданияЗаказа",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Заказ WB " + ИдЗаказаWB + ": " + ОписаниеОшибки()
);
КонецПопытки;
КонецЦикла;
ЗаписьЖурналаРегистрации(
"ИнтеграцияWB.ЗагрузкаЗаказов",
УровеньЖурналаРегистрации.Информация,
,
,
"Создано: " + КоличествоСоздано + ", пропущено дублей: " + КоличествоПропущено
);
КонецПроцедуры
// Функция проверяет существование заказа по внешнему ID WB
Функция ЗаказУжеСуществует(ИдЗаказаWB)
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ЗаказКлиента.Ссылка
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
|ГДЕ
| ЗаказКлиента.ВнешнийКодWB = &ВнешнийКодWB
| И НЕ ЗаказКлиента.ПометкаУдаления";
Запрос.УстановитьПараметр("ВнешнийКодWB", ИдЗаказаWB);
Результат = Запрос.Выполнить();
Возврат НЕ Результат.Пустой();
КонецФункции
// Процедура создаёт документ «Заказ клиента» из данных API WB
Процедура СоздатьЗаказКлиентаИзWB(ДанныеЗаказа)
НачатьТранзакцию();
Попытка
// Создаём новый документ
Документ = Документы.ЗаказКлиента.СоздатьДокумент();
Документ.Дата = ТекущаяДатаСеанса();
// Заполняем внешний код WB (реквизит добавлен через конфигуратор)
Документ.ВнешнийКодWB = Строка(ДанныеЗаказа["id"]);
Документ.НомерWB = Строка(ДанныеЗаказа["orderUid"]);
// Определяем контрагента «Wildberries» (создан заранее в справочнике)
Документ.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию(
"Wildberries", Истина
);
Документ.Организация = ПолучитьОсновнуюОрганизацию();
Документ.Склад = ПолучитьСкладWB();
Документ.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду("643");
// Заполняем адрес доставки из данных WB
АдресДоставки = ДанныеЗаказа["address"];
Если АдресДоставки <> Неопределено Тогда
Документ.АдресДоставки = АдресДоставки["fullAddress"];
КонецЕсли;
// Добавляем товарные позиции
МассивТоваров = ДанныеЗаказа["skus"];
Если МассивТоваров <> Неопределено Тогда
Для Каждого АртикулWB Из МассивТоваров Цикл
// Ищем номенклатуру по штрихкоду WB
Номенклатура = НайтиНоменклатуруПоШтрихкодуWB(АртикулWB);
Если НЕ ЗначениеЗаполнено(Номенклатура) Тогда
ВызватьИсключение "Номенклатура не найдена для SKU WB: " + АртикулWB;
КонецЕсли;
// Добавляем строку в табличную часть
Строка = Документ.Товары.Добавить();
Строка.Номенклатура = Номенклатура;
Строка.Количество = 1;
Строка.Цена = ДанныеЗаказа["convertedPrice"] / 100;
Строка.Сумма = Строка.Количество * Строка.Цена;
Строка.СтавкаНДС = Перечисления.СтавкиНДС.БезНДС;
КонецЦикла;
КонецЕсли;
// Записываем и проводим документ
Документ.Записать(РежимЗаписиДокумента.Проведение);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Синхронизация остатков: как не уйти в минус на маркетплейсе?
Одна из самых критичных задач — своевременное обновление остатков на Wildberries. Если товар закончился на складе, а WB не знает об этом, магазин получает заказ, который не может выполнить, и штраф за отмену. Мы настроили двустороннюю синхронизацию остатков каждые 15 минут.
// Процедура обновляет остатки на складе WB через API
Процедура ОбновитьОстаткиНаWildberries() Экспорт
Настройки = РегистрыСведений.НастройкиИнтеграцииWB.ПолучитьПоследнее();
ИдСклада = Настройки.ИдСкладаWB;
// Получаем актуальные остатки из 1С через запрос к регистру накопления
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.Номенклатура.ШтрихкодWB КАК ШтрихкодWB,
| Остатки.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| ,
| Склад = &СкладWB
| ) КАК Остатки
|ГДЕ
| Остатки.Номенклатура.ШтрихкодWB <> ""
|УПОРЯДОЧИТЬ ПО
| Остатки.Номенклатура.Наименование";
Запрос.УстановитьПараметр("СкладWB", ПолучитьСкладWB());
Выборка = Запрос.Выполнить().Выбрать();
// Формируем массив для отправки в WB API
МассивОстатков = Новый Массив();
Пока Выборка.Следующий() Цикл
ЭлементОстатка = Новый Структура();
ЭлементОстатка.Вставить("sku", Выборка.ШтрихкодWB);
ЭлементОстатка.Вставить(
"amount",
Макс(0, Цел(Выборка.КоличествоОстаток))
);
МассивОстатков.Добавить(ЭлементОстатка);
КонецЦикла;
Если МассивОстатков.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Отправляем остатки порциями по 1000 (ограничение API)
РазмерПорции = 1000;
Начало = 0;
Пока Начало < МассивОстатков.Количество() Цикл
Конец = Мин(
Отправка остатков: завершение логики порционной выгрузки
После формирования массива остатков отправляем данные на Wildberries порциями по 1000 позиций — это ограничение API маркетплейса. Вот как выглядит финальная часть процедуры:
Конец = Мин(
Начало + РазмерПорции,
МассивОстатков.Количество()
);
ПорцияОстатков = Новый Массив();
Для Инд = Начало По Конец - 1 Цикл
ПорцияОстатков.Добавить(МассивОстатков[Инд]);
КонецЦикла;
ТелоЗапроса = Новый Структура();
ТелоЗапроса.Вставить("stocks", ПорцияОстатков);
ОтправитьОстаткиНаWB(ИдСклада, ТелоЗапроса);
Начало = Начало + РазмерПорции;
КонецЦикла;
КонецПроцедуры
Найдите специалиста для решения этой задачи на koderion.ru
Автор: редакция Koderion. Обновлено: 10 мая 2026. Источники: Бухгалтерия.ру, Infostart, ИТС 1С.