Интеграция 1С с Wildberries и Ozon: реальный опыт автоматизации

Склад отгружает на Wildberries 200 позиций в день. Менеджер вручную копирует заказы из личного кабинета в 1С, сверяет артикулы, создаёт перемещения на транзитный склад. Ошибается в среднем трижды за смену — путает размеры, дублирует строки, забывает про отмены. Параллельно по Ozon идут возвраты FBO, и кладовщик сканирует штрихкоды, но партии подставляются неправильно. Знакомая картина? Мы разбирали именно такую ситуацию в проекте для розничной сети спортивных товаров. Расскажем, что сделали, какие грабли нашли и почему штрихкод оказался важнее артикула.

Зачем автоматизировать обмен с маркетплейсами

Ручной ввод заказов из маркетплейса в 1С работает, пока заказов десять в день. При масштабировании до сотен позиций ручной труд становится узким местом по трём причинам.

Скорость. Менеджер тратит 2-3 часа в день на копирование данных. Это время, которое не создаёт ценности — чистые операционные потери. Автоматическая загрузка заказов через API занимает секунды.

Точность. Человек путает размеры, артикулы, количество. Каждая ошибка — это пересортица на складе, штрафы от маркетплейса, возврат, который нужно обрабатывать отдельно. В одном из проектов до автоматизации процент ошибок при ручном вводе составлял около 4%. После запуска интеграции — ноль ошибок сопоставления за три месяца.

Актуальность данных. Пока менеджер вводит заказы утренней выгрузки, поступают новые. Статусы меняются — заказ отменён, но перемещение уже создано. Автоматический обмен по расписанию каждые 15 минут снимает эту проблему.

Есть и четвёртая причина, менее очевидная. Когда компания работает с несколькими маркетплейсами одновременно — Wildberries, Ozon, Яндекс Маркет — количество ручных операций растёт не линейно, а кратно. Каждая площадка со своим API, своей логикой статусов, своими требованиями к данным. Без единой точки интеграции в 1С хаос неизбежен.

Архитектура интеграции: от API до документа 1С

Общая схема выглядит так: регламентное задание в 1С по расписанию обращается к API маркетплейса, получает данные (заказы, возвраты, статусы), преобразует их в документы 1С и записывает в базу. Звучит просто. На практике каждый этап содержит нюансы.

Архитектура интеграции 1С с маркетплейсами

HTTP-клиент и авторизация

Wildberries использует Bearer-токен в заголовке Authorization. Ozon — пару Client-Id и Api-Key. Мы реализовали универсальный HTTP-клиент на базе объекта HTTPСоединение в 1С, который хранит параметры авторизации в справочнике настроек интеграции. Токены не хранятся в коде — только в защищённом справочнике с ограниченным доступом. Этот же подход применяем при построении интеграционного REST API слоя в 1С для других внешних систем.

Регламентные задания и расписание

Загрузка заказов работает через регламентное задание, запускаемое каждые 15 минут. Для возвратов — раз в час, потому что возвраты менее срочны и API маркетплейсов ограничивает частоту запросов.

Критически важный момент — защита от параллельного запуска. В одном из ранних вариантов мы столкнулись с тем, что два экземпляра регламентного задания стартовали одновременно и создавали дублирующие документы. Решение — семафор: перед началом работы задание проверяет константу-флаг, устанавливает её и сбрасывает после завершения. Если предыдущий запуск не завершился — новый не начинается.

Маппинг складов и номенклатуры

Маркетплейс оперирует своими идентификаторами складов и товаров. 1С — своими. Между ними нужна таблица соответствий. Мы реализовали отдельный справочник настроек, где для каждого склада маркетплейса указан склад 1С. Например, склад Wildberries с кодом «Коледино» маппится на транзитный склад «WB-Транзит» в 1С. Для Ozon FBO — аналогично, но с учётом того, что коды складов Ozon числовые и периодически меняются.

С номенклатурой сложнее. Об этом — отдельная история ниже.

Обработка ошибок и логирование

Любой HTTP-запрос к внешнему API может завершиться ошибкой: таймаут, 500 на стороне маркетплейса, невалидный JSON в ответе. Мы логируем каждый запрос и ответ в регистр сведений: дата, метод API, код ответа, тело запроса и ответа, время выполнения. Это позволяет разбирать инциденты постфактум — когда кладовщик говорит «заказ не загрузился», мы видим точную причину в логе, а не гадаем.

При ошибках HTTP-запроса используется стратегия повторных попыток: до трёх повторов с экспоненциальной задержкой (1 секунда, 3 секунды, 9 секунд). Если после трёх попыток запрос не прошёл — задание завершается, ошибка записывается в журнал регистрации, уведомление уходит ответственному.

Wildberries FBS: загрузка заказов и складские перемещения

Схема FBS (Fulfillment by Seller): клиент заказывает товар на WB, заказ приходит продавцу, продавец собирает и отгружает на склад WB для дальнейшей доставки. В 1С это отражается документом «Перемещение товаров» — с основного склада на транзитный склад маркетплейса.

