Розробка сайту автодилера на 1С-Бітрікс
Сайт автодилера — це каталог, де один товар коштує від п'ятисот тисяч до кількох мільйонів гривень. Відвідувач не кладе автомобіль у кошик — він підбирає, порівнює, рахує кредит, записується на тест-драйв. Середня сесія на дилерському сайті — 6-9 хвилин, 3-4 перемикання фільтрів, 2-3 відкриті картки. Якщо фільтр по марці-моделі гальмує, фотографії вантажаться по одній, а калькулятор кредиту вимагає перезавантаження сторінки — відвідувач іде на RST.ua або AUTO.RIA, де все це працює. Завдання — побудувати архітектуру, яка не поступається агрегаторам за швидкістю роботи каталогу, але залишається керованою з адмінки Бітрікса.
Архітектура каталогу: нові автомобілі та автомобілі з пробігом
Перше архітектурне рішення — зберігати нові й вживані автомобілі в одному інфоблоці чи в різних. Відповідь залежить від бізнес-логіки, а не від технічних обмежень.
Один інфоблок, розділи за типами — підходить мультибрендовому дилеру з каталогом до 2000 позицій. Нові та б/в автомобілі мають 80%+ спільних властивостей: марка, модель, рік, двигун, коробка, колір, ціна, фото. Відмінності: у нових є комплектація та гарантійні умови, у б/в — пробіг, VIN, кількість власників, історія обслуговування. Порожні властивості не створюють записів у b_iblock_element_property — таблиця не роздувається. Плюс: єдиний bitrix:catalog.smart_filter, єдиний пошук, одна стрічка в адмінці.
Два інфоблоки — виправдано, коли нові автомобілі формуються з конфігуратора (марка -> модель -> комплектація -> колір -> опції), а б/в — це конкретні екземпляри з VIN. У конфігуратора своя логіка вкладеності (Highload-блоки комплектацій, пакетів опцій), яка не потрібна вживаним. Змішувати в одному інфоблоці — засмічувати адмінку. Мінус: пошук «всі BMW X5» по обох інфоблоках потребує кастомний компонент.
Рекомендована структура для середнього дилера (500-3000 автомобілів):
- Інфоблок «Автомобілі» — розділи: Нові, З пробігом
- Highload-блок «Марки» — довідник марок (BMW, Toyota, Kia...) з логотипами
-
Highload-блок «Моделі» — довідник моделей з прив'язкою до марки через
UF_BRAND_ID - Highload-блок «Покоління» — покоління моделей (тип кузова, роки випуску)
- Highload-блок «Комплектації» — для нових: набір опцій + ціна
-
Інфоблок «Акції» — спеціальні пропозиції з прив'язкою до автомобілів через
PROPERTY_CAR_IDS
Властивості автомобіля — мінімум 40 полів. Ключові для фільтрації та фідів:
| Властивість | Код | Тип | Індексація |
|---|---|---|---|
| Марка | BRAND | S:Highload | Фасетний індекс |
| Модель | MODEL | S:Highload | Фасетний індекс |
| Рік випуску | YEAR | N (число) | Фасетний індекс |
| Ціна | PRICE | N | Фасетний індекс |
| Пробіг | MILEAGE | N | Фасетний індекс |
| Тип двигуна | ENGINE_TYPE | L (список: бензин, дизель, гібрид, електро) | Фасетний індекс |
| Об'єм двигуна | ENGINE_VOLUME | N | Фасетний індекс |
| Коробка передач | TRANSMISSION | L (МКПП, АКПП, робот, варіатор) | Фасетний індекс |
| Привід | DRIVE | L (передній, задній, повний) | Фасетний індекс |
| Тип кузова | BODY_TYPE | L (седан, SUV, хетчбек...) | Фасетний індекс |
| Колір | COLOR | S (рядок) | Фасетний індекс |
| VIN | VIN | S | Ні (унікальний, пошук за точним збігом) |
| Статус | STATUS | L (в наявності, в дорозі, зарезервований) | Фасетний індекс |
| Фото екстер'єр | PHOTOS | F (файл, множинне) | Ні |
| Фото інтер'єр | PHOTOS_INTERIOR | F (множинне) | Ні |
| 360 екстер'єр | SPIN_360_URL | S | Ні |
| Панорама салону | INTERIOR_PANORAMA | S | Ні |
VIN зберігається як рядкова властивість без фасетного індексу — по ньому шукають точним збігом, а не діапазоном. Пошук по VIN реалізується через CIBlockElement::GetList з фільтром ['=PROPERTY_VIN' => $vin].
Залежна фільтрація марка -> модель: чому це складніше, ніж здається
Штатний bitrix:catalog.smart_filter показує всі значення всіх властивостей одночасно. Користувач обирає марку BMW — але у списку моделей досі висять Camry, Ceed, Solaris. Це руйнує UX дилерського сайту. Потрібна каскадна фільтрація: обрав марку — список моделей перерахувався, обрав модель — список поколінь перерахувався.
Варіант 1: кастомний AJAX-контролер. Окремий endpoint /api/catalog/filter-values/, який приймає поточні обрані фільтри і повертає допустимі значення решти властивостей.
// Контролер каскадного фільтра
class FilterValuesController extends \Bitrix\Main\Engine\Controller
{
public function getModelsAction(int $brandId): array
{
$models = [];
$res = \CIBlockElement::GetList(
[],
[
'IBLOCK_ID' => CAR_IBLOCK_ID,
'ACTIVE' => 'Y',
'PROPERTY_BRAND' => $brandId,
],
['PROPERTY_MODEL' => 'CNT'], // GROUP BY MODEL
false,
['PROPERTY_MODEL']
);
while ($row = $res->Fetch()) {
$models[] = [
'id' => $row['PROPERTY_MODEL_VALUE'],
'count' => $row['CNT'],
];
}
return $models;
}
}
На фронті — подія change на select марки, AJAX-запит через BX.ajax.runAction('controller.filterValues.getModels', {data: {brandId: val}}), оновлення select моделі. Для select з 50+ варіантами використовуємо Choices.js або Tom Select — стандартний <select> не придатний.
Варіант 2: передзавантаження дерева залежностей. При рендері сторінки каталогу в JavaScript передається JSON-об'єкт усіх залежностей: {brand_1: [model_5, model_12, ...], brand_2: [...]}. При 30 марках і 200 моделях — це 3-5 КБ JSON. Вибір марки фільтрує моделі на клієнті без AJAX. Швидко, але не враховує поточний стік — показує модель, навіть якщо автомобілів цієї моделі зараз немає. Рішення — у JSON включати count: {model_5: {name: "X5", count: 7}}, і приховувати моделі з count: 0.
Варіант 3: комбінація. Передзавантаження дерева марка-модель-покоління при першому заході (JSON), AJAX-перерахунок count при зміні будь-якого фільтра. Це дає миттєвий відгук на вибір марки (список моделей з'являється без затримки) й актуальні лічильники (перераховані з урахуванням ціни, року, пробігу).
Для range-повзунків (ціна, пробіг, рік випуску) — логіка аналогічна будь-якому каталогу Бітрікс: bitrix:catalog.smart_filter віддає MIN_VALUE/MAX_VALUE, на фронті noUiSlider, значення передаються через GET-параметри arrFilter_P1_MIN/arrFilter_P1_MAX. AJAX-підвантаження результатів через bitrix:catalog.section з AJAX_MODE=Y.
XML-фіди для авто-агрегаторів: три формати, три головні болі
Авто-агрегатори — основне джерело трафіку для дилера. AUTO.RIA, RST.ua, av.by — у кожного свій XML-формат, свій набір обов'язкових полів, свої правила валідації. Помилка у фіді — оголошення знімаються з публікації, дилер втрачає дзвінки.
AUTO.RIA використовує власний XML-формат з обов'язковими полями: марка і модель за довідником AUTO.RIA (числові marka_id, model_id), рік, ціна у валюті, пробіг, тип палива, коробка передач, тип кузова, фотографії. Якщо у вашому Highload-блоці марка називається «БМВ», а в довіднику AUTO.RIA — числовий ідентифікатор 9, фід буде відхилено. Потрібен маппінг — додаткове поле UF_AUTORIA_ID у Highload-блоці марок і моделей.
<offers>
<offer>
<marka_id>9</marka_id>
<model_id>96</model_id>
<year>2024</year>
<price value="2850000" currency="UAH"/>
<race>0</race>
<fuel_id>2</fuel_id>
<gearbox_id>2</gearbox_id>
<body_id>3</body_id>
<vin>WBAJC51090B123456</vin>
<photos>
<photo url="https://site.ua/upload/cars/12345/photo1.jpg"/>
</photos>
</offer>
</offers>
Зверніть увагу: AUTO.RIA оперує числовими ідентифікаторами, а не текстовими кодами. Тип палива 2 — це дизель, коробка 2 — автомат. Ці значення треба зберігати у маппінг-таблиці.
Avito Авто (актуально для дилерів, які працюють і на ринок РФ) — формат Autoload. Кузов — російською («Внедорожник», а не ALLROAD_5_DOORS), тип двигуна — «Дизель», покоління повинно включати маркер рестайлінгу. Кожен агрегатор говорить своєю мовою.
av.by (Білорусь) — власний XML-формат, значення полів російською, обов'язкове зазначення міста за довідником av.by, свої brand_id та model_id.
Архітектура генератора фідів:
-
Абстрактний клас
BaseFeedGenerator— вибірка елементів з інфоблоку черезCIBlockElement::GetList, ітерація, запис XML черезXMLWriter. -
Конкретні класи:
AutoRiaFeedGenerator,AvitoAutoFeedGenerator,AvByFeedGenerator— перевизначають маппінг властивостей у XML-теги та трансформацію значень. -
Таблиця маппінгу — Highload-блок
FeedMappingз полямиUF_PROPERTY_CODE,UF_FEED_TYPE,UF_LOCAL_VALUE,UF_FEED_VALUE. Менеджер може додати відповідність без розробника. -
Агент Бітрікса (
CAgent) запускається раз на 30-60 хвилин, генерує файли у/upload/feeds/. При 1000 автомобілів — генерація за 5-15 секунд, XML ~2-4 MB. -
Валідація перед публікацією. Після генерації — перевірка XSD-схемою. Якщо фід невалідний — надсилання повідомлення менеджеру, старий фід не перезаписується.
Порівняння автомобілів
Порівняння — таблиця характеристик двох-чотирьох автомобілів поруч. Користувач додає машини кнопкою «Порівняти» з каталогу або картки. ID зберігаються в localStorage (неавторизовані) або в Highload-блоці UserCompare (авторизовані). Максимум — 4 автомобілі, більше втрачається наочність.
Компонент порівняння: CIBlockElement::GetList по масиву ID, завантаження всіх властивостей, рендер таблиці. Властивості з однаковими значеннями виділяються сірим, відмінності — контрастним кольором. Горизонтальний скрол на мобільних.
Калькулятор trade-in
Форма оцінки автомобіля клієнта. Вхідні дані: марка, модель, рік, пробіг, стан (відмінний / добрий / задовільний). На клієнті — JavaScript-формула: береться базова вартість з довідника (Highload-блок TradeInPrices з полями UF_BRAND, UF_MODEL, UF_YEAR, UF_BASE_PRICE), застосовуються коефіцієнти за пробіг і стан. Результат — орієнтовна вартість. Точна оцінка — після огляду на майданчику.
Кредитний калькулятор — ануїтетна формула на JavaScript: три повзунки (вартість автомобіля, перший внесок, термін), результат — щомісячний платіж. Ставки зберігаються у Highload-блоці «Банки-партнери». Для лізингу — окрема формула з залишковою вартістю.
Інтеграція з 1С та складський облік
Дилерський сайт без актуальних залишків — марна вітрина. Клієнт телефонує за оголошенням, а машина продана вчора. Синхронізація реалізується через:
CommerceML — штатний механізм обміну Бітрікса та 1С. Модуль sale підтримує імпорт каталогу через /bitrix/admin/1c_exchange.php. Проблема: CommerceML спроектований під товари з SKU, а не під автомобілі з 40 властивостями. VIN, пробіг, кількість власників — немає стандартних полів. Рішення — маппінг через OnBeforeCatalogImport1C або додатковий обробник, який парсить <ЗначенняРеквізиту> з XML і заповнює властивості інфоблоку.
REST API 1С — гнучкіший варіант. HTTP-сервіс на боці 1С віддає JSON з актуальним списком автомобілів. На боці Бітрікса — агент або webhook, який раз на 15-30 хвилин запитує оновлення і синхронізує: нові автомобілі створює, продані деактивує, змінені оновлює. Звірка по VIN як унікальному ключу.
360-огляд та візуальний контент
360-огляд екстер'єру — набір з 36-72 фотографій автомобіля, знятих по колу. На фронті — JavaScript-бібліотека (SpriteSpin, 360-image-viewer або кастомний скрипт на canvas), яка анімує перемикання кадрів при перетягуванні мишею. Фотографії зберігаються в окремій директорії /upload/cars/{ID}/360/, посилання — у властивості SPIN_360_URL.
Панорама салону — сферична фотографія, що відображається через Pannellum.js. Зберігається як URL у властивості INTERIOR_PANORAMA.
Запис на тест-драйв та сервіс
Форма запису на тест-драйв: вибір автомобіля (передзаповнюється, якщо користувач прийшов з картки), дата, час, ім'я, телефон. Дані надсилаються через bitrix:form.result.new або REST API Бітрікс24 (crm.lead.add з SOURCE_ID = "TEST_DRIVE", кастомне поле UF_CRM_CAR_ID). Менеджер отримує повідомлення в CRM, клієнт — SMS-підтвердження через модуль messageservice.
Запис на сервіс — аналогічна форма, але з вибором виду робіт (ТО, шиномонтаж, кузовний ремонт) та бажаною датою. Дані потрапляють у угоду Бітрікс24 з напрямком «Сервіс».
SEO та Schema.org для автомобілів
Кожна картка автомобіля — посадкова сторінка для запиту «купити BMW X5 2024 дизель». Шаблони SEO через налаштування інфоблоку:
- Title:
Купити #PROPERTY_BRAND# #PROPERTY_MODEL# #PROPERTY_YEAR# — #PROPERTY_CITY# | Дилер - Description:
#PROPERTY_BRAND# #PROPERTY_MODEL# #PROPERTY_YEAR#, #PROPERTY_ENGINE_TYPE#, #PROPERTY_TRANSMISSION#, пробіг #PROPERTY_MILEAGE# км
Мікророзмітка Schema.org Vehicle + Offer:
{
"@context": "https://schema.org",
"@type": "Vehicle",
"name": "BMW X5 xDrive30d",
"brand": {"@type": "Brand", "name": "BMW"},
"model": "X5",
"vehicleModelDate": "2024",
"mileageFromOdometer": {
"@type": "QuantitativeValue",
"value": "0",
"unitCode": "KMT"
},
"fuelType": "Diesel",
"vehicleTransmission": "Automatic",
"color": "Black",
"vehicleIdentificationNumber": "WBAJC51090B123456",
"image": ["https://site.ua/upload/cars/12345/photo1.jpg"],
"offers": {
"@type": "Offer",
"price": "2850000",
"priceCurrency": "UAH",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "AutoDealer",
"name": "Назва дилера"
}
}
}
Google розпізнає Vehicle і може показати картку в розширених результатах з фотографією, ціною, пробігом.
Етапи та терміни
- Аналітика, прототипування (1-2 тижні) — структура каталогу, дерево марок-моделей, прототипи Figma
- Дизайн (2-3 тижні) — каталог, картка автомобіля, фільтри, мобільна версія
- Розробка ядра (3-5 тижнів) — інфоблоки, Highload-довідники, каскадний фільтр, картка автомобіля
- Інтеграції (2-4 тижні) — XML-фіди, 1С-обмін, CRM, калькулятори
- Візуальний контент (1-2 тижні) — 360-огляд, панорами, галерея
- Тестування, SEO (1-2 тижні) — валідація фідів, Schema.org, навантажувальне тестування
- Запуск (3-5 днів) — деплой, імпорт каталогу, моніторинг фідів
| Масштаб | Терміни |
|---|---|
| Монобрендовий дилер, до 200 авто, базовий фільтр | 6-8 тижнів |
| Мультибрендовий дилер, 500-2000 авто, фіди + 1С | 10-14 тижнів |
| Дилерська мережа, 3000+ авто, мультисайтовість, CRM | 14-24 тижні |
Терміни не включають фотозйомку автомобілів та підготовку 360-контенту — це паралельний процес, який стартує на етапі розробки.







