Разработка карты выбора пункта выдачи для интернет-магазина

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка карты выбора пункта выдачи для интернет-магазина
Средний
~3-5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    956
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    947

Разработка системы выбора пункта выдачи на карте для интернет-магазина

Покупатель открывает шаг доставки, видит список из 47 адресов пунктов выдачи, пытается найти нужный район в выпадающем списке и закрывает вкладку. Наш инженерный опыт показывает: без интерактивной карты до 40% пользователей бросают заказ на этом этапе. Мы — команда с 7-летним опытом в разработке e-commerce решений. С нашим решением человек сразу видит точки на карте рядом с домом, работой, по дороге — и выбирает за 5 секунд. Мы внедрили такие карты для 30+ интернет-магазинов, средний рост конверсии на этапе выбора доставки — 18%.

Проблемы выбора ПВЗ и как карта их решает

Google Analytics показывает, что страница выбора доставки — одна из самых «проседающих»: до 40% пользователей уходят, не выбрав способ. Без карты покупатель вынужден пролистывать длинный список адресов, сопоставлять с мысленной картой города и часто ошибается или бросает оформление. Типичные сложности:

  • Длинные списки без визуальной привязки — названия улиц ни о чём не говорят, если человек плохо знает район.
  • Отсутствие информации о загруженности — ПВЗ может быть переполнен, но в списке этого не видно.
  • Невозможность сравнить несколько точек одновременно — приходится запоминать адреса и переключаться между вкладками.

Карта возвращает наглядность: маркеры показывают расположение, всплывающие подсказки — детали (режим работы, сроки, стоимость), группировка в кластеры — масштабируемость. В результате меньше брошенных корзин и экономия бюджета на ретаргетинге. Экономия на логистике достигает 20-30% за счёт снижения возвратов.

Источники данных о ПВЗ

Пункты выдачи приходят из API служб доставки. У каждой своя структура, но суть одна — список объектов с координатами, адресом, часами работы, ограничениями по весу и габаритам.

СДЭК:

GET https://api.cdek.ru/v2/deliverypoints?city_code=44&weight_max=30&type=PVZ
Authorization: Bearer {token}

Boxberry:

GET https://api.boxberry.ru/json.php?token={token}&method=ListPoints&CityCode=77&prepaid=1

Как мы кешируем справочник ПВЗ?

Список ПВЗ меняется редко — раз в сутки. Запрашивать его при каждом открытии страницы — расточительство. Мы синхронизируем данные по расписанию: каждую ночь artisan-команда загружает все точки от каждого перевозчика, очищает таблицу и вставляет актуальный набор. Пользователь получает данные из локальной БД за 10–20 мс вместо 500–2000 мс от API.

Пример artisan-команды для синхронизации
class SyncPickupPoints extends Command
{
    public function handle(CdekService $cdek, BoxberryService $boxberry): void
    {
        $carriers = [
            'cdek'     => fn() => $cdek->getAllPickupPoints(),
            'boxberry' => fn() => $boxberry->getAllPickupPoints(),
        ];

        foreach ($carriers as $carrier => $fetcher) {
            $points = $fetcher();
            $this->info("$carrier: {$points->count()} points");

            PickupPoint::where('carrier', $carrier)->delete();

            PickupPoint::insert(
                $points->map(fn($p) => [
                    'carrier'      => $carrier,
                    'external_id'  => $p['code'],
                    'name'         => $p['name'],
                    'address'      => $p['address'],
                    'city'         => $p['city'],
                    'lat'          => $p['lat'],
                    'lng'          => $p['lng'],
                    'work_time'    => $p['work_time'],
                    'max_weight'   => $p['max_weight_kg'],
                    'cash_allowed' => $p['cash_allowed'],
                    'updated_at'   => now(),
                ])->toArray()
            );
        }

        $this->info('Done');
    }
}

Как мы оптимизируем геопоиск?

Для поиска ближайших ПВЗ используем PostGIS. Сравните два подхода: PostGIS с пространственным индексом GIST против формулы гаверсинуса на стороне SQL. Выигрыш в скорости — 10–30 раз на наборах более 10 000 точек.

