Маркетолог обнаруживает, что фид для Яндекс.Маркета обновляется раз в сутки через ручной экспорт, а цены в каталоге меняются несколько раз в день из-за выгрузки из 1С. В итоге на маркетплейсе показываются неактуальные цены — покупатели кликают, видят другую стоимость и уходят. Стандартный модуль экспорта Битрикс (catalog.export) справляется с базовыми случаями, но при нестандартных требованиях (несколько складов, кастомные свойства, региональные условия) упирается в ограничения. На одном из проектов с каталогом на 50 000 товаров расхождение цен достигало 15%, что приводило к 30% отказов от покупок. Только после внедрения кастомного модуля с инкрементальным обновлением проблема была решена. Наш опыт насчитывает более 30 успешных проектов. Гарантируем корректную обработку остатков и отсутствие дублей. Свяжитесь с нами — разработаем модуль под вашу специфику.
Почему стандартный экспорт не подходит для генерации фидов?
Стандартный модуль catalog.export не поддерживает:
- Множественные склады с раздельными остатками.
- Кастомные свойства для разных каналов (например,
condition для Google Merchant).
- Региональные цены и скидки.
- Инкрементальное обновление — приходится генерировать полный фид каждый раз, что на 50 000 товаров занимает 5–10 минут и грузит сервер.
Эти ограничения ведут к ручному экспорту, ошибкам и неактуальным данным. Кастомный модуль решает все задачи.
Как устроен модуль генерации фидов?
Основная задача — сделать генерацию быстрой, гибкой и автоматической. Модуль строится вокруг трёх компонентов: движка шаблонов фидов, планировщика обновлений и реестра форматов.
Реестр форматов хранит конфигурации для каждого канала: Яндекс.Маркет (YML), Google Merchant (XML/CSV), ВКонтакте, Avito, Ozon, собственный формат клиента. Каждый формат описывается PHP-классом, реализующим интерфейс FeedFormatInterface:
interface FeedFormatInterface {
public function getHeader(): string;
public function renderOffer(array $element, array $prices): string;
public function getFooter(): string;
public function getMimeType(): string;
}
Это позволяет добавлять новые форматы, не трогая ядро генератора. Подробнее о формате YML — в Wikipedia.
Генератор работает поточно: данные читаются из b_iblock_element, b_catalog_price, b_catalog_product через DataManager::getList с пагинацией (батчи по 500 элементов), немедленно пишутся в файл через fwrite. Генерация фида из 50 000 товаров не требует 512 МБ памяти. Финальный файл атомарно заменяет предыдущий (rename), поэтому краулер не получает частично записанный документ.
Как работают резолверы цен и остатков?
Это самая вариативная часть. Одному проекту нужна цена для незарегистрированного пользователя, другому — специальная цена с учётом акции, третьему — минимальная цена среди всех складов.
Модуль реализует резолвер цен — стратегию, выбирающую итоговую цену по набору правил:
$priceResolver = new PriceResolver([
new DiscountRule($userId), // применить скидки через Sale\Discount
new RegionPriceRule($regionCode), // региональная надбавка
new MinPriceRule(), // взять минимум среди групп цен
]);
$finalPrice = $priceResolver->resolve($productId);
Остатки по складам. Для Ozon и других площадок нужно указывать остатки по конкретным складам (b_catalog_store_product). Модуль агрегирует остатки по нескольким складам (до 50), применяет резервы из b_sale_basket и выводит корректное доступное количество.
Фильтрация товаров. Через интерфейс модуля задаются условия: только товары с ненулевым остатком, определённые разделы, исключение по свойству CML2_EXPORT = N. Условия компилируются в фильтр для CIBlockElement::GetList.
Что такое инкрементальное обновление?
Полная перегенерация фида из 50 000 позиций занимает 3–5 минут. Для частого обновления цен это неприемлемо. Модуль поддерживает инкрементальный режим: через событие OnAfterCatalogPriceUpdate фиксируются изменившиеся товары, и раз в 15 минут агент перегенерирует только их строки в фиде через partial-update с временным файлом и патчингом. Такое обновление в 10 раз быстрее полной перегенерации. Событие описано в документации Битрикс.
Как мониторинг помогает в работе модуля генерации фидов?
Модуль ведёт таблицу myvendor_feed_log с историей генераций: время начала/конца, количество элементов, размер файла, ошибки. В админ-интерфейсе выводится дашборд: когда обновлялся каждый фид, сколько товаров попало в выгрузку, какие отфильтрованы и почему. Это позволяет быстро выявлять проблемы с данными или конфигурацией.
Типичные ошибки при настройке фидов
- Неправильные URL изображений (не HTTPS).
- Отсутствует идентификатор товара в формате `vendorCode`.
- Завышенный ценовой лимит на площадке.
- Некорректная привязка категорий.
- Отсутствие обязательных полей (например, `condition` для Google Merchant).
Процесс разработки модуля
- Аудит текущего каталога и требований к фидам.
- Проектирование архитектуры модуля (резолверы, форматы, кэширование).
- Разработка и интеграция модуля на вашем проекте.
- Настройка агентов и планировщика для автоматической генерации.
- Тестирование на реальных данных и корректировка.
- Передача документации и обучение администраторов.
- Гарантийная поддержка 1 месяц.
Сравнение стандартного и кастомного модуля
| Критерий |
Стандартный модуль |
Кастомный модуль |
| Инкрементальное обновление |
Нет |
Да, через агенты |
| Поддержка нескольких форматов |
Ограниченно |
Любые (YML, XML, CSV, JSON) |
| Гибкая фильтрация товаров |
Минимальная |
По свойствам, разделам, остаткам, регионам |
| Резолвер цен |
Только основная цена |
Множественные стратегии |
| Мониторинг и логирование |
Нет |
Да, с дашбордом |
| Требования к памяти |
Высокие (полная загрузка) |
Низкие (потоковая запись) |
Сроки разработки
| Объём |
Состав |
Срок |
| Базовый |
1 формат (YML или GMC) + планировщик |
2–3 недели |
| Средний |
3–5 форматов + резолвер цен + остатки |
4–6 недель |
| Расширенный |
+ инкрементальное обновление + мониторинг + регионы |
7–10 недель |
Сроки могут быть скорректированы после анализа вашего каталога. Для точной оценки свяжитесь с нами — получите консультацию по вашему проекту. Конфигурация торгового каталога (цены, структура складов, наличие торговых предложений) должна быть зафиксирована до начала разработки.
Разработка и настройка модулей 1С-Битрикс
Главная ловушка Битрикса — init.php. Сунул туда обработчик OnBeforeIBlockElementUpdate, потом ещё один — через год файл на 2000 строк, и при каждом хите весь этот ком выполняется. Мы переносим бизнес-логику в полноценные модули с D7 ORM, собственными таблицами и административным интерфейсом. Модуль можно отключить, перенести на другой проект, покрыть тестами — с init.php ничего из этого не получится. Опыт команды — 10+ лет в Битрикс, сертифицированные специалисты, гарантия на код 6 месяцев. Закажите консультацию — расскажем, как перевести legacy-код в модульную архитектуру.
Почему init.php — худшее место для бизнес-логики?
Init.php не поддерживает автозагрузку классов, не имеет изолированного пространства имён, не поддаётся модульному тестированию и не отключается без правки самого файла. Каждый обработчик, написанный там, срабатывает на каждом запросе, даже если он не нужен. В модуле вы регистрируете обработчика через EventManager, и он выполняется только при наступлении события. Разница в производительности — до 3 раз при 10+ обработчиках.
Стандартные модули: типовые проблемы и решения
Информационные блоки. Архитектура ИБ — первое, что мы ревьюим на любом проекте. Классическая ошибка: один инфоблок каталога с 80 свойствами, из которых 30 — множественные. Таблица b_iblock_element_property раздувается до миллионов строк, CIBlockElement::GetList на фильтрации по трём свойствам уходит в полное сканирование. Переносим справочники в Highload-блоки, убираем множественные свойства где можно, проектируем структуру с прицелом на то, что каталог вырастет в 5 раз.
Интернет-магазин (sale). Бизнес-правила корзины — отдельная история. Настраиваем приоритеты скидок, чтобы две акции не дали 60% вместо 30%, подключаем платёжные обработчики, прописываем кастомную валидацию через OnSaleOrderBeforeSaved.
Поиск. Встроенный модуль search с морфологией работает до 10–15 тысяч элементов. Дальше — Elasticsearch. Настраиваем через API модуля поиска Битрикс, индексируем через CSearchFullText или кастомные индексаторы.
Highload-блоки для справочников, логов, пользовательских данных — вместо раздутых ИБ. Прямые запросы через Bitrix\Highloadblock\HighloadBlockTable, собственные таблицы вместо EAV-структуры стандартных инфоблоков. Миллион записей — без деградации.
Почтовые события. Настройка — не только шаблоны в b_event_message. Главное — SPF, DKIM, DMARC на DNS, иначе транзакционные письма летят в спам. Проверяем доставляемость, настраиваем bounce-обработку.
Проектирование инфоблоков для производительности
Используем Highload-блоки для справочных данных (цвета, размеры, производители), которые не участвуют в сложных выборках. Для торговых предложений — отдельный инфоблок с привязкой через IBLOCK_ELEMENT_PROPERTY. Включаем INDEX_PROPERTY для часто фильтруемых свойств. Кэширование тегированное: при изменении элемента сбрасывается только связанный кеш. Highload-блоки обрабатывают до 10 раз быстрее, чем инфоблоки с множественными свойствами, на объёмах от 100 000 записей.
Разработка кастомных модулей
Каждый модуль — по структуре /local/modules/vendor.modulename/:
-
install/index.php — класс установки, создание таблиц через $DB->RunSQLBatch()
-
lib/ — классы D7 ORM, наследники Bitrix\Main\ORM\Data\DataManager
-
admin/ — административные страницы через CAdminList, CAdminForm
-
include.php — автозагрузка, регистрация обработчиков через EventManager::getInstance()->registerEventHandler()
- REST API endpoints через
\Bitrix\Rest\RestManager
Модуль регистрируется в системе, появляется в списке «Установленные решения», имеет свои настройки в /bitrix/admin/settings.php?mid=vendor.modulename. Его можно включать, отключать, обновлять через UpdateSystem или свой механизм миграций.
Примеры реализованных задач:
- Управление акциями — визуальный конструктор условий через
CAdminCalendar, таймеры через агенты (CAgent::AddAgent), аналитика эффективности в связке с модулем sale
- Калькулятор стоимости — React-виджет на фронте, REST API в модуле, формулы хранятся в Highload-блоке
- Система бронирования — real-time календарь, блокировка через
$DB->StartTransaction() / $DB->Commit() при одновременных запросах, синхронизация с channel manager через webhook
Компоненты и композитный кэш
Кастомизация компонентов — через result_modifier.php и component_epilog.php, не через правку template.php стандартного шаблона. Так ядро обновляется безболезненно.
Композитный кэш (технология «Композитный сайт») — сервер отдаёт готовый HTML, минуя PHP-роутинг. Динамические зоны (корзина, авторизация) подгружаются через CBitrixComponent::setFrameMode(true) и AJAX. TTFB падает до 30–50 мс. Но есть нюансы: не все компоненты совместимы, $APPLICATION->ShowPanel() ломает композит, нужна аккуратная разметка <div id="bx-composite-...">.
Маркетплейс: аудит перед установкой
Перед установкой модуля с маркетплейса — обязательный аудит. Проверяем: SQL-запросы без подготовленных выражений (привет, SQL-инъекции), прямое обращение к $_REQUEST без фильтрации, использование устаревшего API старого ядра вместо D7, конфликты с модулем композитного кэширования. Модуль без обновлений больше года и с парой десятков установок — скорее всего, проблема на ближайшем обновлении PHP. Типичный случай: модуль вызывает CIBlockElement::GetList с несброшенным кешем — сайт падает при 5000 элементов.
Миграция на D7
При обновлении PHP или переходе на новую редакцию — рефакторинг устаревших вызовов:
-
CIBlockElement::GetList() → Bitrix\Iblock\Elements\ElementTable::getList()
-
CSaleOrder::GetList() → Bitrix\Sale\Order::getList()
-
CModule::IncludeModule() → Bitrix\Main\Loader::includeModule()
Тестирование на staging, откат через git при проблемах.
Согласно официальной документации 1С-Битрикс, D7 ORM является рекомендуемым средством для работы с данными, обеспечивая безопасность типов и автогенерацию запросов.
Сравнение подходов: Init.php vs Модуль
| Критерий |
Init.php |
Модуль с D7 ORM |
| Производительность |
Выполняется на каждом хите |
Выполняется только при событии |
| Тестируемость |
Нет автозагрузки, тесты невозможны |
Полная поддержка PHPUnit |
| Поддерживаемость |
Кодовая база растёт бесконтрольно |
Изолированная структура, версионирование |
| Миграции |
Нет |
Собственные таблицы, управление через install |
| Кэширование |
Не поддерживает автоинвалидацию |
Тегированное кэширование, сброс по событию |
Стоимость и состав разработки модулей
Что входит в разработку модуля?
- Техническое задание и архитектурная схема
- Код с соблюдением PSR-4 и код-стайла Битрикс
- Unit-тесты (PHPUnit) на бизнес-логику
- Интеграционные тесты на события и REST API
- Документация по установке, настройке и API
- Передача доступов к репозиторию и документации
- Обучение администраторов работе с модулем
- Гарантийная поддержка 6 месяцев
Ориентировочные сроки и сложность:
| Сложность |
Примеры |
Сроки |
| Простой |
Виджет обратного звонка, баннерная система, простой калькулятор |
3–5 дней |
| Средний |
Система бронирования, конфигуратор товаров, модуль отзывов с модерацией |
1–2 недели |
| Сложный |
Мультирегиональность, кастомная программа лояльности, интеграция с ERP |
2–4 недели |
| Enterprise |
Маркетплейс-платформа, сложные бизнес-процессы с множеством ролей |
1–3 месяца |
Стоимость рассчитывается индивидуально — свяжитесь с нами для оценки вашего проекта.
Тестирование модулей
Unit-тесты через PHPUnit покрывают бизнес-логику: расчёт скидок, валидацию, формирование документов. Моки для Bitrix\Main\Application::getConnection() позволяют тестам не зависеть от БД. Интеграционные тесты проверяют обработчики событий на реальной базе — OnAfterIBlockElementAdd, OnSaleOrderSaved и другие. REST API endpoints тестируем через curl или PHPUnit HTTP-клиент. Критично для модулей, работающих с b_sale_order, b_catalog_price — где ошибка стоит денег.
Совместимость проверяется на PHP 7.4, 8.0, 8.1, 8.2 и редакциях: Стандарт, Малый бизнес, Бизнес. Проверяем конфликты с популярными модулями маркетплейса — они любят перехватывать те же события. Нагрузочное тестирование: замеры на 10K, 100K, 1M записей, профилирование через Xdebug на предмет утечек памяти и N+1 запросов.
Примеры из практики
Модуль акций для сети электроники. Штатные скидки модуля sale не покрывали сценарии «2+1», подарок при покупке от суммы, комбинированные условия. Собрали визуальный конструктор: маркетолог создаёт правила через drag-and-drop, без тикетов в разработку. Календарь акций, автодеактивация через агенты, аналитика в привязке к b_sale_order — конверсия, средний чек, количество применений. Время запуска новой акции упало с двух дней до получаса.
Калькулятор для строителей. Параметры (площадь, материалы, этажность) → формула → предварительная смета → заявка в CRM через CRest::call('crm.lead.add'). Региональные коэффициенты и сезонные наценки — из Highload-блока, цены материалов — из обмена с 1С. Количество целевых заявок выросло на треть: клиенты видят разбивку по статьям до звонка менеджеру.
Бронирование для сети отелей. Real-time доступность через AJAX-запросы к кастомной таблице vendor_booking_slots, расчёт тарифов по сезону, синхронизация с Booking.com через channel manager API. Блокировка номера при одновременном бронировании — через SELECT ... FOR UPDATE в транзакции. Таймзоны обрабатываются через \DateTimeZone — гость из Владивостока и менеджер из Москвы видят одну картину.
Оценим проект за 1 день. Пишите — расскажем, что входит в разработку под ключ. Свяжитесь с нами для консультации по вашему проекту. Закажите разработку модуля под ключ — получите готовое решение с документацией и поддержкой.