Разработка B2B-портала на 1С-Битрикс
Стандартный интернет-магазин на Битриксе не подходит для оптовых продаж: там одна цена для всех, публичный каталог, отсутствие лимитов кредита и алгоритма согласования заказов. Когда менеджер по продажам тратит 40 минут на оформление каждого заказа вручную через CRM, а дилер звонит, чтобы узнать остатки — это симптомы отсутствия B2B-портала, а не проблема персонала.
Чем B2B-портал принципиально отличается от публичного магазина
Архитектурно — другая логика авторизации, другая модель ценообразования и другой сценарий заказа.
Авторизация и группы пользователей. В bitrix:sale пользователь привязан к одной группе. В B2B нужна иерархия: компания → контактное лицо → роль (закупщик, бухгалтер, директор). Штатные группы пользователей Битрикс для этого не подходят — они плоские. Реализуется через кастомный модуль с таблицей связей company_user и промежуточной сущностью через D7 ORM (Bitrix\Main\ORM\Data\DataManager). Права на действия (создать заказ, видеть задолженность, менять адрес доставки) задаются через битовую маску в Highload-блоке ролей.
Типы цен. Модуль catalog поддерживает несколько типов цен: CATALOG_GROUP_ID в таблице b_catalog_price. Для B2B это обязательная механика — каждой группе пользователей назначается свой тип цены. Но индивидуальные контрактные цены сложнее: нужна отдельная таблица договорных позиций с приоритетом выше базового типа. Реализуется через обработчик события OnSaleOrderBeforeSaved или через кастомный провайдер цен, имплементирующий Bitrix\Catalog\v2\Price\BasePriceProvider.
Каталог с остатками в реальном времени. B2B-покупатели заказывают крупными партиями и проверяют доступность до оформления. Данные об остатках b_catalog_store_product обновляются при синхронизации с 1С через CommerceML 2.10. Если синхронизация идёт раз в час — клиент видит устаревшие данные. Решение: REST API 1С + обработчик изменений на стороне Битрикс, обновляющий остатки инкрементально через CCatalogStoreProduct::Update().
Ключевые модули и компоненты
Модуль sale — основа для корзины и заказов. В B2B дорабатывается: добавляем статусы (На согласовании, Согласован, Отклонён), настраиваем бизнес-процессы через модуль bizproc для маршрутизации заказов по ответственным.
Модуль catalog — ценообразование, торговые предложения (SKU), управление складами. Для B2B обязательно задействуется CatalogGroup (типы цен) и DiscountCoupon для разовых акций.
Модуль crm (если выбрана схема с Битрикс24) — синхронизация заказов портала со сделками CRM. Зависимость двусторонняя: заказ с портала создаёт сделку, изменение статуса сделки меняет статус заказа. Через REST API crm.deal.add / crm.deal.update с вебхуком обратно.
Личный кабинет — минимальный набор: история заказов с повтором, текущие заказы в работе, задолженность по актам сверки, документы (счета, накладные в PDF), управление контактными лицами компании.
Интеграция с 1С
Это обычно самая трудоёмкая часть. Стандартный обмен через CommerceML закрывает товары, цены, склады, заказы. Но не закрывает:
-
Лимиты кредита и задолженность — выгружается отдельным XML или через REST-сервис 1С. На стороне Битрикс — кастомный Highload-блок
b2b_credit_limitsс полями:UF_COMPANY_ID,UF_CREDIT_LIMIT,UF_CURRENT_DEBT,UF_OVERDUE_DEBT,UF_UPDATED_AT -
Документы — счета и накладные хранятся в 1С. Портал запрашивает список через REST, получает ссылки на PDF или бинарные данные. Кешируем в
/upload/b2b/docs/с TTL 24 часа -
Спецификации — индивидуальные договорные позиции, которых нет в общем прайсе. Синхронизируются отдельным форматом, хранятся в Highload-блоке с привязкой к
COMPANY_ID
Критически важно: не ломать стандартный обмен CommerceML. Кастомные поля и логика — через события OnBeforeCatalogImport1C, OnSuccessCatalogImport1C, отдельные таблицы. Ядро обмена не трогаем.
Производительность под нагрузкой
B2B-портал с 500+ активными компаниями и пиковой нагрузкой в момент открытия рабочего дня — это другие требования, чем у розничного магазина.
- Кеш каталога — тегированный, тег привязан к IBLOCK_ID.
CIBlock::clearIblockTagCache($iblockId)при обновлении остатков из 1С очищает только нужные страницы - Цены — не кешируются на уровне компонента, если персональные. Альтернатива: кеш по ключу
user_group_price_{groupId}_{productId}, инвалидация при изменении цены - Сессии — при наличии балансировщика между несколькими серверами сессии переносятся в Redis, настройка через
\Bitrix\Main\Application::getInstance()->getSession() - Поиск по каталогу — модуль
searchне справляется с B2B-фильтрами. Подключается Elasticsearch через кастомный индексер, который обходитCIBlockElement::GetListи напрямую формирует документы для индекса
Этапы разработки
| Этап | Содержание | Срок |
|---|---|---|
| Аналитика | Схема ролей, сценарии заказа, карта интеграций с 1С | 2-3 недели |
| Проектирование БД | Highload-блоки, D7-сущности, схема ценообразования | 1-2 недели |
| Бэкенд | Модуль авторизации, ценообразование, интеграция 1С | 4-8 недель |
| Личный кабинет | Заказы, документы, управление компанией | 3-5 недель |
| Согласование заказов | Бизнес-процессы bizproc, уведомления |
1-3 недели |
| Тестирование | Нагрузочное, приёмочное, интеграционное | 2-3 недели |
Итого: 12-22 недели в зависимости от глубины интеграции с 1С и количества кастомных бизнес-правил.
Что часто идёт не так
Хранят персональные цены в сессии. Работает до перезапуска PHP-FPM, при балансировке — теряются. Цены хранятся в базе или Redis, не в сессии.
Синхронизация 1С блокирует сайт. Полный импорт CommerceML на 50К товаров занимает 20-40 минут и держит таблицы на lock. Переходим на инкрементальный обмен: только изменённые позиции с момента последней синхронизации.
Бизнес-процессы согласования написаны в init.php. Логика согласования заказов на 300 строк в init.php — это технический долг, который придётся переписывать при любом изменении правил. Выносим в отдельный модуль с конфигурируемыми правилами.







