Ми часто стикаємося з ситуацією: на сайті інтернет-магазину сотні пунктів видачі, а стандартний компонент sale.order.ajax пропонує лише випадний список з адресами. Це незручно для користувача — він не бачить, де саме знаходяться ПВЗ відносно його адреси, а менеджеру підтримки доводиться пояснювати, як знайти потрібний пункт. Ми розробляємо віджет з картою, який вирішує цю проблему. У статті розповімо, як влаштована архітектура такого рішення, як зберігаються дані та як віджет вбудовується в checkout Бітрікс.
Віджет дозволяє користувачеві вибрати ПВЗ на карті з фільтрами за режимом роботи, типом пункту та відстанню. Він значно прискорює оформлення замовлення: за нашими вимірами, час вибору скорочується в 3–5 разів порівняно зі списком. До того ж знижується кількість помилок — користувач бачить актуальну інформацію про пункт (розклад, контакти, фотографії).
Як віджет прискорює оформлення замовлення?
При стандартному списку користувач змушений читати адреси та уявляти розташування. Карта дає візуальне уявлення, а кластеризація дозволяє працювати з тисячами точок без втрати продуктивності. Вибір ПВЗ зводиться до одного кліку. Інтеграція з розрахунком вартості доставки відбувається миттєво — віджет надсилає запит до обробника та показує ціну і термін поруч з адресою ще до підтвердження.
Де живе віджет в архітектурі Бітрікс
Віджет вбудовується в процес оформлення замовлення. Використовуємо подію OnBeforeSaleOrderFinalAction або шаблон компонента sale.checkout.v2 — залежно від того, який checkout використовується на сайті.
Віджет — це окремий JS-компонент, який:
- Завантажує список ПВЗ через AJAX-запит до обробника на сервері.
- Рендерить карту (Яндекс.Карти або Leaflet з OpenStreetMap).
- Розставляє мітки ПВЗ на карті.
- По кліку на мітку показує інформацію про ПВЗ.
- При підтвердженні вибору записує ПВЗ у властивість замовлення.
Зберігання даних про пункти видачі
Якщо ПВЗ надходять від служби доставки (СДЕК, Boxberry, Укрпошта) — дані синхронізуються періодично. Структура:
CREATE TABLE custom_pvz_points ( id SERIAL PRIMARY KEY, provider VARCHAR(50) NOT NULL, -- 'cdek', 'boxberry', 'pochta' external_id VARCHAR(100) NOT NULL, name VARCHAR(255) NOT NULL, address TEXT NOT NULL, city VARCHAR(100), lat DECIMAL(10,8) NOT NULL, lng DECIMAL(11,8) NOT NULL, schedule JSON, phone VARCHAR(50), is_active TINYINT DEFAULT 1, synced_at DATETIME, INDEX idx_city (city), INDEX idx_coords (lat, lng), UNIQUE KEY uk_provider_ext (provider, external_id) ); Синхронізація запускається через агент Бітрікс (\Bitrix\Main\Agent) раз на добу або за запитом з адміністративної панелі.
Серверний обробник (AJAX-endpoint)
Запити від віджета обробляються через /bitrix/services/main/ajax.php або local/ajax/pvz.php. Обробник приймає параметри: місто, координати центру карти, радіус, провайдер доставки.
// Отримуємо ПВЗ в радіусі N км від координат $lat = (float)$_REQUEST['lat']; $lng = (float)$_REQUEST['lng']; $radius = (int)($_REQUEST['radius'] ?? 10); // км // Формула Haversine в SQL $sql = " SELECT *, ( 6371 * ACOS( COS(RADIANS({$lat})) * COS(RADIANS(lat)) * COS(RADIANS(lng) - RADIANS({$lng})) + SIN(RADIANS({$lat})) * SIN(RADIANS(lat)) ) ) AS distance FROM custom_pvz_points WHERE is_active = 1 HAVING distance <= {$radius} ORDER BY distance LIMIT 100 "; Результат кешується через \Bitrix\Main\Data\Cache з ключем по місту та провайдеру. Список ПВЗ змінюється раз на добу — кеш на 12–24 години виправданий.
Фронтенд: інтеграція з Яндекс.Картами
// Ініціалізація карти ymaps.ready(function() { const map = new ymaps.Map('pvz-map', { center: [userLat, userLng], zoom: 12, controls: ['zoomControl', 'geolocationControl'] }); // Кластеризація міток при великій кількості ПВЗ const clusterer = new ymaps.Clusterer({ preset: 'islands#invertedDarkBlueClusterIcons', groupByCoordinates: false, }); points.forEach(pvz => { const placemark = new ymaps.Placemark( [pvz.lat, pvz.lng], { balloonContentHeader: pvz.name, balloonContentBody: `${pvz.address}<br>${pvz.schedule}`, hintContent: pvz.name, }, { preset: 'islands#darkBlueIcon' } ); placemark.events.add('click', function() { selectPvz(pvz); }); clusterer.add(placemark); }); map.geoObjects.add(clusterer); }); При виборі ПВЗ через selectPvz() заповнюються приховані поля форми замовлення — адреса доставки та зовнішній ID пункту. Ці дані передаються у властивість замовлення DELIVERY_LOCATION або кастомну властивість UF_PVZ_ID.
Геолокація користувача
При відкритті віджета запитуємо координати користувача через navigator.geolocation.getCurrentPosition(). Якщо дозвіл не надано — визначаємо місто через IP (сервіс ip-api.com або вбудований геолокатор Бітрікс \Bitrix\Main\Web\IpTools). Карта центрується на знайденому місті.
Інтеграція з розрахунком вартості доставки
Після вибору ПВЗ віджет оновлює вартість доставки. Запит до обробника, який викликає \Bitrix\Sale\Delivery\Services\Manager::calculateDelivery() з обраним пунктом — повертає вартість та термін. Дані показуються поруч з адресою ПВЗ ще до підтвердження.
Синхронізація з провайдерами
| Провайдер | API / метод | Частота синхронізації |
|---|---|---|
| СДЕК | GET /v2/deliverypoints |
1 раз на добу |
| Boxberry | ListPoints (SOAP/REST) |
1 раз на добу |
| Укрпошта | Tariff.offices |
1 раз на тиждень |
| DPD | getParcelShops |
1 раз на добу |
| Яндекс.Доставка | GET /pickup-points |
1 раз на добу |
Агент Бітрікс запускає синхронізацію, оновлює custom_pvz_points через INSERT ... ON DUPLICATE KEY UPDATE, знімає прапорець is_active у зниклих пунктів.
Що входить в роботу (під ключ)
- Проектування схеми даних та вибір картографічного API
- Розробка серверної частини: зберігання ПВЗ, AJAX-обробник, агенти синхронізації
- Розробка фронтенду: карта, мітки, кластеризація, фільтри
- Інтеграція в checkout: передача обраного ПВЗ в замовлення, оновлення вартості доставки
- Документація та навчання: передача вихідних кодів, інструкція з додавання нових провайдерів
- Технічна підтримка протягом місяця після здачі
Ми гарантуємо, що віджет працюватиме на всіх сучасних браузерах та мобільних пристроях. Всі роботи ведуться за договором з фіксованим кошторисом. Щоб оцінити проект під вашу задачу, зв'яжіться з нами — ми проаналізуємо поточний checkout та кількість ПВЗ. Вартість — від $500, термін — від 2 тижнів. Маємо 5+ років досвіду в інтеграціях з Бітрікс, реалізовано 30+ подібних проектів.
Терміни
| Етап | Термін |
|---|---|
| Проектування схеми даних, вибір картографічного API | 1–2 дні |
| Серверна частина: зберігання, AJAX-обробник, синхронізація | 3–5 днів |
| Фронтенд: карта, мітки, кластеризація, вибір ПВЗ | 4–6 днів |
| Інтеграція в checkout (передача в замовлення) | 2–3 дні |
| Розрахунок вартості при виборі ПВЗ | 1–2 дні |
| Тестування + мобільна адаптація | 2–3 дні |
Разом: 2–3 тижні. Якщо потрібна інтеграція з кількома провайдерами доставки одночасно — плюс 3–5 днів на кожного.
Документація Яндекс.Карт: Яндекс.Карти API. Докладніше про подію OnBeforeSaleOrderFinalAction — в офіційному курсі 1С-Бітрікс.