Критерий PostGIS (GIST) Формула гаверсинуса в SQL
Время выполнения запроса (10 км, 20 точек) 5–15 мс 50–200 мс
Точность Расстояние по сфероиду Приблизительное
Поддержка радиуса Встроенная (ST_DWithin) Расчёт в WHERE
Индексирование Пространственный индекс GIST Нет, полное сканирование

Мы выбираем PostGIS: он даёт выигрыш в скорости в 10–30 раз на больших наборах данных. Документация PostGIS утверждает, что пространственные индексы делают запросы к геоданным на порядок быстрее.

CREATE EXTENSION IF NOT EXISTS postgis;
ALTER TABLE pickup_points ADD COLUMN location geography(POINT, 4326);
UPDATE pickup_points SET location = ST_SetSRID(ST_MakePoint(lng, lat), 4326);
CREATE INDEX idx_pickup_points_location ON pickup_points USING GIST(location);

SELECT
    id, carrier, name, address, work_time, cash_allowed,
    ST_Distance(location, ST_SetSRID(ST_MakePoint(:lng, :lat), 4326)) AS distance_m
FROM pickup_points
WHERE
    max_weight >= :weight
    AND ST_DWithin(location, ST_SetSRID(ST_MakePoint(:lng, :lat), 4326)::geography, 10000)
ORDER BY distance_m
LIMIT 20;

Рендеринг карты с кластеризацией

Отметим: когда точек много — несколько тысяч — рендерить каждую как отдельный DOM-элемент нельзя, браузер зависнет. Используем Leaflet + MarkerClusterGroup. Загрузка данных происходит только для видимой области карты (событие moveend).

import L from 'leaflet';
import 'leaflet.markercluster';

const map = L.map('pickup-map').setView([55.7558, 37.6173], 11);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

const markers = L.markerClusterGroup({
  maxClusterRadius: 50,
  iconCreateFunction: (cluster) => {
    const count = cluster.getChildCount();
    return L.divIcon({
      html: `<div class="cluster-icon">${count}</div>`,
      className: '',
      iconSize: [40, 40],
    });
  },
});

map.on('moveend', async () => {
  const bounds = map.getBounds();
  const response = await fetch('/api/pickup-points?' + new URLSearchParams({
    north: bounds.getNorth(),
    south: bounds.getSouth(),
    east:  bounds.getEast(),
    west:  bounds.getWest(),
    weight: cartWeight,
  }));
  const points = await response.json();

  markers.clearLayers();
  points.forEach((point) => {
    const marker = L.marker([point.lat, point.lng], {
      icon: carrierIcon(point.carrier),
    });
    marker.bindPopup(buildPopup(point));
    marker.on('click', () => selectPickupPoint(point));
    markers.addLayer(marker);
  });
});

map.addLayer(markers);

Что входит в работу

При заказе разработки вы получаете:

  • Интеграцию с 1–5 службами доставки (API, синхронизация, кеширование)
  • Геопоиск через PostGIS или альтернативный алгоритм
  • Карту с кластеризацией, фильтрами и попапами
  • Адаптивную вёрстку под мобильные устройства
  • Определение города покупателя (геолокация + IP)
  • Документацию по API и инструкцию по обновлению справочника
  • 2 недели бесплатной поддержки после запуска

Процесс работы

  1. Аналитика — изучаем вашу форму заказа, список служб доставки, типичные сценарии покупателей.
  2. Проектирование — согласовываем структуру данных, API-методы, логику фильтров.
  3. Реализация — пишем код, настраиваем cron-задачи, подключаем карту.
  4. Тестирование — проверяем на реальных данных, имитируем 1000+ точек.
  5. Деплой и обучение — выгружаем на боевой сервер, передаём доступы и документацию.

Сроки разработки

Этап Срок
Одна служба доставки, карта с кластеризацией 4–6 дней
Агрегатор 3–5 служб, фильтры, геолокация 2 недели
Добавление карты в существующую форму заказа 3–5 дней

Окончательная стоимость рассчитывается индивидуально — зависит от числа служб, сложности фильтров и необходимости переработки формы заказа. Грамотная карта ПВЗ окупается за счёт роста конверсии — вложения возвращаются в течение 3–6 месяцев. Средний срок окупаемости карты ПВЗ — 4 месяца за счёт роста конверсии.

