Обмен 1С ↔ сайт через REST вместо CommerceML — когда оправдан
CommerceML — типовой обмен между 1С и сайтом, родной для Битрикса и многих CMS. Работает, но грузит партиями XML по cron, режет real-time и плохо переносит сложные витрины. REST-обмен — гибче и быстрее, но требует инженерных решений. Разбираем, когда REST окупается и как его собрать без вечных конфликтов остатков.
CommerceML — стандарт обмена между 1С и сайтом, который работает с 2000-х годов. Простой по смыслу: 1С выгружает XML с товарами и предложениями, сайт скачивает архив по HTTP и импортирует. В обратную сторону — заказы выгружаются с сайта аналогично. Битрикс умеет это из коробки, для большинства CMS есть готовые модули.
Проблема не в самом протоколе, а в его модели работы — batch-обмен по расписанию. Стоит магазину перейти из лоу-трафика в режим «остатки меняются каждые 10 минут, цены прыгают, маркетплейсы и склад одновременно тащат данные» — CommerceML начинает протекать. Тут на сцену выходит REST.
Что не так с CommerceML в 2026
Конкретные больные точки в активных проектах:
- Полная выгрузка ради двух правок. Изменилась цена одного товара — выгружается архив на 80 000 SKU. Импорт час, сервер в нагрузке.
- Cron-задержка. Cron раз в 30 минут — реалистичный потолок. Покупатель видит «есть в наличии» через 25 минут после того, как 1С зафиксировала отгрузку.
- Конфликты при параллельных изменениях. Сайт принял заказ, через 2 минуты 1С выгрузила старый остаток — товар на витрине снова появился. Покупатель попадает в негатив.
- Жёсткая структура XML. Любое расширение типа «гарантия 24 месяца» или «совместимые модели» в стандарт не лезет — пихается в служебные поля или отдельные обмены.
- Цепочка «1С → файл → веб-сервер → импорт» хрупкая. Падение на любом шаге значит «синхронизации не было». Логи неинформативные, восстановление вручную.
- Сложно дебажить. XML на 200 МБ через WinMerge — это боль.
Когда CommerceML достаточно
До REST переходить рано, если:
- Каталог <3 000 SKU, обновления раз в день или реже.
- Сайт на типовом Битриксе, нет планов разнести фронт.
- Нет интеграций с маркетплейсами, складом, кассами в режиме real-time.
- Команда разработки минимальная, поддержка через подрядчика на типовых задачах.
В этих сценариях CommerceML — рабочий вариант. Не чините то, что не сломано.
Когда REST окупается
Стоит переходить, если есть хотя бы три из списка:
- Каталог >10 000 SKU и активно растёт.
- Остатки меняются чаще, чем раз в час, и это важно для конверсии.
- Магазин торгует на маркетплейсах — нужен единый источник остатков.
- На сайте есть личный кабинет с балансом, статусом отгрузки, бонусами — это требует real-time.
- Сайт построен не на Битриксе или на head-less архитектуре.
- Нужно интегрировать платежи и доставку с событиями в 1С.
- Команда разработки штатная или регулярный подрядчик.
Архитектура REST-обмена
Базовая схема — четыре слоя:
- 1С с HTTP-сервисами (BAS, http-сервисы из конфигуратора) или внешним REST-фасадом.
- Брокер сообщений или очередь (RabbitMQ, Kafka, Redis Streams, PostgreSQL LISTEN/NOTIFY).
- Service worker на бэкенде сайта, слушает очередь и применяет изменения.
- Sync state — таблица с маппингом ID 1С ↔ ID сайта, метками синхронизации, последним изменением.
Поток: изменение в 1С → событие в очередь → worker применяет на сайте → подтверждение → обновление sync state. В обратную сторону — заказы с сайта в очередь, 1С тащит из веб-сервиса или принимает webhook.
Реальное API
Пример набора эндпоинтов сайта, которые слушает 1С:
POST /api/sync/products/upsert
{ ext_id, name, price, currency, weight, vat,
attributes: {...}, variants: [...] }
→ { id, ext_id, status: "ok" | "conflict", version }
POST /api/sync/stocks/batch
{ items: [ { ext_id, warehouse_code, qty } ] }
→ { applied: 384, conflicts: 0 }
POST /api/sync/orders/status
{ order_ext_id, status, tracking, updated_at }
→ { ok: true, version }
GET /api/sync/orders/since?ts=2026-06-12T00:00:00Z
→ { orders: [...] }
GET /api/sync/products/dirty?since=...
→ { items: [...] }
Все эндпоинты идемпотентные: повторный вызов с тем же ext_id и updated_at не должен ломать состояние.
Идемпотентность и версионирование
В асинхронной системе сообщения иногда дублируются, иногда теряются, иногда приходят в неправильном порядке. Без идемпотентности это разрушает данные.
Минимум, что нужно:
- Уникальный
ext_idна стороне 1С. По нему мэппинг на сайт. updated_atилиversionна каждой записи. При апдейте — сравниваем: если входящий старше — отбрасываем.- Журнал применённых событий (event_id из 1С). Перед обработкой — проверка «не было ли это уже».
- Optimistic locking на критичных полях (остаток): входящий апдейт идёт с
if-match: version=N, если на сайте уже N+1 — отказ и пересчёт.
Самая болезненная точка — остатки
Конфликт сценария: на сайте оформлен заказ, остаток уменьшился. Параллельно 1С прислала обновление остатка из учёта (без учёта этого заказа). Если просто перезаписать — товар «появится» обратно, и сайт продаст его повторно.
Решение — модель «дельт и резервов», а не «текущего остатка»:
- Сайт хранит остаток как:
actual_qty - reserved_by_orders. - 1С шлёт дельты: «+15 пришло на склад», «-3 списано на отгрузку» — а не «теперь 47».
- Сайт ведёт собственные резервы при оформлении заказа.
- Раз в N минут — сверка:
SELECTагрегата дельт и резервов =actual_qtyс сайта.
Это сложнее, но единственный способ не задвоить продажу при высокой нагрузке. Альтернатива — централизация остатков в WMS, и 1С с сайтом получают данные оттуда.
Безопасность
REST-эндпоинты сайта будут торчать в интернет. Минимум:
- TLS обязательно.
- Аутентификация — JWT с коротким сроком или взаимный mTLS.
- Rate limiting на эндпоинт по токену.
- IP-whitelist для исходящих от 1С (если 1С на статическом IP).
- Логирование всех изменений с маркером, какая система их инициировала.
Стек на стороне 1С
Три рабочих варианта:
- HTTP-сервисы 1С — встроены в платформу, пишут на встроенном языке. Удобно для серверных конфигураций, нагрузка средняя.
- 1С + внешний фасад (Python/Go-сервис между 1С и интернетом). 1С шлёт по локальной сети, фасад отвечает за rate limit, кэш, очередь.
- Шина данных (1С → DataLens-style middleware → сайт). Оправдано при 3+ системах в обмене.
Реалистичная оценка миграции
Перевод магазина с CommerceML на REST — не один спринт. Реалистичный план для каталога 30 000 SKU + 200 заказов в день:
- Аудит текущего обмена и схемы данных — 1 неделя.
- Доработка 1С под HTTP-сервисы и события — 3–6 недель.
- Бэкенд сайта: API, sync state, worker, очередь — 4–8 недель.
- Перевод остатков на модель дельт — 2–3 недели.
- Параллельная работа CommerceML + REST 2–4 недели с реальным трафиком.
- Полный переход, мониторинг 1 месяц.
Итого — 3–5 месяцев календарно, бюджет на команду 1С + бэкенд + DevOps. Дешёвых вариантов нет, попытки сделать «за месяц» обычно приводят к рассинхрону данных и эпическому откату.
Грабли
- «Перевожу обмен, оставлю остатки на CommerceML». Гибрид CommerceML + REST на тех же сущностях — мина. Либо мигрируем всё, либо ничего.
- Без очереди. Прямой sync 1С → API сайта без брокера. Сайт упал — события потеряны. Возврат к XML по cron.
- Логика на стороне сайта дублирует 1С. Расчёт скидок, налогов, наценок в двух местах — источник вечных расхождений. Один источник истины, остальное — отображение.
- Перенос всех справочников целиком. Сайту нужны не все 200 справочников из 1С. Перенесите только те, что показываются клиенту.
- Отказ от sync state-таблицы. «Будем по timestamp» работает плохо, особенно когда 1С обновляет данные обратно во времени.
Вывод
CommerceML — рабочий стандарт для типовых интернет-магазинов на Битриксе с обновлениями раз в день. REST становится необходимым, когда подключаются маркетплейсы, real-time остатки и нестандартная архитектура сайта. Переход — 3–5 месяцев, нужна правильная архитектура: очередь, идемпотентность, остатки через дельты и резервы, sync state. Гибрид CommerceML + REST на тех же сущностях — категорически нет.