Интернет-магазин и учётная система обмениваются простыми вещами: каталог, цены, остатки, заказы. Этого достаточно, потому что покупатель платит сразу, никакого договора с ним нет, а вся «история отношений» умещается в одном заказе. B2B-портал устроен иначе. За каждым клиентом стоит контрагент с договором, персональными ценами, балансом, отсрочкой и кредитным лимитом; заказы связаны с историей отгрузок и оплат; на портале нужно показывать не только «что почём», но и «сколько вы должны, сколько можно взять в долг и по каким документам». Всё это живёт не в магазине, а в ERP — и должно аккуратно, надёжно и вовремя доходить до портала.
Эта статья — практический разбор того, как связать b2b портал erp на 1С-Битрикс: какие данные обмениваются (номенклатура и характеристики, договорные цены по контрагенту, остатки по складам, заказы и статусы, взаиморасчёты, лимиты и документы), какими способами (CommerceML, REST API и очереди для реального времени), кто чему хозяин (мастер-система и разграничение ответственности), как выдержать объёмы и производительность, обеспечить надёжность и безопасность обмена и внедрить всё это поэтапно. Материал из нашей практики разработки B2B-порталов и личных кабинетов — по делу, без обещаний «бесшовной интеграции в один клик».
Коротко
- Интеграция B2B-портала с ERP сложнее розничной: кроме каталога и заказов обмениваются договорными ценами, взаиморасчётами, дебиторкой, лимитами и документами.
- Пять костяковых потоков: номенклатура, цены по контрагенту, остатки по складам, заказы и статусы, финансы (баланс, лимит, документы).
- Способы обмена комбинируют: CommerceML для объёмов, REST API для актуальности, очереди для надёжной доставки событий.
- Ключ к порядку — мастер-система: ERP хозяин цен, остатков и финансов, портал хозяин нового заказа; никто не перетирает чужие данные.
- Надёжность держится на идемпотентности, ретраях и наблюдаемости, а актуальность — на разделении потоков и корректной инвалидации кэша.
Почему интеграция B2B-портала с ERP сложнее розничной
Начнём с честного сравнения. Розничный интернет-магазин, интегрированный с 1С, обменивается по сути четырьмя вещами: выгрузкой каталога (товары и картинки), ценами (обычно одна-две колонки), остатками и заказами. Клиент кладёт товар в корзину, платит картой, заказ уходит в учёт — цикл замкнулся. Никакой «истории отношений» с покупателем нет: сегодня он есть, завтра его нет, и системе достаточно знать, что и почём продать.
В B2B «покупатель» — это организация, с которой у поставщика долгие договорные отношения. И вот тут появляется всё то, чего в рознице просто нет как класса:
- Договорные и персональные цены. У каждого контрагента своя цена: по договору, по соглашению, по объёму, по группе. Это не одна колонка, а матрица «клиент × товар».
- Взаиморасчёты и баланс. Клиент видит, сколько он должен, сколько переплатил, какие счета оплачены. Это данные учёта, а не магазина.
- Кредитный лимит и отсрочка. B2B работает в долг: отгрузили сейчас — оплата через срок. Лимит ограничивает долг, и портал обязан его учитывать.
- Документы. Счета, УПД, накладные, акты сверки — их формирует учётная система, а портал показывает и даёт скачать.
- История и статусы. Не только «заказ оформлен», а весь путь: резерв, сборка, частичная отгрузка, дозаказ, возврат — всё это ведётся в ERP.
Каждый из этих пунктов — отдельный поток данных со своим владельцем, частотой обновления и требованиями к актуальности. Каталог можно обновлять раз в час, а баланс перед оформлением заказа клиент хочет видеть здесь и сейчас. Остаток по складу должен быть свежим, иначе клиент закажет то, чего нет. Цена по договору не должна «плавать» между тем, что показали в каталоге, и тем, что попало в заказ. Именно эта разнородность требований и делает интеграцию B2B-портала с ERP многослойной задачей, а не «настройкой обмена по инструкции».
Есть и вторая сторона сложности — цена ошибки. В рознице неверная цена — это спор на кассе и, в худшем случае, отменённый заказ. В B2B неверная цена по договору, показанный не тот баланс или пропущенный кредитный лимит — это уже про деньги и доверие в долгих отношениях. Поэтому к обмену в B2B предъявляют требования, ближе к банковским: данные должны быть согласованными, обмен — надёжным, а ответственность за каждое число — понятной.
Что такое ERP и чем она отличается: 1С:ERP, УТ, SAP
Прежде чем обсуждать обмен, договоримся о терминах. ERP (Enterprise Resource Planning) — это система управления ресурсами предприятия: она ведёт не только продажи и склад, но и производство, закупки, финансы, взаиморасчёты, бюджетирование, иногда зарплату и кадры. В отличие от «учётной программы магазина», ERP охватывает весь бизнес и является единым источником правды по большинству операций компании.
С точки зрения интеграции B2B-портала важно понимать, что «ERP» — это спектр систем разной тяжести:
| Система | Что это | Обмен с Битриксом |
|---|---|---|
| 1С:Управление торговлей (УТ) | Торговля, склад, взаиморасчёты — без производства | Штатный CommerceML, для B2B расширяют обмен |
| 1С:ERP Управление предприятием | Тяжёлая ERP: производство, финансы, закупки, продажи | CommerceML как база + доработки под сложные данные |
| 1С:Комплексная автоматизация | Промежуточная конфигурация между УТ и ERP | CommerceML + расширения под взаиморасчёты и лимиты |
| SAP, MS Dynamics и прочие | Зарубежные ERP крупного бизнеса | Обмен через их API / шину, на стороне Битрикса — коннектор |
Для систем 1С у Битрикса есть готовый мост — протокол обмена CommerceML, который «из коробки» умеет каталог, цены, заказы и часть служебных данных. Это большое преимущество: базовый обмен не приходится изобретать. Но для B2B «из коробки» покрывает лишь фундамент, а всё сложное — договорные цены, взаиморасчёты, лимиты, документы — либо расширяют поверх CommerceML, либо выносят в отдельный обмен через API. Причём даже внутри линейки 1С конфигурации сильно различаются: УТ и полноценная 1С:ERP по-разному хранят цены и взаиморасчёты, а на реальных внедрениях почти всегда есть доработки конфигурации под конкретный бизнес.
С зарубежными ERP вроде SAP история другая: штатного CommerceML там нет, и обмен строят через их программные интерфейсы или корпоративную интеграционную шину (ESB). На стороне Битрикса при этом обычно всё равно оставляют привычный формат данных, а «переводом» между форматами занимается коннектор или middleware. Логика обмена — какие данные, в какую сторону, кто хозяин — от смены ERP не меняется; меняется только транспорт и формат.
Практический вывод из этого раздела один, но важный: универсального «обмена с ERP» не существует. Есть общие принципы (о них вся статья), но конкретный 1c erp обмен всегда проектируется под конкретную конфигурацию, её доработки и реальные бизнес-процессы. Поэтому проект интеграции начинается не с кода, а с обследования: что за ERP, как в ней устроены цены и взаиморасчёты, какие данные вообще есть, кто их владелец.
Карта данных: что обмениваем между порталом и ERP
Чтобы не утонуть в деталях, полезно сначала увидеть всю картину целиком — карту потоков данных. В B2B-интеграции их обычно пять групп, и у каждой своё направление, частота и владелец.
| Данные | Направление | Частота | Хозяин |
|---|---|---|---|
| Номенклатура, характеристики | ERP → портал | Регулярно (часы/сутки) | ERP |
| Договорные и персональные цены | ERP → портал | Регулярно + по изменению | ERP |
| Остатки по складам | ERP → портал | Часто + по требованию | ERP |
| Заказ (новый) | портал → ERP | По событию (сразу) | Портал |
| Статусы заказа | ERP → портал | По событию / часто | ERP |
| Взаиморасчёты, баланс | ERP → портал | Часто + по требованию | ERP |
| Дебиторка, лимит, отсрочка | ERP → портал | Часто | ERP |
| Документы (счёт, УПД, акт) | ERP → портал | По событию / регулярно | ERP |
Из этой таблицы видна главная закономерность: почти всё течёт из ERP на портал, и лишь новый заказ рождается на портале и уходит в ERP. Портал в B2B — это в основном «витрина» на данные учётной системы: он красиво и удобно показывает то, чем владеет ERP, и добавляет ровно одну вещь от себя — оформленный клиентом заказ. Понимание этой асимметрии сразу упрощает проектирование: не нужно мучиться вопросом «а кто хозяин баланса» — хозяин ERP, портал только отражает.
Вторая закономерность — разная частота и требования к актуальности. Каталог и характеристики меняются редко, их можно грузить пакетом по расписанию. Цены и остатки меняются чаще и критичнее — их обновляют чаще, а перед оформлением заказа остаток и цену иногда перепроверяют в реальном времени. Финансы (баланс, лимит) клиент хочет видеть свежими, поэтому их либо часто синхронизируют, либо запрашивают по требованию. Эта разница в частоте — причина, по которой один протокол обмена на всё не годится: об этом дальше в разделах про способы обмена.
Номенклатура и характеристики
Основа любого каталога — номенклатура: товары, их описания, изображения, единицы измерения, свойства. В B2B каталог обычно сложнее розничного: больше технических характеристик, кратность упаковки и отгрузки, аналоги и замены, привязка к брендам и сериям. Всё это хозяйство ведётся в ERP и приходит на портал регулярным обменом.
Что важно передавать в номенклатурном потоке для B2B:
- Товары и торговые предложения. Карточка товара и его вариации (цвет, размер, фасовка) — как товары с характеристиками. В Битриксе это торговые предложения (SKU).
- Характеристики и свойства. Технические параметры для фильтров и подбора: мощность, размер, материал, совместимость. В B2B по ним часто ищут и заказывают.
- Единицы измерения и кратность. Штуки, упаковки, коробки, палеты; кратность отгрузки. Клиент заказывает не «1 штуку», а «2 палеты по 48».
- Артикулы и коды. Внутренний код номенклатуры, артикул производителя, штрихкод — по ним идёт быстрый заказ и сопоставление.
- Категории и иерархия. Структура каталога, привязка к разделам, бренды и серии для навигации.
Ключевая техническая тонкость номенклатурного обмена — устойчивое сопоставление. У каждого товара должен быть неизменный идентификатор (обычно внешний код из ERP, XML_ID в Битриксе), по которому портал всегда узнаёт «это тот же товар». Если сопоставлять по названию или артикулу, первое же переименование в ERP породит дубли или потерю привязки. Правильный обмен ведёт товары по внешнему коду, а название и остальные поля просто обновляет.
Номенклатура — относительно «спокойный» поток: товары и характеристики меняются нечасто, поэтому такой обмен обычно делают пакетным по расписанию (раз в час или в сутки), а не в реальном времени. Полный перечень товаров может быть большим, поэтому важно поддерживать не только полную выгрузку, но и обмен изменениями (только то, что поменялось) — иначе каждый обмен будет прогонять весь каталог целиком и нагружать обе системы. О производительности объёмных обменов — отдельный раздел ниже.
Договорные и персональные цены по контрагенту
Вот где B2B резко расходится с розницей. В магазине цена — это, как правило, одна колонка: столько стоит товар. В B2B цена зависит от того, кто спрашивает: у одного контрагента цена по договору, у другого — по объёмному соглашению, у третьего — базовая со скидкой за группу. Одна и та же позиция для разных клиентов стоит по-разному, и портал обязан показать каждому именно его цену.
Откуда берутся персональные цены и как они попадают на портал:
| Тип цены | Как устроена | Как обменивается |
|---|---|---|
| Типы (колонки) цен | Опт, крупный опт, дилер — базовые уровни | Несколько типов цен через обмен, привязка к группам |
| Цена по соглашению | Договорённость с контрагентом на набор позиций | Матрица «соглашение × товар» из ERP |
| Персональная скидка | Индивидуальный процент или наценка | Правило скидки по контрагенту |
| Цена по объёму | Зависит от количества в заказе | Ценовые шкалы (диапазоны количества) |
Здесь принципиально важное правило: цену считает ERP, а не портал. Соблазн «получить базовую цену и накрутить скидку на сайте» почти всегда приводит к расхождениям: в ERP своя логика соглашений, округлений, приоритетов скидок, и повторить её на портале один в один сложно и хрупко. Правильный подход — ERP отдаёт уже рассчитанную цену по контрагенту (или набор типов цен и правил, из которых портал выбирает нужный по группе клиента), а портал её просто показывает. Тогда цена в каталоге, в корзине и в заказе гарантированно совпадает с той, что попадёт в отгрузочные документы.
Технически персональные цены реализуют по-разному в зависимости от объёма. Если типов цен немного (несколько уровней опта), их передают как обычные ценовые колонки Битрикса и показывают по группе пользователя. Если у контрагентов реально индивидуальные матрицы цен на тысячи позиций, хранить их «в лоб» для каждого клиента накладно — тогда актуальную персональную цену запрашивают из ERP по требованию через API в момент показа или оформления. Выбор зависит от масштаба: разграничение цен по группам мы подробно разбираем в отдельном материале, а здесь важно, что владельцем цены всегда остаётся ERP.
Остатки по складам
Остаток — данные, которые устаревают быстрее всего. В B2B он ещё и многомерный: товар лежит на нескольких складах, и клиент часто выбирает, откуда отгружать — из ближнего, где меньше, или из дальнего, где всё есть. Поэтому обмен остатками в B2B — это не одно число «в наличии», а разбивка по складам, а иногда ещё и по статусу (свободно, в резерве, ожидается).
Что передаёт обмен остатками:
- Остаток по складам. Сколько товара на каждом складе, из которого возможна отгрузка данному контрагенту.
- Свободный и зарезервированный. Часть остатка может быть в резерве под другие заказы; клиенту важен именно свободный.
- Ожидаемые поступления. Когда и сколько приедет — чтобы клиент мог оформить заказ «под приход».
- Признак доступности. Для крупных каталогов иногда показывают не точное число, а градацию: «много», «мало», «под заказ».
Главная проблема остатков — гонка за актуальностью. Если обмен идёт раз в час, за этот час товар могли распродать, и клиент оформит заказ на то, чего уже нет. В B2B это болезненно: заказ крупный, клиент рассчитывал на объём. Поэтому остатки обновляют чаще каталога, а для критичных сценариев (оформление крупного заказа, дефицитная позиция) остаток перепроверяют в реальном времени запросом в ERP прямо перед подтверждением. Это классический пример, когда пакетного обмена мало и нужен API.
Вторая тонкость — что делать с резервом. Когда клиент оформляет заказ, товар желательно зарезервировать, чтобы его не «увели» параллельные заказы. Но резерв — это операция в ERP, и здесь встаёт вопрос: резервирует портал (оптимистично, до подтверждения в ERP) или резерв ставится только после приёма заказа учётной системой. Однозначного ответа нет, это зависит от бизнеса и от того, насколько дефицитен товар; но решение нужно принять осознанно, иначе появятся либо «фантомные» резервы на портале, либо перепроданные позиции.
Заказы и статусы исполнения
Заказ — единственный поток, который течёт от портала в ERP, и потому особенный. Клиент собирает корзину, оформляет заказ, тот уходит в учётную систему, и дальше начинается его жизнь в ERP: резерв, сборка, отгрузка, выставление документов. Обратно на портал возвращается движение по статусам — чтобы клиент видел, где его заказ.
Жизненный цикл заказа в интеграции выглядит так:
- Оформление на портале. Клиент собирает корзину по своим ценам, проверяется остаток и лимит, заказ фиксируется. В B2B перед этим часто идёт согласование внутри компании-покупателя.
- Передача в ERP. Заказ уходит в учётную систему — сразу по событию или ближайшим обменом. Ему присваивается номер в ERP, портал сохраняет связь «заказ портала ↔ заказ ERP».
- Обработка в ERP. Менеджер и склад работают с заказом в учётной системе: резервируют, комплектуют, отгружают. Портал в это не вмешивается.
- Возврат статусов. Каждая смена стадии (принят, в сборке, отгружен, закрыт) возвращается на портал, и клиент видит актуальное состояние.
- Документы и закрытие. По факту отгрузки в ERP формируются документы, которые тоже приходят на портал и привязываются к заказу.
Ключевой момент — что считать хозяином заказа на каждом этапе. До передачи в ERP хозяин заказа портал: клиент может править корзину, отменить, согласовать. После передачи хозяином становится ERP: там заказ обрабатывают, и портал уже не должен «молча» его менять — иначе состав на сайте и в учёте разойдётся. Если клиенту нужно изменить переданный заказ, это отдельный сценарий (запрос на изменение, который обрабатывает менеджер в ERP), а не тихая правка на портале.
В B2B заказ почти всегда проходит внутреннее согласование до отправки в ERP — черновик, заявка, утверждение по сумме и лимиту. В ERP заказ должен уходить уже утверждённым, чтобы там не копились «мусорные» неподтверждённые заявки. Механику согласования, статусов и ролей мы подробно разбираем в статье про согласование и статусы заказов в B2B-портале — здесь же важно, что в ERP передаётся результат согласования, а не каждый черновик.
Взаиморасчёты и баланс контрагента
Переходим к самой чувствительной части — деньгам. Обмен взаиморасчётами отвечает на вопрос, который в рознице не возникает вовсе: сколько этот контрагент нам должен (или мы ему), какие счета оплачены, каков текущий баланс. В B2B клиент хочет видеть это в личном кабинете, а поставщик — контролировать перед отгрузкой.
Что входит в обмен взаиморасчётами:
| Данные | Что показывает | Откуда |
|---|---|---|
| Сальдо (баланс) | Текущее состояние: должен клиент или переплатил | ERP, готовое число |
| Дебиторская задолженность | Сколько отгружено, но не оплачено | ERP |
| Оплаченные и неоплаченные счета | Статус оплаты по каждому счёту | ERP |
| История платежей | Когда и сколько оплачено | ERP |
| Акт сверки | Итоговая сверка расчётов за период | ERP (документ) |
Железное правило взаиморасчётов: баланс считает ERP, портал его только показывает. Портал ни при каких условиях не должен «выводить долг», складывая заказы или оплаты — у учёта своя логика зачётов авансов, частичных оплат, возвратов, курсовых разниц. Любая попытка посчитать сальдо на сайте гарантированно разойдётся с бухгалтерией, а расхождение в деньгах мгновенно подрывает доверие клиента к порталу. Портал берёт готовое сальдо из ERP и отображает — точка.
Из-за важности и чувствительности взаиморасчёты обычно выделяют в отдельный поток обмена, более частый, чем каталог. Клиенту важно видеть свежий баланс именно перед заказом, поэтому здесь особенно уместен запрос по требованию через API: открыл кабинет или корзину — портал спросил у ERP актуальное сальдо. При этом полную выверку (все счета, вся история) синхронизируют по расписанию, а «горячее» число баланса — по требованию. Такое разделение даёт и актуальность, и разумную нагрузку.
Дебиторка, кредитные лимиты и отсрочки
Взаиморасчёты дают статичную картину «сколько должен», а лимиты и отсрочки — динамическую: «сколько ещё можно взять в долг и до какого срока платить». В B2B это встроено прямо в процесс заказа, поэтому соответствующие данные обязаны быть на портале и обновляться из ERP.
Из чего складывается «кредитный» слой обмена:
- Кредитный лимит. Потолок задолженности, который поставщик готов держать за контрагентом. Задаётся в ERP по договору.
- Остаток лимита. Сколько ещё можно отгрузить в долг с учётом текущей задолженности. Это лимит минус дебиторка.
- Отсрочка платежа. Срок, в течение которого нужно оплатить после отгрузки. По нему считается, есть ли просрочка.
- Просроченная задолженность. Долг, срок оплаты которого прошёл, — более серьёзный сигнал, чем просто большой баланс в пределах срока.
В момент оформления заказа портал сверяет новую сумму с остатком лимита из ERP и применяет правило поставщика: в пределах лимита — заказ идёт обычным путём; на грани — предупреждение; сверх лимита — блокировка, требование предоплаты или отправка на согласование менеджеру. То же с просрочкой: есть просроченный долг — новые заказы могут ограничиваться до его погашения. Но и лимит, и просрочка — это числа из ERP, а не расчёт портала; сайт лишь применяет к ним заранее заданное правило.
Важно понимать разделение ролей: значения лимита и долга — из ERP, правило реакции — политика поставщика, портал — исполнитель. Финансовая служба решает, что делать при превышении лимита, ERP хранит и считает цифры, а портал реализует выбранное поведение. Такое разграничение защищает от типичной ошибки, когда портал «сам решает» блокировать клиента по посчитанному на сайте долгу и ошибается, потому что не знает про свежий платёж, ещё не отражённый в его данных. Поэтому лимит и баланс перед критичным заказом лучше перепроверять запросом в реальном времени.
Документы: счета, УПД, акты сверки
Отдельный поток обмена — документы. В B2B клиент работает с бумагами: ему нужен счёт на оплату, отгрузочные документы (УПД, накладная), акт сверки. Все они формируются в ERP по факту операций, а портал даёт к ним доступ в личном кабинете — показать и скачать.
Какие документы обычно обмениваются и как:
| Документ | Когда возникает | Как обменивается |
|---|---|---|
| Счёт на оплату | По заказу, до отгрузки | Формируется в ERP или предварительно на портале |
| УПД / накладная | По факту отгрузки | Файл из ERP, привязка к заказу |
| Акт сверки | По запросу / за период | Формируется в ERP, отдаётся файлом |
| Договор, спецификация | При оформлении отношений | Прикрепляется к контрагенту |
Здесь есть развилка «где формировать документ». Предварительный счёт по составу заказа портал иногда генерирует сам — данные все есть, а клиенту удобно получить счёт сразу. Но бухгалтерские документы (УПД, накладные, финальные счета, акты) формирует ERP и передаёт на портал как файлы, привязанные к заказу или контрагенту. Рисовать учётные документы на сайте в обход ERP — плохая идея: они разойдутся с учётом и не будут иметь юридической силы. Портал — витрина документов, а не их источник.
Технически документы передают либо как файлы (PDF), либо как структурированные данные, из которых портал строит отображение. Файловый вариант проще и надёжнее для юридически значимых документов: что сформировала ERP, то клиент и видит, без пересборки. Отдельно продумывают изоляцию: документы одного контрагента не должны быть доступны другому — доступ проверяется на бэкенде по привязке пользователя к контрагенту, а не скрытием ссылок. Это и вопрос корректности, и вопрос безопасности, о которой ниже.
Мастер-система: кто чему хозяин
Мы уже много раз говорили «хозяин ERP», «хозяин портал» — пора собрать это в систему. Мастер-система (source of truth) — это сторона, чьё значение данных принимается за истину. Для каждого типа данных должен быть ровно один хозяин; остальные системы это значение отражают, но не правят. Нарушение этого принципа — источник почти всех «загадочных» багов интеграции, когда данные то появляются, то пропадают: это две системы перетирают изменения друг друга.
Типовое разграничение ответственности для B2B-портала и ERP:
| Данные | Хозяин | Кто отражает |
|---|---|---|
| Номенклатура, характеристики | ERP | Портал показывает |
| Цены по контрагенту | ERP | Портал показывает |
| Остатки, резервы | ERP | Портал показывает |
| Взаиморасчёты, лимит, документы | ERP | Портал показывает |
| Новый заказ (состав, факт оформления) | Портал | ERP принимает |
| Учётные атрибуты пользователя (логин, права) | Портал | — |
| Контрагент, договор | ERP | Портал сопоставляет пользователя |
Из этой таблицы виден простой навигационный принцип: всё, что связано с деньгами, товаром и учётом — хозяин ERP; всё, что связано с поведением пользователя на сайте — хозяин портал. Заказ рождается на портале (клиент его собрал и оформил) и там он хозяин до передачи; после приёма в ERP хозяином исполнения становится учётная система. Пользователь и его права — на портале, но привязка этого пользователя к контрагенту и договору — из ERP.
Особенно коварны «пограничные» данные, которые хочется вести с обеих сторон. Классика — статус заказа: соблазн менять его и на портале, и в ERP. Правильно так: пока заказ на согласовании — статусами владеет портал; после передачи в работу — ERP, а портал только отражает возвращённые статусы. Ещё пример — резерв: он должен принадлежать той системе, которая реально управляет складом, то есть ERP. Каждую такую пограничную сущность нужно явно «прописать» одному хозяину на каждом этапе, иначе рассинхрон неизбежен.
Способ обмена: CommerceML
Переходим к тому, как технически течут данные. Первый и базовый способ для систем 1С — протокол CommerceML. Это штатный формат обмена Битрикса с 1С: XML-пакеты с товарами, ценами, остатками и заказами, которые системы передают друг другу по расписанию. Для розницы этого хватает почти полностью, для B2B — это надёжный фундамент, поверх которого достраивают остальное.
Что хорошо ложится на CommerceML:
- Каталог и характеристики. Товары, свойства, изображения, единицы измерения — классический пакетный обмен.
- Цены и типы цен. Несколько ценовых колонок передаются штатно; для B2B их привязывают к группам клиентов.
- Остатки. Разбивка по складам передаётся в пакете остатков.
- Заказы. Оформленный заказ уходит в 1С, обратно приходят статусы — тоже штатный механизм.
Сильные стороны CommerceML — зрелость и «коробочность»: не нужно изобретать формат, много что работает из готовых компонентов, обмен переживает обновления платформы. Слабые стороны — это пакетный обмен по расписанию: он не про реальное время. Между сессиями обмена данные устаревают; тяжёлый пакет каталога грузится долго; при большом объёме важно грузить изменения, а не всё целиком, и следить, чтобы пакет не «оборвался» на полпути, оставив данные наполовину обновлёнными.
Для B2B ключевое ограничение CommerceML в том, что он не покрывает сложные данные: договорные матрицы цен на тысячи позиций, оперативный баланс, лимиты, произвольные документы. Часть этого можно уместить в расширенные свойства пакета, но многое удобнее вынести в отдельный обмен через API. Поэтому в зрелых B2B-интеграциях CommerceML отвечает за тяжёлый регулярный поток (каталог, базовые цены, остатки, заказы, документы-файлы), а актуальность и события берут на себя другие способы. Общие принципы штатного обмена с 1С мы разбираем в статье про интеграцию интернет-магазина с 1С.
Способ обмена: REST API в реальном времени
Там, где пакетного обмена мало и нужна свежесть «здесь и сейчас», подключают второй способ — обмен через API (REST). Идея простая: вместо того чтобы ждать следующего пакета, портал в нужный момент спрашивает у ERP актуальное значение напрямую — или ERP по событию дёргает портал.
Где API незаменим в B2B:
- Актуальный остаток перед заказом. Клиент оформляет крупный заказ — портал перепроверяет остаток в ERP, чтобы не продать то, чего нет.
- Свежий баланс и лимит. Открыл кабинет или корзину — портал запросил актуальное сальдо и остаток лимита, а не показал вчерашнее.
- Персональная цена по требованию. Если матрицы цен огромны, актуальную цену по контрагенту запрашивают в момент показа.
- Статус конкретного заказа. Клиент открыл заказ — портал уточнил его текущую стадию в ERP.
Сильная сторона API — актуальность по требованию: данные берутся ровно тогда, когда нужны, и всегда свежие. Слабая — зависимость от доступности ERP в момент запроса и нагрузка: если на каждый показ страницы дёргать ERP, учётная система может не выдержать. Поэтому API применяют точечно — для критичных к свежести вещей (остаток и баланс перед заказом), а не для всего подряд. Массовые данные (весь каталог) через синхронные запросы не гоняют — для этого есть пакет.
Важный нюанс — что делать, если ERP не ответила. Синхронный запрос в реальном времени может завершиться таймаутом: учётная система перегружена или на обслуживании. Портал не должен «падать» из-за этого: нужен запасной сценарий — показать последнее известное значение с пометкой «данные от такого-то времени», а не пустой экран или ошибку. Проектирование этих деградаций отличает надёжную интеграцию от хрупкой. Подробно про построение API-обмена, таймауты и устойчивость — в материале про API, очереди и надёжность интеграций на Битрикс.
Способ обмена: очереди и события
Третий способ решает задачу, с которой плохо справляются и пакет, и синхронный API — надёжную асинхронную доставку событий. Событие — это факт: «заказ оформлен», «статус изменился», «лимит обновился». Такие факты нельзя терять, но и обрабатывать их синхронно (заставляя пользователя ждать ответа ERP) не хочется. Решение — очередь сообщений (брокер).
Как работает обмен через очередь:
- Событие кладётся в очередь. Портал оформил заказ — вместо прямого вызова ERP он публикует сообщение «новый заказ» в очередь и сразу отвечает пользователю «принято».
- Обработчик забирает сообщение. Отдельный процесс (воркер) берёт сообщение из очереди и пытается передать заказ в ERP.
- Успех — подтверждение. ERP приняла заказ — сообщение помечается обработанным и уходит из очереди.
- Ошибка — ретрай. ERP недоступна — сообщение не теряется, а возвращается в очередь и повторяется позже с нарастающей задержкой.
- Разбор «застрявших». Если после нескольких попыток не вышло — сообщение уходит в отдельную очередь для ручного разбора, а не пропадает молча.
Главное преимущество очереди — развязка систем во времени. Портал не зависит от того, работает ли ERP прямо сейчас: он положил событие и продолжил работу, а доставка произойдёт, как только ERP будет доступна. Это решает больной вопрос B2B — «что делать, если заказ оформлен, а обмен с ERP временно недоступен». Ответ: заказ не теряется, он ждёт в очереди и уйдёт, когда связь восстановится. Клиент видит честный статус «передаётся в учёт», а не ошибку.
Очередь — это ещё и фундамент надёжности через ретраи и идемпотентность (об этом отдельный раздел). Для B2B её обычно применяют к событиям, которые нельзя терять: передача заказа, смена статуса, обновление лимита после платежа. Пакетный каталог через очередь гонять не нужно, а вот критичные бизнес-события — самое то. Комбинация всех трёх способов и даёт зрелую интеграцию.
Комбинированная архитектура обмена
Ни один способ не покрывает всё, и это нормально. Зрелая интеграция B2B-портала с ERP — это комбинация трёх способов, где каждый делает то, что умеет лучше всего. Соберём картину воедино.
| Способ | Для чего | Характер | Пример данных |
|---|---|---|---|
| CommerceML | Тяжёлый регулярный обмен | Пакет по расписанию | Каталог, базовые цены, остатки, документы-файлы |
| REST API | Актуальность по требованию | Синхронный запрос | Остаток и баланс перед заказом, статус, цена |
| Очередь | Надёжная доставка событий | Асинхронно с ретраями | Новый заказ, смена статуса, обновление лимита |
Логика распределения простая. Объём — в пакет: то, чего много и что меняется предсказуемо, грузим CommerceML по расписанию. Свежесть — в API: то, что должно быть актуальным в конкретный момент, спрашиваем напрямую. Надёжность — в очередь: то, что нельзя потерять и что происходит по событию, проводим через брокер с гарантией доставки. Одни и те же данные могут участвовать в разных способах: остаток грузится пакетом регулярно, но перед крупным заказом перепроверяется через API.
Такое разделение — не усложнение ради усложнения, а способ одновременно выдержать три противоречивых требования: объём, актуальность и надёжность. Пакет дёшев для больших данных, но не свежий; API свежий, но дорог на объёме и хрупок при сбоях; очередь надёжна, но избыточна для массовой загрузки. Комбинируя их по назначению, вы получаете обмен, который и не задыхается на объёмах, и показывает актуальные цифры, и не теряет заказы. С чего начинать — с CommerceML как фундамента, а API и очередь добавлять там, где базовый обмен упирается в свои ограничения.
Объёмы данных и производительность
B2B-каталоги бывают огромными: десятки и сотни тысяч позиций, у каждой — характеристики, несколько типов цен, остатки по нескольким складам. Умножьте это на количество контрагентов с персональными ценами — и объём данных становится серьёзным инженерным вызовом. Производительность обмена — не «приятное дополнение», а условие того, что интеграция вообще будет работать.
Что нагружает обмен и как с этим бороться:
- Полная выгрузка каждый раз. Если гнать весь каталог при каждом обмене, обе системы задыхаются. Лечение — обмен изменениями: передавать только то, что поменялось с прошлого раза.
- Тяжёлый пакет и таймауты. Огромный XML может не догрузиться за отведённое время. Лечение — разбивка на порции (пакетами по N товаров), пошаговая загрузка с сохранением прогресса.
- Матрицы персональных цен. Хранить индивидуальную цену на каждую позицию для каждого клиента — комбинаторный взрыв. Лечение — типы цен по группам плюс запрос индивидуальной цены по требованию.
- Частые остатки на большом каталоге. Обновлять все остатки часто — дорого. Лечение — обменивать только изменившиеся остатки и приоритизировать ходовые позиции.
Отдельная тема — кэш и его инвалидация. Чтобы портал был быстрым, каталог и цены кэшируют. Но после обмена кэш обязан обновиться, иначе клиент увидит вчерашние цены и остатки, хотя обмен уже прошёл — классический источник рассинхрона «в базе новое, на экране старое». Правильно — по завершении обмена точечно сбрасывать кэш затронутых разделов и товаров, а не ждать, пока он протухнет сам. И наоборот: персональные данные (баланс, свои заказы) нельзя кэшировать «одинаково для всех», иначе один клиент увидит данные другого.
Наконец, важно развести обмен по времени и приоритету. Тяжёлый полный каталог — ночью, когда нагрузка низкая. Остатки и цены — чаще, небольшими порциями. Баланс и статусы критичных заказов — по требованию. Разделение потоков по частоте и «весу» — то, что позволяет большому B2B-порталу оставаться быстрым и актуальным одновременно. Пытаться решить всё одним «большим ночным обменом» на серьёзных объёмах не выйдет: либо данные устаревают, либо система не справляется.
Надёжность: идемпотентность и ретраи
Обмен между двумя системами по сети обязательно будет иногда сбоить: сеть моргнула, ERP на обслуживании, таймаут, дубль сообщения. Вопрос не «случится ли сбой», а «что будет, когда он случится». Надёжная интеграция спроектирована так, что сбои не приводят ни к потере данных, ни к дублям. Держится это на нескольких принципах.
Идемпотентность. Каждое сообщение и каждый заказ имеют устойчивый идентификатор, и повторная обработка того же сообщения не создаёт дубль и ничего не портит. Это критично: при сбоях сообщения часто доставляются повторно (отправитель не получил подтверждения и шлёт ещё раз). Если обработчик не идемпотентен, повтор породит второй такой же заказ в ERP. Правильно — при приёме проверять, не обработан ли уже этот идентификатор, и если да — просто подтвердить, не создавая дубль.
Ретраи с очередью. Если ERP недоступна, событие не теряется и не «падает с ошибкой пользователю», а остаётся в очереди и повторяется с нарастающей задержкой (backoff), пока не будет принято. После нескольких безуспешных попыток сообщение уходит в отдельную очередь «на разбор», чтобы человек посмотрел, что не так, — но и там оно не пропадает. Это превращает временные сбои в невидимую для пользователя задержку вместо потерянных заказов.
Наблюдаемость. По каждому обмену видно, что ушло, что принято, где застряло и почему. Есть журнал сообщений, счётчики успешных и неуспешных обменов, оповещение о «зависших» очередях. Без наблюдаемости сбои обнаруживаются постфактум по жалобе клиента «где мой заказ», а с ней — заранее, по мониторингу. Это тот случай, когда вложение в диагностику окупается первым же инцидентом.
Эти принципы универсальны для любой сложной интеграции, не только с ERP, и мы разбираем их детально в отдельном материале про API, очереди и надёжность интеграций на Битрикс. Для B2B они особенно важны, потому что цена потерянного заказа или задвоенной отгрузки здесь высока: это деньги, документы и отношения с контрагентом.
Безопасность обмена
Обмен с ERP везёт самое чувствительное: цены, взаиморасчёты, лимиты, документы, персональные данные контрагентов. Утечка или подмена этих данных — не просто баг, а риск для бизнеса и репутации. Поэтому безопасность обмена продумывают наравне с его логикой.
На что смотреть в первую очередь:
- Защищённый канал. Весь обмен — только по HTTPS/TLS. Ни цены, ни баланс, ни документы не должны ходить в открытом виде.
- Аутентификация систем. ERP и портал подтверждают, что общаются именно друг с другом: ключи, токены, сервисные учётные записи с ограниченными правами.
- Минимум прав. Учётная запись обмена имеет ровно те права, что нужны для обмена, и не больше — не полный админ «на всякий случай».
- Изоляция данных контрагентов. На портале клиент видит только свои цены, баланс, заказы и документы; доступ проверяется на бэкенде по привязке к контрагенту.
- Ограничение доступа к API обмена. Точки обмена закрыты от публичного доступа: по IP, по токену, через сервисный контур, а не открытый URL.
Особенно важна изоляция на уровне портала. Даже при идеально защищённом канале обмена ошибка в правах на сайте сведёт всё на нет: если один авторизованный клиент может подбором ссылки открыть баланс или документы другого контрагента — это утечка. Поэтому каждый запрос персональных данных фильтруется по привязке пользователя к контрагенту на сервере, а не скрытием элементов в интерфейсе. Скрытая, но вызываемая напрямую точка — это не защита.
Отдельно — журналирование доступа. По чувствительным данным (кто смотрел баланс, кто скачивал документы, какие цены запрашивались) полезно вести журнал: и для разбора инцидентов, и для соответствия требованиям к обработке данных. В B2B, где за каждым клиентом стоит юрлицо с договором, аккуратность с их данными — часть деловой репутации поставщика, а не только техническая гигиена.
Реализация на D7
Немного о том, на чём всё это собирают в 1С-Битрикс. Современный код интеграции пишут на ядре D7 — актуальном API платформы (пространства имён, ORM, сервисы, события). Старый процедурный код (прямые запросы, глобальные функции) для сложного обмена не годится: его тяжело тестировать, поддерживать и масштабировать.
Из чего складывается реализация обмена на D7:
- Свой модуль интеграции. Логика обмена живёт в отдельном модуле, а не в файлах шаблона — так её можно версионировать, переносить и не терять при обновлениях.
- ORM и сущности. Данные обмена (соответствия, журнал сообщений, статусы) хранят в своих таблицах через ORM D7, а не в разрозненных опциях.
- Обработчики событий. На оформление заказа, смену статуса вешают обработчики, которые публикуют события в очередь, — без правки ядра.
- Контроллеры и сервисы. Точки API обмена — на контроллерах с проверкой прав; бизнес-логика вынесена в сервисы, а не размазана по компонентам.
- Агенты и очереди. Фоновая обработка (разбор очереди, ретраи, пакетная загрузка) — через агенты, cron-воркеры или брокер, а не в момент запроса пользователя.
Незыблемое правило кастомизации Битрикса действует и здесь: не править ядро и штатные компоненты напрямую. Обмен строят через события, наследование и собственные модули. Иначе первое же обновление платформы затрёт доработки, и интеграция сломается в самый неподходящий момент. Аккуратная архитектура на D7 — то, что отличает поддерживаемый обмен, переживающий обновления, от «однажды написанного и боящегося тронуть».
Ещё один практический момент — тестируемость и стенд. Обмен с ERP нельзя отлаживать сразу на бою: нужен тестовый контур, где портал общается с тестовой базой ERP, и где можно прогнать сценарии сбоев (ERP недоступна, дубль сообщения, оборванный пакет) до того, как они случатся в проде. Вложение в стенд и в наблюдаемость окупается уже на этапе внедрения, а не когда-нибудь потом.
Поэтапное внедрение интеграции
Попытка сделать «всю интеграцию сразу» — большими объёмами, всеми потоками, со всеми сложными данными — почти всегда затягивается и рискует. Правильный путь — поэтапно, от фундамента к сложному, с рабочим результатом на каждом шаге.
Разумная последовательность внедрения:
- Обследование. Что за ERP, как устроены цены и взаиморасчёты, какие данные есть, кто их владелец. Без этого проектировать нечего.
- Базовый обмен каталогом. Номенклатура, характеристики, базовые цены, остатки через CommerceML. Портал наполняется актуальным каталогом.
- Заказы в ERP. Оформленный заказ уходит в учёт, обратно приходят статусы. Замыкается основной торговый цикл.
- Персональные цены. Договорные цены по контрагенту — типы цен по группам или запрос по требованию. Клиент видит свою цену.
- Финансы. Баланс, дебиторка, лимит, отсрочка — обмен взаиморасчётами. Личный кабинет показывает деньги.
- Документы. Счета, УПД, акты сверки из ERP привязываются к заказам и контрагенту.
- Реальное время и надёжность. API для актуальных остатка и баланса, очередь для событий с ретраями и идемпотентностью.
Смысл этапности в том, что после каждого шага портал уже приносит пользу, а не «ждёт, пока доделают всё». Сначала клиент получает актуальный каталог и может оформить заказ — это уже ценно. Потом добавляются его цены, потом финансы, потом документы, потом — реальное время и надёжность под нагрузкой. Такой порядок ещё и снижает риск: каждый следующий слой встаёт на проверенный предыдущий, а не на зыбкую конструкцию из всего сразу.
Часто оказывается, что часть задуманного на старте «сложного» в реальности не нужна, а всплывают потребности, о которых не думали. Это выясняется только в работе, поэтому гибкость и обратная связь на каждом этапе важнее, чем идеальный план на год вперёд. Интеграция — живой процесс, который дозревает вместе с тем, как бизнес обкатывает портал.
Частые ошибки интеграции с ERP
Эти промахи повторяются в B2B-проектах чаще всего — зная их заранее, вы сэкономите недели отладки и нервы:
- Считают цены, баланс и лимит на сайте. Портал пытается повторить логику ERP вместо того, чтобы взять готовые числа, — и они расходятся с учётом. Хозяин денег и цен — ERP.
- Нет единого владельца данных. Одни и те же поля правят и портал, и ERP, они перетирают друг друга, данные «мигают». Каждому полю — один хозяин на каждом этапе.
- Всё на одном пакетном обмене. Каталог, цены, остатки, баланс — раз в сутки одним пакетом. Остатки и баланс устаревают, клиент заказывает то, чего нет. Нужны API и разделение потоков.
- Обмен не идемпотентен. Повторная доставка сообщения создаёт дубль заказа в ERP. Каждый заказ и сообщение — с устойчивым идентификатором и проверкой на повтор.
- Нет ретраев и очереди. ERP на пять минут недоступна — заказы теряются с ошибкой. Нужна очередь: событие ждёт и уходит, когда связь восстановится.
- Сопоставление по названию, а не по коду. Товары и контрагентов связывают по имени — первое переименование в ERP плодит дубли. Ведут по неизменному внешнему коду.
- Кэш не инвалидируется после обмена. В базе новые цены, на экране старые. Обмен обязан сбрасывать кэш затронутых данных.
- Полная выгрузка каждый раз. Весь каталог гоняют при каждом обмене — системы задыхаются. Нужен обмен изменениями и порционность.
- Черновики и неутверждённые заявки уходят в ERP. В учёте копятся «мусорные» заказы. В ERP передаётся только согласованный заказ.
- Нет запасного сценария при недоступности ERP. Синхронный запрос упал — портал показывает ошибку вместо последнего известного значения. Деградации проектируют заранее.
- Слабая изоляция контрагентов. Клиент подбором ссылки видит чужой баланс и документы. Доступ проверяется на бэкенде по привязке к контрагенту.
- Интеграцию делают «всю сразу». Все потоки и сложные данные разом — запуск затягивается, риск растёт. Внедряют поэтапно, от фундамента к сложному.
Чек-лист интеграции
Короткий список для приёмки интеграции B2B-портала с ERP — по нему удобно проверить, что обмен закрыт и не развалится под нагрузкой:
- Обследование проведено. Известно, что за ERP, как устроены цены и взаиморасчёты, какие данные есть и кто их владелец.
- Мастер-система определена. Для каждого потока данных назван один хозяин на каждом этапе; пограничные сущности (статус, резерв) прописаны явно.
- Каталог и характеристики обмениваются. Товары ведутся по неизменному внешнему коду, поддержан обмен изменениями, а не только полная выгрузка.
- Персональные цены из ERP. Цену считает ERP, портал показывает; выбран способ (типы цен по группам или запрос по требованию) под объём.
- Остатки актуальны. Обмен остатками чаще каталога; перед критичным заказом остаток перепроверяется через API; поведение резерва определено.
- Заказы и статусы состыкованы. В ERP уходит только согласованный заказ; статусы возвращаются; связь «заказ портала ↔ заказ ERP» хранится.
- Взаиморасчёты из ERP. Баланс, дебиторка, лимит, отсрочка приходят как готовые числа; портал ничего не пересчитывает; свежий баланс доступен по требованию.
- Документы привязаны. Счета, УПД, акты из ERP доступны в кабинете с изоляцией по контрагенту.
- Способы обмена скомбинированы. CommerceML для объёмов, API для актуальности, очередь для событий — каждый по назначению.
- Надёжность обеспечена. Идемпотентность, ретраи с очередью, разбор «застрявших» сообщений, наблюдаемость и мониторинг.
- Производительность выдержана. Обмен изменениями, порционность, разведение потоков по частоте, корректная инвалидация кэша.
- Безопасность закрыта. TLS, аутентификация систем, минимум прав, изоляция контрагентов на бэкенде, ограничение доступа к точкам обмена.
Вывод
Интеграция B2B-портала на 1С-Битрикс с ERP — это не «выгрузка каталога и приём заказов», а обмен несколькими связанными потоками сложных данных: номенклатурой и характеристиками, договорными ценами по контрагенту, остатками по складам, заказами и статусами, взаиморасчётами, лимитами и документами. Именно эти «лишние» по сравнению с розницей потоки — цены по соглашениям, баланс, дебиторка, отсрочка — и делают B2B-интеграцию многослойной задачей, где к обмену предъявляют требования, близкие к финансовым: согласованность, надёжность, понятная ответственность за каждое число.
Два принципа определяют, будет интеграция работать или мучить. Первый — единый владелец данных: ERP хозяин цен, остатков, взаиморасчётов и документов, портал хозяин нового заказа и пользователя, и никто не перетирает чужие данные и не пересчитывает деньги на своей стороне. Второй — правильный способ под каждую задачу: CommerceML для тяжёлых объёмов, REST API для актуальности по требованию, очередь с идемпотентностью и ретраями для надёжной доставки событий. Соблюдая их, разделяя потоки по частоте и внедряя поэтапно от фундамента к сложному, вы получаете обмен, которому можно доверять: цены и остатки не расходятся, баланс актуален, заказы не теряются, а документы совпадают с учётом. А это и есть основа доверия и клиента, и поставщика к B2B-порталу.