Розробка віджета вибору ПВЗ на карті на Vue.js для 1С-Бітрікс
Вибір пункту видачі замовлення на карті — один з найбільш конверсійно значущих елементів checkout. Користувач повинен бачити найближчі ПВЗ, вибрати зручний і отримати коректну вартість доставки. Реалізація вимагає інтеграції карт (Яндекс або Leaflet), API служби доставки та Бітрікс-модуля sale.
Джерела даних ПВЗ
Координати та атрибути ПВЗ надходять з API служби доставки:
-
СДЕК:
https://api.cdek.ru/v2/deliverypoints— список точок з координатами, режимом роботи, типом -
Boxberry:
https://api.boxberry.ru/json.php?token=...&method=ListPoints -
Пошта Росії: API
otpravka.pochta.ru— список ВПС - DPD, Ozon Rocket, Яндекс.Доставка — власні API
Всі ці дані кешуються на сервері (в b_cached_files або Redis), не запитуються напряму з клієнта — це приховує API-ключі та прискорює відповідь.
Архітектура віджета
PvzMapWidget.vue
├── MapContainer.vue — Яндекс.Карти або Leaflet
├── PvzList.vue — список ПВЗ поруч з картою (мобільний вигляд)
├── PvzMarker.vue — кастомна мітка з іконкою служби
├── PvzPopup.vue — попап з деталями (адреса, години, вартість)
└── DeliveryCostBadge.vue — вартість доставки до даного ПВЗ
Інтеграція з Яндекс.Картами
// Після завантаження ymaps
const map = new ymaps.Map('pvz-map', {
center: userCoords, // З геолокації або IP-геолокації
zoom: 12,
});
const clusterer = new ymaps.Clusterer({ preset: 'islands#greenClusterIcons' });
pvzPoints.forEach(pvz => {
const placemark = new ymaps.Placemark(
[pvz.latitude, pvz.longitude],
{ balloonContent: pvz.address },
{ preset: 'islands#greenDotIcon' }
);
placemark.events.add('click', () => selectPvz(pvz));
clusterer.add(placemark);
});
map.geoObjects.add(clusterer);
Vue керує станом (вибраний ПВЗ, фільтри за службами), карта — через ref та пряме API.
Визначення місцезнаходження користувача
Три джерела, використовуються послідовно:
-
Браузерна геолокація (
navigator.geolocation.getCurrentPosition) — найточніший, потребує дозволу -
IP-геолокація — через Бітрікс (
\Bitrix\Sale\Location\LocationManager::getUserLocation()) або зовнішній сервіс - Останній вибір — з localStorage/cookie
Інтеграція з checkout
При виборі ПВЗ — оновлюємо store:
function selectPvz(pvz) {
checkoutStore.setDeliveryPoint({
deliveryId: pvz.deliveryServiceId,
pvzCode: pvz.code,
address: pvz.address,
coords: [pvz.latitude, pvz.longitude],
});
// Перерахунок вартості доставки
checkoutStore.recalculateDelivery();
}
Бітрікс-доставка: \Bitrix\Sale\Delivery\Services\Manager::calculateDeliveryPrice() з передачею коду ПВЗ у поле додаткових даних доставки.
Приклад із практики
Маркетплейс з кількома службами доставки одночасно (СДЕК + Boxberry + Пошта Росії). На карті — три шари міток з перемиканням. Користувач бачить всі ПВЗ одночасно або фільтрує за службою. Головна складність: СДЕК віддає 20 000+ точок по Росії — завантажувати всі при відкритті не можна. Рішення: завантаження точок тільки у видимій області карти (map.getBounds()) при кожній зміні області перегляду (подія boundschange), з debounce 500 мс. Кеш точок у Pinia — вже завантажені області не перезапитуються.
Терміни виконання
| Варіант | Термін |
|---|---|
| ПВЗ однієї служби доставки, Яндекс.Карти | від 5 до 8 робочих днів |
| Кілька служб з фільтрацією | від 8 до 12 робочих днів |
| З геолокацією, кластеризацією та lazy-завантаженням | від 12 до 18 робочих днів |