Загрузка работает так: регламентное задание запрашивает список новых заказов через API WB (метод /api/v3/orders/new), проверяет каждый на дубль по уникальному идентификатору заказа, и для новых — создаёт документ перемещения.

Проблема сопоставления: почему артикул — это не товар

Первая версия интеграции искала номенклатуру в 1С по артикулу поставщика из заказа WB. Работало — до первого звонка со склада: «Мне пришёл заказ на футболку размера L/XL, а в перемещении стоит S/M».

Сопоставление номенклатуры: штрихкод vs артикул

Разбираемся. Артикул поставщика — например, DX0006 — это артикул модели, а не конкретной единицы товара. Футболка Nike Dri-FIT с артикулом DX0006 существует в 1С как два элемента номенклатуры: «Футболка Nike Dri-FIT S/M» и «Футболка Nike Dri-FIT L/XL». Запрос по артикулу DX0006 возвращает первый попавшийся — обычно тот, что создан раньше. Результат — случайный размер в документе.

Решение: сопоставлять по штрихкоду. В ответе API Wildberries каждый заказ содержит поле skus — массив штрихкодов конкретной единицы товара. Штрихкод уникален для размера, цвета и любой другой характеристики. Алгоритм сопоставления стал таким:

  1. Берём штрихкод из поля skus заказа WB.
  2. Ищем номенклатуру в 1С по штрихкоду через регистр сведений «Штрихкоды номенклатуры».
  3. Если по штрихкоду не нашли (бывает для старых товаров, которым штрихкоды не присвоены) — ищем по артикулу поставщика как fallback.
  4. Если не нашли вообще — помечаем заказ как «Требует ручного сопоставления» и отправляем уведомление.

После внедрения этой логики ошибки сопоставления прекратились полностью. Штрихкод — единственный надёжный идентификатор товарной единицы при обмене с маркетплейсами.

Обработка отмен и защита документов

Заказ WB может быть отменён после создания перемещения в 1С. При следующей загрузке статусов мы получаем статус, сигнализирующий об отмене. Первая реакция — удалить или пометить на удаление документ перемещения. Но если перемещение уже проведено и товар физически передан на транзитный склад — удаление сломает остатки.

Мы реализовали двухуровневую проверку: если документ перемещения ещё не проведён — помечаем на удаление. Если проведён (товар уже в пути или передан на WB) — создаём обратное перемещение. Статус «Передан в Wildberries» блокирует любые автоматические изменения документа — только ручное вмешательство.

Пакетная обработка и дубли

При загрузке заказов проверка на дубли — обязательный этап. API WB может вернуть один и тот же заказ повторно (например, при сбое подтверждения получения). Мы проверяем по уникальному идентификатору заказа WB через запрос к регистру сведений, где хранится связка «ID заказа WB — Документ 1С». Если запись есть — заказ пропускается.

Отдельная история — пакетная загрузка. Первая версия создавала отдельный документ перемещения на каждый заказ. При 200 заказах в день — 200 документов. Склад попросил объединять заказы в одно перемещение по дате отгрузки. Сделали. И получили race condition: два регламентных задания одновременно пытались дописать строки в один и тот же документ перемещения. Решение — вынесли формирование объединённых перемещений в отдельное регламентное задание с семафором. Загрузка заказов только записывает «сырые» данные в промежуточный регистр. Формирование документов — отдельный процесс, который гарантированно работает в один поток.

Ozon FBO: возвраты и партионный учёт

FBO (Fulfillment by Ozon) — схема, при которой товар хранится на складе Ozon. Возвраты FBO приходят обратно на склад продавца, и их нужно принять в 1С с правильными партиями. Здесь мы столкнулись с неочевидной проблемой в партионном учёте.

Обработка возвратов Ozon FBO с FIFO-логикой

Проблема: одна партия на все строки

Кладовщик сканирует штрихкод возвращённого товара. Документ возврата в 1С заполняется автоматически — номенклатура, количество, партия. Проблема возникла, когда в одном возврате было несколько единиц одного и того же товара из разных партий.

Исходная логика работала так: при добавлении строки в документ система находила номенклатуру по штрихкоду, затем определяла партию — и записывала её. При добавлении второй строки того же товара система снова находила партию — но ту же самую, потому что в кеше хранилась только одна партия на товар. В результате все строки одного товара получали одну и ту же партию, хотя реально товар приходил из разных поставок.

Решение: FIFO с исключением использованных партий

Мы переписали алгоритм подбора партий. Теперь он работает по принципу FIFO (First In — First Out) с исключением уже использованных партий в текущем документе:

  1. При добавлении строки система собирает список партий, которые уже назначены другим строкам этого же товара в текущем документе.
  2. Запрос к регистру остатков партий строится с условием NOT IN — исключая уже использованные.
  3. Из оставшихся выбирается самая старая партия (FIFO).
  4. Если свободных партий нет — строка помечается для ручного разбора.