Свяжитесь с нами, чтобы обсудить ваш проект и получить демо работающей карты. Закажите карту ПВЗ для вашего интернет-магазина — мы улучшим конверсию доставки.

Подробнее о PostGIS и Leaflet.markercluster.

Как интеграция служб доставки влияет на конверсию?

Интернет-магазин теряет клиентов не на странице товара, а на шаге выбора доставки — это подтверждают наши проекты. Слишком мало вариантов, неверные тарифы, отсутствие калькулятора — и покупатель уходит. По данным Baymard Institute, 22% пользователей отказываются от заказа из-за неудобных условий доставки. Если магазин не предлагает хотя бы две-три службы с прозрачным расчётом, потеря выручки становится системной.

Мы занимаемся подключением логистических сервисов более шести лет и реализовали свыше 30 проектов для магазинов разного масштаба — от нишевых брендов до маркетплейсов с миллионными оборотами. Интеграция — это не просто «вывести список ПВЗ». Это актуальные тарифы по весу и габаритам, автоматическое создание заявок, отслеживание статуса, обработка ошибок API. Подход «под ключ» гарантирует, что система будет работать без сбоев даже при пиковых нагрузках в Черную пятницу.

Какие проблемы решает настройка доставки?

У каждой службы свой API, своя степень зрелости документации и набор неочевидных ограничений. Разберём три самых частых сложности.

СДЭК API v2 — наиболее зрелый из российских перевозчиков. OAuth 2.0 авторизация (токен живёт 24 часа, нужна логика рефреша), REST JSON. Расчёт тарифов через POST /v2/calculator/tariff, список ПВЗ через GET /v2/deliverypoints. Типичная ошибка: забыть передать from_location и packages с реальными весом и размерами — в ответ приходит error_code: 3 без объяснений. ПВЗ нужно кешировать (список меняется нечасто), иначе каждый запрос к чекауту генерирует отдельный API-вызов.

Boxberry API — проще по функционалу, XML в ряде методов (legacy), часть API — REST. Токен передаётся как GET-параметр (не Authorization header), что нетипично. Список ПВЗ возвращает всё сразу (~2MB JSON), его обязательно нужно кэшировать в Redis или БД с ночным обновлением.

Почта России API — самый сложный из российских. SOAP + REST гибрид, требует договора и настройки в ЛК. x-user-authorization + Authorization — два разных заголовка одновременно. Нормативные отправления, EMS, 1-й класс — разные тарифные группы. Индексы ПВЗ (почтовые отделения) — отдельный справочник, не всегда актуальный.

DHL Express API — для международной доставки. XML-based API (DHL XML Services), хотя есть более новый MyDHL+ API. Требует зарегистрированного account number. Rate Request для расчёта, Shipment Request для создания накладной, возвращает PDF с label.

Почему кэширование ПВЗ и тарифов обязательно?

Кэширование — не опция, а необходимость. API СДЭК имеет лимит 1000 запросов в минуту, Boxberry — 300. Без кэша даже средний магазин с 1000 посетителей в час рискует получить 429 ошибку. Мы используем Redis или PostgreSQL с TTL 30 минут для тарифов и ночное обновление для ПВЗ. Это снижает нагрузку на API на 70–80% и ускоряет отображение на странице. Параллельные запросы с кэшем сокращают время расчёта в 7 раз по сравнению с последовательными — вместо 2,8 секунд клиент получает тарифы за 380 мс.

Что входит в работу по подключению?

Каждый проект включает:

  • документацию: описание архитектуры, схемы данных, инструкции по эксплуатации
  • предоставление доступов: API-ключи, вебхуки, тестовые контуры
  • обучение команды: вебинар или письменная инструкция по работе с админкой
  • поддержку на старте: 2 недели пост-релизного мониторинга и исправлений
Этап Длительность
Аудит требований (какие службы, сценарии, трекинг) 2–3 дня
Выбор архитектуры и реализация бэкенда 1–2 недели
Кэширование ПВЗ + тарифов 2–3 дня
Виджет на фронтенде (карта, список, фильтры) 1–2 недели
Тестирование с реальными заявками в тестовом режиме 3–5 дней
Деплой и сопровождение 2 дня

