Менеджер поднял цену в МойСклад, кладовщик отгрузил последнюю коробку — а на сайте товар всё ещё «в наличии» по старой цене. Покупатель оформляет заказ, которого по факту нет, и вы теряете либо деньги, либо репутацию. Ровно эту дыру закрывает синхронизация номенклатуры между МойСклад и 1С-Битрикс: остатки, цены и карточки товаров живут в одном источнике правды, а витрина всегда показывает актуальную картину.
Ниже — практическая схема двустороннего обмена: как связать позиции по стабильному ключу, что и в какую сторону синхронизировать, как выбрать между вебхуками и опросом, и как построить очередь, которая не теряет заказы при сбое API. Это выжимка из наших проектов по интеграции МойСклад с 1С-Битрикс — без общих слов, с конкретикой по инфоблокам, свойствам и агентам платформы.
Коротко
- У МойСклад нет CommerceML под Битрикс — обмен строится через REST JSON API и коннектор.
- Свяжите позиции по стабильному UUID МойСклад в свойстве элемента, а не по названию.
- Задайте владельца каждому полю: остатки и цены ведёт МойСклад, контент — сайт, заказы — сайт.
- Остатки гоняйте по вебхуку или частым опросом, номенклатуру — реже, полную сверку — ночью.
- Заказы пишите в очередь с повторами: витрина не должна зависеть от доступности МойСклад.
Зачем связывать МойСклад и Битрикс
МойСклад — это облачная система товароучёта: приёмка, отгрузка, себестоимость, резервы, ценообразование, документы. 1С-Битрикс — витрина и движок интернет-магазина: каталог, корзина, оформление заказа, личный кабинет, SEO. Пока эти две системы живут порознь, кто-то в компании вручную переносит между ними товары и остатки — и именно на этом ручном звене копятся ошибки.
Автоматическая синхронизация убирает ручной труд и делает данные согласованными. Практически это даёт четыре измеримых эффекта. Во-первых, витрина показывает реальные остатки, и покупатель не заказывает то, чего нет. Во-вторых, цена на сайте всегда совпадает с ценой в учёте — не бывает ситуации «на сайте дешевле, чем в кассе». В-третьих, новый товар, заведённый в МойСклад, автоматически появляется на сайте, а снятый с продажи — прячется. В-четвёртых, заказы с сайта сразу попадают в учёт как документы, и менеджеру не нужно перебивать их руками.
Отдельно стоит подчеркнуть: МойСклад часто выбирают именно небольшие и средние магазины, которым «полноценная» 1С избыточна. Для них связка «МойСклад + Битрикс» — это способ получить нормальный товароучёт без внедрения тяжёлой ERP. Но техническая цена такого выбора в том, что готового двустороннего протокола, как обмен с «1С:Предприятие», здесь нет — интеграцию нужно проектировать. Если у вас как раз стоит выбор между МойСклад и 1С, полезно заранее посмотреть на классический обмен магазина с 1С и оценить, какой сценарий ближе вашему процессу.
Архитектура обмена: кто с кем разговаривает
Чтобы проектировать интеграцию осознанно, полезно держать в голове её слои. Обмен между МойСклад и Битриксом — это не «одна кнопка», а конвейер из нескольких компонентов, у каждого своя зона ответственности.
- REST API МойСклад. Источник и приёмник данных со стороны учёта. Отдаёт товары, модификации, цены, остатки в формате JSON и принимает документы заказов.
- Коннектор (модуль обмена). Прослойка на стороне сайта, которая ходит в API, преобразует форматы, ведёт сопоставление и очереди. Это либо решение из Маркетплейса, либо собственный модуль.
- Инфоблоки каталога Битрикса. Приёмник номенклатуры: инфоблок товаров, инфоблок торговых предложений, каталог цен и складов торгового каталога.
- Агенты и вебхуки. Триггеры обмена: агенты платформы запускают опрос по расписанию, вебхуки МойСклад толкают изменения в реальном времени.
- Очередь и журнал. Буфер, который хранит незавершённые операции (например, неотправленные заказы) и лог всех обменов для разбора инцидентов.
Данные ходят по этой цепочке в обе стороны. От МойСклад к сайту движется «мастер-справочник»: товары, характеристики, цены, остатки. От сайта к МойСклад движутся заказы и, при необходимости, витринные правки, если сайт назначен владельцем какого-то поля. Понимание, где именно проходит каждый поток, сразу подсказывает, где искать проблему: если на сайте старый остаток — смотрим поток «МойСклад → сайт» и его триггер, если заказ не дошёл в учёт — смотрим очередь и поток «сайт → МойСклад».
Ведущая система и владельцы полей
Главное проектное решение принимается до первой строчки кода: нужно определить, какая система «главная» по каждому полю. Если этого не сделать, две системы начнут писать в одно и то же поле навстречу друг другу, и обмен превратится в качели, где каждая сторона затирает изменения другой.
Правильный подход — назначить каждому полю ровно одного владельца. Владелец имеет право записи, остальные только читают. Типовое распределение для связки «МойСклад + Битрикс» выглядит так:
| Поле / сущность | Владелец | Кто читает |
|---|---|---|
| Номенклатура, артикул, модификации | МойСклад | Сайт (создаёт карточки) |
| Отпускные цены, типы цен | МойСклад | Сайт (витрина) |
| Остатки по складам | МойСклад | Сайт (наличие) |
| Описание, SEO-поля, фото, разделы | Сайт | — |
| Заказы покупателей | Сайт | МойСклад (документы) |
| Статусы отгрузки заказа | МойСклад | Сайт (личный кабинет) |
Обратите внимание на строку с контентом: описания, SEO-теги и привязку к разделам каталога почти всегда лучше держать на стороне сайта. В МойСклад описание товара — это учётное поле, оно не заточено под витрину и SEO. Если разрешить МойСклад перезаписывать описание, при каждом обмене ваши вылизанные тексты и метатеги будут затираться скупыми учётными строками. Поэтому контентные поля исключают из потока «МойСклад → сайт» на уровне маппинга.
Сопоставление товаров: ключи связи
Второй фундаментальный вопрос — как система понимает, что «вот эта позиция в МойСклад» и «вот этот элемент каталога Битрикса» — один и тот же товар. Это называется сопоставлением (матчингом), и от надёжности ключа зависит, будет ли обмен создавать дубли или аккуратно обновлять существующие карточки.
Ключи сопоставления сильно различаются по надёжности:
- UUID МойСклад (поле
id) — самый надёжный ключ. Это неизменный глобальный идентификатор позиции. Он присваивается при создании и живёт с товаром всю жизнь, что бы ни делали с названием и артикулом. Его хранят в отдельном свойстве элемента инфоблока. - Артикул / код — хороший запасной ключ. Обычно уникален и осмыслен, но его иногда меняют или переиспользуют, поэтому как единственный ключ он рискован. Годится для первичного связывания существующего каталога с МойСклад.
- Штрихкод (EAN) — узкий, но точный ключ. Хорош там, где он есть у всех позиций, но у услуг и части товаров штрихкода нет.
- Название — использовать нельзя. Названия правят, переводят, дублируют и склоняют. Любая правка порвёт связь и породит дубль. Это антипаттерн.
Рабочая схема: основной ключ — UUID МойСклад, который сохраняется в служебное свойство элемента (например, MOYSKLAD_ID) при первом обмене; запасной ключ на этапе первичной сцепки существующего каталога — артикул. Дальше вся синхронизация идёт по UUID, а артикул остаётся человекочитаемым атрибутом. Такой подход мы разбираем и в общем материале про интеграцию с МойСклад, потому что от выбора ключа зависит устойчивость всей связки.
Что синхронизируем: номенклатура, цены, остатки
Полезно разложить обмен на три независимых потока данных. У каждого своя частота, свои поля и своя логика конфликтов, и смешивать их в один «большой обмен» — ошибка проектирования.
Номенклатура. Это «медленный» справочник: сами товары, их артикулы, единицы измерения, привязка к группам, набор характеристик. Меняется относительно редко — при заведении новых позиций или правке карточек. Из МойСклад приходят товары и модификации; на сайте они превращаются в элементы каталога и торговые предложения. Именно в этом потоке живут решения про контент: какие поля сайт принимает, а какие ведёт сам.
Цены. МойСклад умеет вести несколько типов цен (розничная, оптовая, специальная). На сайте им соответствуют типы цен торгового каталога. Здесь важно заранее договориться о маппинге: какой тип цены МойСклад в какой тип цены Битрикса ложится, и что показывать на витрине для розничного и оптового покупателя. Цены меняются чаще номенклатуры, но реже остатков.
Остатки. Это самый «горячий» и самый чувствительный к задержке поток. Остаток меняется при каждой продаже и отгрузке, и именно его рассинхрон бьёт по бизнесу сильнее всего — либо продаёте то, чего нет, либо прячете то, что есть. Если у вас несколько складов, остатки приходят в разрезе складов, и нужно решить, как их сводить в витринное «в наличии»: суммировать, брать по конкретному складу или считать по правилам доступности. Мультискладовую логику мы подробно разбираем в материале про обмен остатками при нескольких складах и WMS.
Направления обмена и частота
Слово «двусторонний» звучит просто, но на деле у обмена не одно, а несколько направлений, и у каждого своя частота. Свести их в таблицу — значит сразу увидеть нагрузку на API и точки риска.
| Поток | Направление | Частота | Триггер |
|---|---|---|---|
| Остатки | МойСклад → сайт | Почти реального времени | Вебхук или частый агент |
| Цены | МойСклад → сайт | 15–60 минут | Агент по расписанию |
| Новые товары | МойСклад → сайт | По событию / раз в час | Вебхук создания |
| Заказы | Сайт → МойСклад | Реального времени, через очередь | Событие оформления |
| Статусы отгрузки | МойСклад → сайт | 10–30 минут | Агент по расписанию |
| Полная сверка | Двусторонняя | Раз в сутки, ночью | Агент в часы низкой нагрузки |
Ключевая мысль: не пытайтесь всё синхронизировать одинаково часто. Гонять полную номенклатуру каждые пять минут бессмысленно и вредно — вы упрётесь в лимиты API МойСклад и создадите лишнюю нагрузку. Наоборот, обновлять остатки раз в час опасно — за час можно продать несуществующий товар. Разнесите частоты по важности и изменчивости поля, а «тяжёлую» полную сверку уведите на ночь.
Модификации и торговые предложения
Отдельная тема, на которой спотыкаются многие внедрения, — модификации. В МойСклад товар может иметь модификации (вариации по характеристикам: цвет, размер, объём). В Битриксе этому соответствует механизм торговых предложений (SKU) — отдельный инфоблок, привязанный к каталогу товаров. Задача обмена — корректно разложить одну сущность МойСклад на две сущности Битрикса.
Схема отображения такая: родительский товар МойСклад становится элементом каталога товаров, а каждая его модификация — элементом инфоблока торговых предложений, привязанным к этому товару. Характеристики модификации (тот самый «цвет: синий, размер: L») превращаются в свойства торгового предложения. Артикул, цена и остаток у каждой модификации свои, поэтому обмен ведёт их на уровне SKU, а не на уровне родителя.
На что обратить внимание при проектировании модификаций:
- Уровень остатка и цены — SKU. Остаток и цена принадлежат конкретной модификации. Родительский товар их не хранит, он агрегирует наличие своих предложений.
- Характеристики — в свойства предложений. Те характеристики модификации, по которым покупатель выбирает и фильтрует, выносят в свойства SKU и включают в умный фильтр.
- Стабильные ключи на обоих уровнях. И у родителя, и у каждой модификации МойСклад свой UUID — храните оба, иначе при обмене перепутаете вариации.
- Товары без модификаций. Простой товар без вариаций тоже можно завести как товар с единственным предложением — это унифицирует обработку каталога.
Тонкости разложения модификаций на торговые предложения и настройку свойств SKU мы подробно разбираем в отдельных материалах рубрики Интеграции — здесь же важно зафиксировать принцип: одна модификация МойСклад = одно торговое предложение Битрикса, связанные стабильными идентификаторами.
Вебхуки против опроса по расписанию
Есть два способа узнать, что в МойСклад что-то изменилось: спросить самому (опрос, polling) или дождаться, когда МойСклад сам сообщит (вебхук, webhook). У обоих есть место в правильной архитектуре, и обычно их комбинируют.
Опрос по расписанию (агент Битрикса). Сайт периодически ходит в API МойСклад и спрашивает: «что изменилось с прошлого раза?». Плюсы — простота и полный контроль на стороне сайта, устойчивость к пропущенным событиям. Минусы — задержка (изменение увидите только на следующем цикле) и лишние запросы вхолостую, когда ничего не менялось.
Вебхуки МойСклад. МойСклад сам шлёт HTTP-запрос на ваш эндпоинт в момент изменения товара, цены или остатка. Плюсы — минимальная задержка и отсутствие холостых опросов. Минусы — нужен публично доступный и защищённый эндпоинт, а также обработка ситуации, когда вебхук не дошёл (сеть, перезагрузка, ошибка). Вебхук нельзя считать «гарантированной доставкой».
| Критерий | Вебхуки | Опрос по расписанию |
|---|---|---|
| Задержка | Секунды | Интервал агента |
| Нагрузка на API | Низкая, только по событию | Постоянная, даже вхолостую |
| Надёжность доставки | Событие можно потерять | Высокая, всегда доспросит |
| Требования к инфраструктуре | Публичный защищённый эндпоинт | Только агент на сайте |
| Лучшее применение | Остатки, новые товары | Полная сверка, страховка |
Практичная стратегия — гибрид: вебхуки для мгновенной реакции на остатки и новые товары, плюс ночной опрос-сверка как страховка, которая догоняет всё, что вебхуки могли пропустить. Так вы получаете и низкую задержку, и гарантию, что за сутки любой рассинхрон будет вычищен.
Реализация в 1С-Битрикс
Теперь конкретика по платформе. Вне зависимости от того, берёте ли вы готовый модуль из Маркетплейса или пишете свой коннектор, набор задач на стороне Битрикса примерно одинаковый. Разложим внедрение на шаги.
- Подготовьте структуру каталога. Создайте инфоблок товаров и инфоблок торговых предложений в модуле «Торговый каталог», задайте типы цен (розница, опт) и склады, соответствующие складам МойСклад.
- Добавьте служебные свойства. В инфоблоки товаров и предложений добавьте свойства для внешних идентификаторов:
MOYSKLAD_ID(UUID) и, при необходимости, поле времени последней синхронизации. Это ключи и метки обмена. - Получите доступ к API МойСклад. Заведите отдельного пользователя или токен доступа для интеграции, ограничьте права только нужными сущностями (товары, цены, остатки, заказы). Не используйте личный логин администратора.
- Опишите маппинг полей. Составьте таблицу соответствия «поле МойСклад → поле инфоблока», зафиксировав владельцев полей: какие данные сайт принимает, а какие ведёт сам и в обмен не отдаёт.
- Реализуйте импорт номенклатуры. Напишите обработчик, который читает изменённые позиции по API (с фильтром по дате изменения), создаёт или обновляет элементы каталога и торговые предложения по ключу UUID.
- Настройте обновление цен и остатков. Отдельными потоками обновляйте цены в таблицах торгового каталога и остатки по складам — по вебхуку и/или агентом с нужной частотой.
- Настройте агенты и вебхуки. Зарегистрируйте агенты платформы для опроса и сверки, поднимите защищённый эндпоинт под вебхуки МойСклад с проверкой подписи или секрета.
- Реализуйте выгрузку заказов. На событии оформления заказа кладите его в очередь, а фоновым агентом отправляйте в МойСклад с повторами и логированием.
- Включите журналирование. Пишите лог всех обменов: что пришло, что записалось, какие были ошибки. Без журнала разбирать инциденты рассинхрона практически невозможно.
Как это выглядит в админке
Со стороны Битрикса настройка обмена — это связка «служебные свойства инфоблока + агенты + панель модуля обмена». Схематично экран настройки коннектора выглядит так:
Обратите внимание на две детали этой схемы. Первая — раздельные интервалы для остатков и цен: это прямое следствие принципа «три потока — три частоты». Вторая — маппинг типов цен и складов: без явного соответствия «розничная цена МойСклад → тип цены BASE в Битриксе» и «склад в МойСклад → склад в каталоге» обмен не будет знать, куда класть значения.
Очереди, повторы и защита от сбоев
Любая интеграция с внешним API обязана предполагать, что API иногда недоступно. МойСклад — облачный сервис: у него бывают технические работы, таймауты и превышения лимитов. Если ваш обмен написан в предположении «API всегда отвечает мгновенно и без ошибок», первый же сбой обернётся потерянными заказами или зависшим сайтом.
Правильная защита строится на трёх принципах.
- Асинхронность через очередь. Заказ или изменение не отправляются в МойСклад прямо в обработчике пользовательского действия. Они пишутся в собственную очередь на стороне сайта, а доставкой занимается фоновый агент. Пользователь получает ответ мгновенно и не ждёт внешний сервис.
- Повторы с нарастающей паузой. Если попытка доставки не удалась, операция остаётся в очереди и повторяется позже, увеличивая паузу между попытками (экспоненциальный backoff). Так вы не долбите упавший сервис и даёте ему восстановиться.
- Идемпотентность. Повторная отправка того же заказа не должна создавать в МойСклад дубль. Для этого при создании документа передают внешний идентификатор заказа сайта, а перед созданием проверяют, нет ли уже документа с таким ключом.
Отдельно — обработка ошибок валидации. Одно дело, когда API недоступно (это лечится повтором), и совсем другое — когда МойСклад отклонил данные из-за некорректного поля (это повтором не лечится, нужен разбор). Разделяйте временные ошибки (сеть, таймаут, лимит) и постоянные (валидация, права): первые уводите в повтор, вторые — в журнал ошибок для ручного разбора, чтобы не зациклить очередь на заведомо «битой» операции.
Борьба с рассинхроном и дублями
Даже при аккуратной архитектуре данные со временем «расходятся»: где-то потерялся вебхук, где-то менеджер поправил позицию в обход обмена, где-то сбой прервал цикл на середине. Рассинхрон — не исключение, а нормальное состояние, к которому нужно быть готовым. Инструменты борьбы с ним такие.
- Ночная полная сверка. Раз в сутки прогоняйте сверку всей номенклатуры, цен и остатков против МойСклад. Она догоняет всё, что пропустили инкрементальные обмены за день.
- Метка времени синхронизации. Храните у каждой позиции время последнего успешного обмена. Позиции, которые давно не обновлялись, — кандидаты на проверку.
- Отчёт расхождений. Сверка должна не молча «чинить», а логировать, что и почему разошлось. Систематические расхождения указывают на дыру в архитектуре, а не на случайность.
- Защита от дублей на импорте. Перед созданием новой карточки всегда ищите существующую по UUID и запасному ключу. Создание «вслепую» — главный источник дублей каталога.
Особый случай — дубли, которые появились до внедрения обмена, когда каталог вели вручную. Перед запуском синхронизации проведите разовую чистку и первичное сопоставление: сцепите существующие карточки с позициями МойСклад по артикулу, проставьте им UUID, а найденные дубли объедините. Запускать регулярный обмен на «грязном» каталоге — значит закрепить бардак и размножить его автоматически.
Заказы обратно в МойСклад
Синхронизация номенклатуры — половина дела. Вторая половина — вернуть в МойСклад то, ради чего всё затевалось: заказы. Когда покупатель оформляет заказ на сайте, он должен превратиться в документ МойСклад (заказ покупателя или отгрузка), чтобы менеджер работал с ним в привычной учётной системе, а остаток корректно зарезервировался.
Что важно передать вместе с заказом:
- Позиции с привязкой по UUID. Каждая строка заказа ссылается на конкретную позицию или модификацию МойСклад по её идентификатору, а не по названию.
- Контрагента. Покупателя нужно либо найти среди существующих контрагентов, либо создать нового — тоже по стабильному ключу (телефон, email), чтобы не плодить дубли клиентов.
- Цены и скидки заказа. В документ уходят те цены, по которым фактически оформлен заказ, включая примененные скидки, а не текущие цены из справочника.
- Внешний идентификатор. Номер заказа сайта передаётся как внешний ключ документа — это основа идемпотентности и обратной связи по статусам.
Обратный поток — статусы. Когда заказ в МойСклад проходит через сборку, отгрузку и доставку, эти статусы полезно возвращать на сайт в личный кабинет покупателя. Здесь снова работает связка по внешнему идентификатору: агент периодически спрашивает МойСклад о состоянии отгрузок и обновляет статусы соответствующих заказов на витрине. Тему обмена заказами и статусами мы разбираем отдельно, а общий принцип интеграции витрины с учётной системой — в материале про интеграцию магазина с 1С, где логика документооборота во многом схожая.
Частые ошибки
- Сопоставляют товары по названию — любая правка или перевод названия рвёт связь и рождает дубль в каталоге.
- Разрешают обеим системам писать в одно поле — описания и цены начинают «воевать» и затирать друг друга при каждом обмене.
- Отправляют заказ в МойСклад прямо из обработчика оформления — при недоступности API покупатель ловит ошибку, а заказ теряется.
- Синхронизируют всё с одной частотой — остатки отстают на час либо API упирается в лимиты из-за лишних полных выгрузок.
- Забывают про идемпотентность — повторная отправка при сбое создаёт в учёте задвоенные документы заказов.
- Не ведут журнал обмена — при рассинхроне невозможно понять, что и когда разошлось, и починка превращается в гадание.
- Запускают регулярный обмен на «грязном» каталоге с дублями — автоматизация закрепляет и размножает существующий бардак.
- Дают интеграции права администратора МойСклад вместо узкого токена — лишний риск безопасности и случайных изменений.
- Игнорируют мультискладовую логику — суммируют остатки всех складов, включая те, откуда фактически не отгружают на сайт.
Чек-лист внедрения
Сведём всё в практический список, по которому удобно принимать готовность интеграции перед запуском:
- Владельцы полей определены. Составлена таблица «поле → владелец», контентные и SEO-поля закреплены за сайтом и исключены из потока «МойСклад → сайт».
- Ключ сопоставления выбран. Основной ключ — UUID МойСклад в свойстве элемента; запасной — артикул; сопоставление по названию исключено.
- Каталог подготовлен. Инфоблоки товаров и предложений, типы цен и склады созданы и сопоставлены со складами и типами цен МойСклад.
- Потоки разнесены по частоте. Остатки — вебхук/частый агент, цены — реже, номенклатура — по событию, полная сверка — ночью.
- Модификации разложены. Модификации МойСклад ложатся в торговые предложения, характеристики вынесены в свойства SKU для фильтра.
- Заказы через очередь. Выгрузка заказов асинхронна, с повторами и идемпотентностью по внешнему ключу; витрина не зависит от доступности API.
- Журнал и сверка включены. Ведётся лог обмена, ночная сверка догоняет рассинхрон и пишет отчёт расхождений.
- Доступ ограничен. Интеграция ходит под отдельным токеном с минимально необходимыми правами, а не под администратором.
Вывод
Надёжная синхронизация МойСклад и 1С-Битрикс держится на нескольких простых, но обязательных решениях: стабильный ключ сопоставления по UUID, чёткие владельцы полей, разнесённые по частоте потоки данных и заказы через очередь с повторами. Соберите эти четыре опоры — и витрина всегда покажет актуальные остатки и цены, заказы не потеряются при сбое API, а каталог не обрастёт дублями. Всё остальное — детали маппинга, которые настраиваются под конкретный ассортимент и процесс.