Дополнительно мы изменили источник данных о партии. Вместо того чтобы подбирать партию из остатков по сложному алгоритму, для возвратов FBO партия копируется напрямую из исходного документа отгрузки на Ozon. Это логичнее: возвращается тот товар, который был отгружен, и партия должна быть той же.

Маппинг складов: неочевидные подмены кодов

Отдельный нюанс — коды складов в Ozon FBO. При возврате API Ozon передаёт код склада, на который товар возвращается. Но этот код может не совпадать с кодом склада, с которого товар был отгружен. В нашем случае отгрузка шла со склада с кодом 100, а возвраты приходили с кодом 580. Это один и тот же физический склад, но Ozon использует разные коды для разных операций.

Без учёта этой особенности документы возврата создавались на несуществующий склад в 1С. Мы добавили таблицу маппинга «код склада Ozon → склад 1С» с учётом типа операции (отгрузка/возврат), и проблема ушла. Важно, что такие несоответствия кодов не документированы в API Ozon — мы обнаружили их только при тестировании на реальных возвратах. Это ещё раз подтверждает: интеграцию с маркетплейсами нельзя написать по документации — нужно обкатывать на живых данных.

Подводные камни, которые не видно на старте

За время работы с интеграциями маркетплейсов мы накопили список проблем, которые не описаны в документации API и проявляются только на боевых данных.

Лимиты API. Wildberries и Ozon ограничивают количество запросов в минуту. При пакетной загрузке 500 заказов легко упереться в лимит. Решение — очередь запросов с паузами и retry-логикой. Если API вернул 429 (Too Many Requests) — ждём и повторяем, а не падаем с ошибкой.

Изменение API без предупреждения. Ozon несколько раз менял структуру ответа: добавлял поля, переименовывал параметры, менял формат дат. Wildberries — тоже. Мы закладываем устойчивость к неизвестным полям: парсер JSON игнорирует всё, что не использует, и не падает на новых полях. Критичные изменения отлавливаем через мониторинг: если загрузка не вернула ни одного заказа за 2 часа в рабочее время — уведомление в Telegram.

Часовые пояса и даты. API Wildberries возвращает даты в UTC. Ozon — тоже, но в другом формате. 1С работает в локальном времени сервера. Если не конвертировать — заказы «из будущего» или пропущенные заказы за последний час дня. Все даты из API приводим к UTC, храним в UTC, конвертируем в локальное время только для отображения пользователю.

Номенклатура без штрихкодов. Старые товары в 1С часто не имеют присвоенных штрихкодов. Интеграция по ним работает через fallback на артикул — с риском ошибки размера/цвета. Первое, что мы делаем при запуске интеграции — генерируем и присваиваем штрихкоды всей номенклатуре, которая торгуется через маркетплейсы. Это разовая операция, но без неё надёжное сопоставление невозможно.

Тестирование на боевых данных. Маркетплейсы не предоставляют полноценных тестовых сред. Wildberries имеет песочницу, но с ограниченной функциональностью. Ozon — практически нет. Тестирование приходится вести аккуратно на боевом API с реальными заказами. Мы используем флаг «тестовый режим», при котором данные загружаются и обрабатываются, но документы создаются с пометкой «Тест» и не проводятся.

Конфликт обновлений конфигурации. Если 1С:ERP или 1С:УНФ обновляются, структура регистров и документов может измениться. Интеграционный код, который напрямую обращается к реквизитам документов, перестаёт работать. Подробнее о том, как выстраивать устойчивые интеграции с магазинами и избегать таких ситуаций, — в материале про обмен данными между 1С и интернет-магазином. Мы выносим всю работу с прикладными объектами в отдельный модуль-адаптер: интеграционная логика вызывает функции адаптера, а адаптер знает актуальную структуру объектов. При обновлении конфигурации достаточно поправить адаптер, а не переписывать всю интеграцию.

Обработка больших объёмов данных. При выходе на высокие обороты — тысячи заказов в день — стандартный подход «один запрос к API за все заказы» перестаёт работать. API отдаёт данные постранично, и нужно корректно обрабатывать курсор пагинации. В одном из проектов мы обнаружили, что Wildberries API при большом количестве новых заказов иногда «теряет» последнюю страницу, если между запросами проходит слишком много времени. Решение — уменьшить размер страницы и увеличить частоту опроса, чтобы за один цикл обрабатывать не более 50-100 заказов.

Интеграция 1С с маркетплейсами — это не разовая задача «настроил и забыл». API меняются, бизнес-процессы усложняются, появляются новые площадки. Архитектура должна быть такой, чтобы подключение нового маркетплейса сводилось к написанию нового адаптера, а не к переделке всей системы. Тот проект, который начался с 200 заказов WB в день, через полгода добавил Ozon, потом Яндекс Маркет — и каждое подключение занимало дни, а не недели, потому что база была заложена правильно с самого начала. Каждый новый маркетплейс мы подключаем как отдельное расширение конфигурации 1С — это позволяет отключить интеграцию без последствий для основной системы.