Pickup Point Selection Map Widget Development with Vue.js for 1C-Bitrix
Selecting a pickup point on a map is one of the most conversion-critical elements of checkout. The user must see nearby pickup points, choose a convenient one, and get the correct delivery cost. The implementation requires integration with a mapping library (Yandex Maps or Leaflet), a delivery service API, and the Bitrix sale module.
Pickup Point Data Sources
Pickup point coordinates and attributes come from the delivery service API:
-
CDEK:
https://api.cdek.ru/v2/deliverypoints— list of points with coordinates, working hours, type -
Boxberry:
https://api.boxberry.ru/json.php?token=...&method=ListPoints -
Russian Post:
otpravka.pochta.ruAPI — list of post offices - DPD, Ozon Rocket, Yandex Delivery — their own APIs
All this data is cached on the server (in b_cached_files or Redis), not queried directly from the client — this hides API keys and speeds up the response.
Widget Architecture
PvzMapWidget.vue
├── MapContainer.vue — Yandex Maps or Leaflet
├── PvzList.vue — list of pickup points beside the map (mobile view)
├── PvzMarker.vue — custom marker with delivery service icon
├── PvzPopup.vue — popup with details (address, hours, cost)
└── DeliveryCostBadge.vue — delivery cost to the selected point
Integration with Yandex Maps
// After loading ymaps
const map = new ymaps.Map('pvz-map', {
center: userCoords, // From geolocation or IP geolocation
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 manages state (selected pickup point, filters by service), the map — via ref and direct API calls.
Determining the User's Location
Three sources, used in sequence:
-
Browser geolocation (
navigator.geolocation.getCurrentPosition) — most accurate, requires permission -
IP geolocation — via Bitrix (
\Bitrix\Sale\Location\LocationManager::getUserLocation()) or an external service - Last selection — from localStorage/cookie
Checkout Integration
When a pickup point is selected — update the store:
function selectPvz(pvz) {
checkoutStore.setDeliveryPoint({
deliveryId: pvz.deliveryServiceId,
pvzCode: pvz.code,
address: pvz.address,
coords: [pvz.latitude, pvz.longitude],
});
// Recalculate delivery cost
checkoutStore.recalculateDelivery();
}
Bitrix delivery: \Bitrix\Sale\Delivery\Services\Manager::calculateDeliveryPrice() with the pickup point code passed in the delivery extra data field.
Real-World Case
A marketplace with multiple delivery services simultaneously (CDEK + Boxberry + Russian Post). Three marker layers on the map with toggle switching. The user sees all pickup points at once or filters by service. The main challenge: CDEK returns 20,000+ points across Russia — loading all of them on open is not viable. Solution: loading points only within the visible map area (map.getBounds()) on every area change (the boundschange event), with a 500 ms debounce. A point cache in Pinia — already-loaded areas are not re-fetched.
Delivery Timelines
| Option | Timeline |
|---|---|
| Single delivery service pickup points, Yandex Maps | 5 to 8 business days |
| Multiple services with filtering | 8 to 12 business days |
| With geolocation, clustering, and lazy loading | 12 to 18 business days |