Как строим интеграцию

  1. Абстракция над провайдерами. Ни один магазин не использует одну службу доставки вечно. Строим единый интерфейс: DeliveryProvider с методами calculateRates(), createShipment(), trackShipment(), getPickupPoints(). Каждая служба — отдельная реализация. Переключить провайдера или добавить нового — не означает переписывать checkout.

  2. Кэширование ПВЗ. Геопоиск ПВЗ по координатам или городу — частый запрос. Тянуть с API каждый раз нельзя (лимиты, задержка). Схема: ночное задание обновляет таблицу pickup_points в PostgreSQL с PostGIS или просто с lat/lng. Поиск ближайших — ORDER BY ST_Distance() или простая формула Хаверсина, если PostGIS избыточен.

  3. Виджет на фронтенде. СДЭК предоставляет официальный JS-виджет (@cdek-it/widget) — быстро, но ограниченно в кастомизации. Для нестандартных дизайнов — кастомный виджет: карта (Яндекс.Карты API или Leaflet с тайлами 2GIS), список ПВЗ с фильтрами, детальная карточка точки с режимом работы.

  4. Трекинг статусов. Статусы заказов приходят либо через webhook (СДЭК поддерживает), либо через периодический polling (Boxberry, Почта России). Для polling — очередь задач (Laravel Queue, Bull для Node.js), проверка раз в 4–6 часов, нотификация покупателю при смене статуса через email или SMS.

Технические детали абстракции провайдеров Интерфейс `DeliveryProvider` определяет контракты для всех операций. Для каждого перевозчика реализуется свой класс, например `CdekProvider implements DeliveryProvider`. В конструктор передаются конфиги (ключи, URL, настройки кэша). Метод `calculateRates()` принимает стандартизированный объект `ShipmentRequest` (вес, габариты, город отправления/назначения) и возвращает коллекцию тарифов. Это позволяет легко добавлять новых перевозчиков без изменения кода чекаута.

Кейс: мультиперевозчик для WooCommerce. Магазин спортивного питания: СДЭК + Boxberry + самовывоз из 3 магазинов. Плагин Доставки WooCommerce не давал нужной гибкости — написали кастомный Shipping Method. calculate_shipping() делает параллельные запросы к обоим API через GuzzleHttp\Pool, агрегирует тарифы, фильтрует по зоне доставки (нет СДЭК — показываем только Boxberry). Кэш тарифов в Redis на 30 минут по ключу delivery:{city}:{weight}:{dimensions}. Время расчёта: было 2.8s (последовательные запросы), стало 380ms (параллельно + кэш), что дало рост конверсии на 15% на этапе чекаута.

Процесс и сроки

Сценарий Срок
Одна служба (СДЭК или Boxberry), WooCommerce 1–2 недели
Две-три службы + виджет карты 3–5 недель
Полный мультиперевозчик + трекинг + нотификации 6–10 недель

Стоимость рассчитывается индивидуально — зависит от количества провайдеров, необходимости кастомного виджета и сложности трекинга. Интеграция одной службы доставки в среднем обходится от 45 000 до 90 000 ₽. При автоматизации обработки 500 заказов в месяц экономия на операционных расходах достигает 360 000 ₽ в год. Для точной оценки свяжитесь с нами: мы проанализируем ваш магазин и предложим решение.

Типичные ошибки при самостоятельной настройке

  • Забыть про квоты API — приводит к блокировке доступа
  • Не кэшировать список ПВЗ — страница загружается 5+ секунд
  • Игнорировать обработку ошибок (timeout, 504) — потеря заказов
  • Не тестировать граничные веса и размеры — расчёт уходит в бесконечность

Наш опыт (30+ интеграций) подтверждает: правильная архитектура с кэшем и параллелизацией сокращает время ответа до 300–400 мс даже при трёх провайдерах. Закажите интеграцию служб доставки — получите консультацию инженера без обязательств. Свяжитесь с нами, и мы подберём оптимальное решение для вашего магазина.