Разработка кастомизируемой витрины для дилеров 1С-Битрикс
Дилер работает не как розничный покупатель. Ему нужен свой прайс-лист с персональными ценами, возможность оформлять заказ от имени конечного клиента, видеть остатки по складам и выгружать данные в свою учётную систему. Стандартная витрина интернет-магазина Битрикс не покрывает ни одного из этих сценариев без серьёзной доработки. Задача — построить B2B-раздел, который работает параллельно с розничным магазином на том же инфоблоке товаров.
Архитектура: многосайтовость или раздел
Два подхода к разделению розницы и дилеров:
Мультисайт — отдельный сайт в Битрикс (s2) с собственным доменом (dealer.myshop.by). Дилерский сайт использует тот же инфоблок каталога, но свой тип цен и шаблон. Преимущество: полная изоляция дизайна, настроек корзины и оформления заказа. Недостаток: дублирование шаблонов компонентов.
Раздел на основном сайте — /dealer/ с проверкой принадлежности пользователя к группе «Дилеры». Компоненты каталога используют тот же инфоблок, но через параметр PRICE_CODE показывают дилерский тип цены. Проще в поддержке, но сложнее изолировать логику оформления заказа.
Для большинства проектов мультисайт — правильный выбор. Он даёт чистое разделение бизнес-логики без условных конструкций в шаблонах.
Персональные цены и типы цен
Битрикс поддерживает до 8 типов цен в стандартной лицензии и неограниченное количество — в «Бизнес» и выше. Для дилерской витрины создаётся отдельный тип цены (например, DEALER_PRICE), привязанный к группе пользователей «Дилеры».
Персонализация по дилеру реализуется через дополнительные типы цен — по одному на каждого крупного дилера — или через скидки каталога, привязанные к группе пользователя. Первый вариант масштабируется до 20–30 дилеров, дальше управление становится неподъёмным. Второй — работает на любом количестве, но не даёт гибкости «любая цена для любого товара».
Для индивидуальных прайсов с тысячами позиций используйте пользовательское свойство заказа с ценой, рассчитанной на лету из базовой дилерской цены и персонального коэффициента. Коэффициент хранится в UF-поле пользователя (UF_DEALER_DISCOUNT), цена пересчитывается в обработчике OnGetOptimalPrice.
Остатки по складам
Розничный покупатель видит «В наличии / Нет в наличии». Дилеру нужны точные цифры по складам.
Модуль catalog.store хранит остатки в таблице b_catalog_store_product (поля PRODUCT_ID, STORE_ID, AMOUNT). Склады — в b_catalog_store. Компонент catalog.store.amount выводит остатки, но его стандартный шаблон не подходит для B2B — нет группировки по регионам, нет фильтрации по складам, доступным конкретному дилеру.
Решение: кастомный шаблон компонента, который фильтрует склады по UF-полю пользователя UF_AVAILABLE_STORES (массив ID складов). Дилер из Минска видит склады «Минск-1» и «Минск-2», дилер из Гомеля — «Гомель-центральный».
Заказ от имени клиента
Дилер оформляет заказ и указывает конечного получателя. В модуле sale это реализуется через свойства заказа типа «Конечный клиент» — группа свойств (PERSON_TYPE) для дилерского типа плательщика.
Создайте тип плательщика «Дилер» с полями: реквизиты дилера (заполняются автоматически из профиля) + блок «Конечный получатель» (ФИО, адрес, телефон). В обработчике OnSaleOrderBeforeSaved проверяйте, что дилер не может оформить заказ по розничному типу плательщика.
Выгрузка данных
Дилеры запрашивают прайс-лист в Excel/CSV для загрузки в свою 1С. Реализуется через кастомную страницу /dealer/export/, которая генерирует файл на основании \Bitrix\Catalog\PriceTable::getList() с фильтром по дилерскому типу цены. Формат Excel — через библиотеку PhpSpreadsheet (ставится через Composer).
Для автоматической выгрузки дайте дилеру API-эндпоинт с авторизацией по токену. Эндпоинт возвращает JSON с товарами, ценами и остатками — дилер забирает его по cron.
Сроки
| Компонент | Срок |
|---|---|
| Мультисайт + базовый каталог с дилерскими ценами | 3–4 дня |
| Персональные коэффициенты + остатки по складам | 3–4 дня |
| Заказ от имени клиента + выгрузка | 2–3 дня |
| Тестирование и отладка прав доступа | 1–2 дня |
| Итого | 1–2 недели |







