Мы часто сталкиваемся с ситуацией: на сайте интернет-магазина сотни пунктов выдачи, а стандартный компонент 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 и количество ПВЗ.
Сроки
| Этап | Срок |
|---|---|
| Проектирование схемы данных, выбор картографического API | 1–2 дня |
| Серверная часть: хранение, AJAX-обработчик, синхронизация | 3–5 дней |
| Фронтенд: карта, метки, кластеризация, выбор ПВЗ | 4–6 дней |
| Интеграция в checkout (передача в заказ) | 2–3 дня |
| Расчёт стоимости при выборе ПВЗ | 1–2 дня |
| Тестирование + мобильная адаптация | 2–3 дня |
Итого: 2–3 недели. Если нужна интеграция с несколькими провайдерами доставки одновременно — плюс 3–5 дней на каждого.
Документация Яндекс.Карт: Яндекс.Карты API. Подробнее о событии OnBeforeSaleOrderFinalAction — в официальном курсе 1С-Битрикс.







