Реалізація власної кур'єрської доставки на сайті
Власна кур'єрська служба — логічний крок для магазинів з великим обсягом доставок на обмеженій території. Коли досягається поріг близько 50–100 доставок на день, витрати на власних кур'єрів виявляються нижчими, ніж комісії зовнішніх служб. Система управління кур'єрами — це окремий продукт у межах платформи з мобільним додатком для кур'єра, диспетчерською панеллю та відстеженням у реальному часі.
Архітектура системи
Система складається з трьох взаємопов'язаних компонентів:
Бекенд: REST API + WebSocket-сервер для реалтайм-координат Диспетчерська: веб-інтерфейс для управління кур'єрами та маршрутами Мобільний додаток кур'єра: React Native або PWA для прийому завдань та відправлення GPS-координат
Модель даних
couriers (
id, user_id, name, phone, vehicle_type,
status: offline | available | busy | on_break,
current_lat, current_lng, last_seen_at,
zone_ids (jsonb) -- зони доставки, за які відповідає кур'єр
)
delivery_tasks (
id, order_id, courier_id (nullable),
status: pending | assigned | picked_up | in_transit | delivered | failed,
pickup_address, delivery_address,
scheduled_at, picked_up_at, delivered_at,
proof_photo_url, -- фото при вручені
recipient_signature_url, -- підпис одержувача
failure_reason
)
courier_routes (
id, courier_id, date,
task_ids (jsonb, ordered), -- послідовність доставок
total_distance_km, estimated_duration_min
)
Розподіл замовлень за кур'єрами
Ручне призначення — диспетчер перетягує замовлення на кур'єра на карті. Підходить для невеликих обсягів.
Автоматична маршрутизація — алгоритм Vehicle Routing Problem (VRP). Для невеликих обсягів підходить жадний алгоритм (найближчий вільний кур'єр до пункту відправлення). Для серйозної оптимізації — бібліотеки типу Google OR-Tools або сервіси типу Route4Me API, OptimoRoute.
# Проста евристика: призначити найближчого вільного кур'єра
def assign_courier(task):
available_couriers = Courier.objects.filter(status='available')
nearest = min(available_couriers,
key=lambda c: haversine(c.location, task.pickup_address))
task.assign(nearest)
Мобільний додаток кур'єра
Основні екрани:
- Список завдань — поточний маршрут, наступна точка
-
Навігація — інтеграція з Яндекс.Навігатором через deep link:
yandexnavi://map_search?text={address} - Підтвердження доставки — фото вручення, підпис або код підтвердження з SMS покупцеві
- Недоставлено — вибір причини: не відкрили двері, перенесення на інший час, відмова
GPS-координати відправляються на сервер кожні 30 секунд через WebSocket або MQTT. При втраті інтернету — буферизуються та відправляються при відновленні.
// Відправлення координат через WebSocket
const ws = new WebSocket(`wss://api.example.com/couriers/${courierId}/location`);
navigator.geolocation.watchPosition((position) => {
ws.send(JSON.stringify({
lat: position.coords.latitude,
lng: position.coords.longitude,
accuracy: position.coords.accuracy,
timestamp: Date.now()
}));
}, null, {enableHighAccuracy: true, maximumAge: 30000});
Відстеження для покупця
Покупець отримує SMS/push із посиланням на сторінку відстеження. На сторінці — карта з відображенням кур'єра в реальному часі та прогнозуваний час прибуття. ETA перераховується кожні 2 хвилини на основі поточних координат кур'єра та відстані до пункту доставки.
Диспетчерська панель
- Карта з кур'єрами в реальному часі (Яндекс.Карти або Leaflet)
- Список нерозподілених замовлень
- Drag-and-drop призначення кур'єрів
- Черга завдань кожного кур'єра з можливістю перестановки
- Моніторинг: кур'єр не рухається 20 хвилин → сигнал диспетчеру
- Історія маршрутів та ефективність за день
Зони доставки
Географічні зони обмежують район, де працює кур'єр. Зони малюються як багатокутники на карті та зберігаються в PostgreSQL з розширенням PostGIS:
delivery_zones (
id, name, courier_ids (jsonb),
polygon geometry(Polygon, 4326),
min_order_amount, delivery_price, free_delivery_from
)
Запит для визначення, в якій зоні знаходиться адреса:
SELECT * FROM delivery_zones
WHERE ST_Contains(polygon, ST_SetSRID(ST_MakePoint(lng, lat), 4326));
Робота з невдалими доставками
Кур'єр не застав одержувача — встановлюється статус failed з причиною. Автоматично планується повторна доставка на наступний день або покупець отримує сповіщення з можливістю вибрати новий час.
Термін розробки: 8–12 тижнів для повної системи: API, диспетчерської панелі та мобільного додатка кур'єра.







