Динамическое ценообразование: от правил до обработчика
Представьте: интернет-магазин электроники с 10 000 позиций. Один товар — SSD-накопитель. При остатке меньше 10 штук цена автоматически растёт на 20% — без ручных скидок, только логика в коде. Реализовать это можно через перехват события OnGetOptimalPrice — подменяем цену на лету, не трогая таблицу b_catalog_price. За 5 лет реализовали более 50 проектов с динамическим ценообразованием для магазинов разного масштаба. Наши клиенты получают прозрачный аудит: все модификации логируются в отдельную таблицу.
Как Битрикс формирует итоговую цену?
Цепочка расчёта: базовая цена (b_catalog_price) → скидки каталога (b_catalog_discount) → правила корзины (b_sale_discount) → итог. Динамическое ценообразование работает на первом уровне — меняет базовую цену, либо перехватывает её через событие OnGetOptimalPrice и возвращает другое значение. Событие вызывается при каждом запросе цены: в списке товаров, на детальной, в корзине. Без оптимизации один запрос к БД — 0.3 мс, но страница каталога с 48 товарами — 48 запросов. Решение — кэшировать модификатор с TTL 5 минут.
Почему стоит использовать событие, а не прямую запись в базу?
| Критерий | Через событие OnGetOptimalPrice |
Прямая смена цены в b_catalog_price |
|---|---|---|
| Чистота истории цен | Цена остаётся неизменной, модификатор применяется на лету | Заполняет историю лишними записями |
| Откат изменений | Мгновенно — отключаем правило | Нужно восстанавливать предыдущие значения, до 2 часов |
| Индексация прайсов | Не влияет | Может искажать выгрузки |
| Производительность | Один запрос к кэшу на товар | Много запросов на запись при каждом изменении |
Событие сокращает время отката до 1 минуты, а прямая запись требует восстановления из бекапа. Кэширование ускоряет работу в 10 раз.
Какие правила динамического ценообразования мы настраиваем?
Правила хранятся в пользовательской таблице bl_dynamic_pricing_rules. Вот её поля с примерами:
| Поле | Описание | Пример |
|---|---|---|
rule_type |
stock / demand / competitor / time |
stock |
iblock_id |
инфоблок или NULL (все) | 17 |
product_id |
конкретный товар или NULL (все в разделе) | 1234 |
condition_json |
параметры условия (остаток, час, коэффициент) | {"min_stock": 5} |
price_modifier |
коэффициент (1.15 = +15%, 0.9 = -10%) | 1.2 |
priority |
порядок применения при конфликте правил | 10 |
active |
включено/выключено | Y |
При конфликте правил применяется правило с наивысшим приоритетом.
Пример: правило по остаткам склада
Если остаток товара падает ниже порога — повышаем цену. Это стимулирует покупать быстрее или ограничивает ажиотаж. Остатки берём из b_catalog_store_product:
$stock = \Bitrix\Catalog\StoreProductTable::getList([ 'filter' => ['PRODUCT_ID' => $productId], 'select' => ['AMOUNT'], 'runtime' => [new \Bitrix\Main\ORM\Fields\ExpressionField('TOTAL', 'SUM(%s)', 'AMOUNT')], ])->fetch()['TOTAL'] ?? 0; if ($stock < 5) return 1.2; // +20% при остатке < 5 шт if ($stock < 20) return 1.1; // +10% при остатке < 20 шт return 1.0; Пороги и коэффициенты вы можете настроить в административном интерфейсе.
Как настроить правило по остаткам?
- Создайте правило в административном интерфейсе (раздел «Динамическое ценообразование»).
- Укажите тип
stock. - Задайте пороги остатков (например,
<5,5-20). - Назначьте коэффициент изменения цены (например,
1.2для +20%). - Включите кэширование с TTL 300 секунд.
- Протестируйте на одном товаре — проверьте цену на витрине.
- Активируйте правило для всего каталога.
Оптимизация производительности
Без кэширования страница каталога с 48 товарами делает 48 вызовов события OnGetOptimalPrice к БД. С кэшированием — 1 запрос каждые 5 минут. Нагрузка снижается в 10 раз. Мы также используем тегированный кэш Bitrix \Bitrix\Main\Data\Cache с TTL 300 секунд и сбросом по тегу dynamic_price_{productId}. Это позволяет выдерживать каталоги до 100 000 товаров без просадок.
Процесс работы
- Анализ: изучаем текущую схему ценообразования, бизнес-требования, нагрузку на сайт.
- Проектирование: создаём структуру таблицы
bl_dynamic_pricing_rulesи логику приоритетов. - Разработка: пишем класс
DynamicPricingEngineс кэшированием, подключаем обработчикOnGetOptimalPriceвinit.php. - Интерфейс администрирования: создаём форму для управления правилами (добавление, редактирование, включение/отключение).
- Логирование: записываем все применения правил в
bl_dynamic_pricing_logдля аудита. - Тестирование: нагрузочное тестирование на каталоге из 100 000 товаров, проверка корректности цен.
- Деплой и документация: инструкция для оператора по настройке правил.
Что входит в результат
После завершения работ вы получаете:
- работающий механизм динамического ценообразования на основе правил;
- административный интерфейс для управления правилами без доступа к коду;
- логи всех изменений цен для аудита;
- документацию по настройке и эксплуатации;
- нагрузочное тестирование каталога до 100 000 товаров;
- гарантийную поддержку в течение месяца после внедрения.
Сроки и консультация
Настройка занимает от 3 до 10 рабочих дней в зависимости от числа правил и размера каталога. Стоимость рассчитывается индивидуально — мы оценим проект после брифа. Получите консультацию — свяжитесь с нами, и мы подготовим дорожную карту. Закажите внедрение — и ваш магазин получит гибкое ценообразование без ручного управления.
Мы гарантируем, что решение будет работать стабильно: выдержит пиковые нагрузки и не вызовет ошибок на витрине. Наши сертификаты и портфолио — по запросу.







