Розробка калькулятора доставки – ключове завдання для e-commerce. Покупець додає товари в кошик, переходить до оформлення і бачить несподівано високу вартість доставки. За даними досліджень, неочікувана вартість доставки — причина 60% покинутих кошиків. Калькулятор доставки, що попередньо показує вартість, вирішує цю проблему і підвищує конверсію на 15–30%. Реалізація такого калькулятора — нетривіальне завдання: потрібно врахувати об'ємну вагу, інтегруватися з API кількох служб доставки (СДЭК, Boxberry, Пошта Росії), забезпечити відмовостійкість і швидкість розрахунків. Запити до API займають 200–800 мс і часто платні, тому потрібне грамотне кешування та паралельна обробка. Ми розглянемо технічні деталі: від зберігання тарифів у базі до паралельних запитів і обробки помилок. Наведемо приклади коду на Laravel і React, розповімо про кешування та роботу з об'ємною вагою. Впровадження агрегатора окупається за 2–3 місяці, економлячи до 30% на доставці. При обороті 100 000 грн на місяць економія може сягати 25 000 грн щомісяця.
Наша команда має 5+ років досвіду в e-commerce розробці та реалізувала 20+ калькуляторів доставки. Ми надаємо гарантію на працездатність калькулятора протягом 3 місяців після запуску. Це дозволило накопичити типові рішення, що прискорюють впровадження. Звертайтеся — ми допоможемо підібрати оптимальну архітектуру під ваш бюджет.
Що рахує калькулятор доставки
Вартість доставки залежить від параметрів, які потрібно отримати з різних джерел:
- Адреса складу (звідки везуть) — може бути фіксованою або найближчим магазином.
- Адреса покупця (куди везуть) — до дверей чи до пункту видачі.
- Вага та габарити товарів у кошику (що везуть).
- Обраний спосіб доставки — кур'єр, ПВЗ, поштомат, Пошта Росії.
- Терміновість — стандарт або експрес.
Параметри товарів зберігаються в базі даних інтернет-магазину. Тарифи доставки — або у власних таблицях (для партнерських договорів з фіксованими цінами), або приходять у реальному часі через API служби доставки.
Локальні таблиці та API: два підходи до розрахунку
Локальні тарифні таблиці
Для простих випадків — коли є договір з фіксованими цінами або доставка власними силами — тарифи зберігаються локально:
CREATE TABLE shipping_zones ( id SERIAL PRIMARY KEY, name VARCHAR(100), regions TEXT[], base_price DECIMAL(10,2), price_per_kg DECIMAL(10,2), price_per_km DECIMAL(10,2), min_days INT, max_days INT ); CREATE TABLE shipping_methods ( id SERIAL PRIMARY KEY, zone_id INT REFERENCES shipping_zones(id), name VARCHAR(100), carrier VARCHAR(50), multiplier DECIMAL(4,2) DEFAULT 1.0, free_from DECIMAL(10,2) ); class LocalShippingCalculator { public function calculate(Cart $cart, Address $destination): Collection { $zone = $this->zoneDetector->detect($destination->city); $weight = $cart->totalWeight(); $orderTotal = $cart->total(); return ShippingMethod::where('zone_id', $zone->id)->get() ->map(function (ShippingMethod $method) use ($weight, $orderTotal, $zone) { $cost = $zone->base_price + ($weight * $zone->price_per_kg); $cost *= $method->multiplier; if ($method->free_from && $orderTotal >= $method->free_from) { $cost = 0; } return [ 'id' => $method->id, 'name' => $method->name, 'carrier' => $method->carrier, 'cost' => round($cost, 2), 'min_days' => $zone->min_days * $method->multiplier < 1 ? 1 : (int)($zone->min_days / $method->multiplier), 'max_days' => $zone->max_days, 'free' => $cost === 0.0, ]; }); } } API-розрахунок у реальному часі: приклад із СДЭК
Зазначимо: коли потрібні актуальні тарифи служби доставки, запит надсилається до їхнього API:
class CdekShippingCalculator { private string $baseUrl = 'https://api.cdek.ru/v2'; public function calculate( string $fromCity, string $toCity, float $weight, array $dimensions ): array { $token = $this->authenticate(); $response = Http::withToken($token) ->post("{$this->baseUrl}/calculator/tarifflist", [ 'from_location' => ['city' => $fromCity], 'to_location' => ['city' => $toCity], 'packages' => [[ 'weight' => (int)($weight * 1000), 'length' => $dimensions['length'], 'width' => $dimensions['width'], 'height' => $dimensions['height'], ]], ]); return collect($response->json('tariff_codes')) ->map(fn($t) => [ 'tariff_code' => $t['tariff_code'], 'tariff_name' => $t['tariff_name'], 'cost' => $t['delivery_sum'], 'min_days' => $t['period_min'], 'max_days' => $t['period_max'], ]) ->toArray(); } } Порівняння підходів
| Критерій | Локальні таблиці | API в реальному часі |
|---|---|---|
| Швидкість розрахунку | <10 мс | 200–800 мс |
| Актуальність тарифів | Ручне оновлення | Автоматично |
| Складність інтеграції | Низька | Середня |
| Вартість обслуговування | Низька | Середня (комісії API) |
Локальні таблиці швидші за API в 10–80 разів, але поступаються в гнучкості. Інтеграція з СДЭК у 2 рази швидше, ніж з Поштою Росії. Вибір залежить від обсягів і вимог до актуальності.
Як агрегувати кілька служб доставки?
Реальний калькулятор зазвичай показує варіанти від кількох служб одночасно. Запити надсилаються паралельно. Якщо один сервіс недоступний — показуємо інші. Покупець не бачить помилку, лише менше варіантів.
public function getShippingOptions(Cart $cart, Address $address): array { $weight = $cart->totalWeight(); $dimensions = $cart->boundingBox(); $results = collect([ 'cdek' => fn() => $this->cdek->calculate($address, $weight, $dimensions), 'boxberry' => fn() => $this->boxberry->calculate($address, $weight, $dimensions), 'pochta' => fn() => $this->russianPost->calculate($address, $weight, $dimensions), ])->map(function ($calculator, $carrier) { try { return $calculator(); } catch (\Exception $e) { logger()->warning("Shipping calculator error: $carrier", ['error' => $e->getMessage()]); return []; } })->flatten(1)->sortBy('cost')->values(); return $results->toArray(); } Нижче — порівняння популярних служб доставки для інтеграції.
| Служба | Швидкість доставки (дні) | Зони покриття | Складність API | Комісія |
|---|---|---|---|---|
| СДЭК | 1–5 | Міста РФ, СНД | Низька | За тарифами |
| Boxberry | 2–7 | Міста РФ, СНД | Середня | За тарифами |
| Пошта Росії | 3–14 | Всі регіони РФ | Висока | Низька |
Що таке об'ємна вага і як вона впливає на вартість?
Багато служб вважають оплачувану вагу як максимум із фактичної та об'ємної. Згідно з правилами СДЭК, оплачувана вага дорівнює максимуму з фактичної та об'ємної. Об'ємна вага — це розрахункова вага, заснована на габаритах. Для повітряної доставки коефіцієнт 6000 см³/кг, для морської — 1000 см³/кг. Якщо цього не врахувати, розцінки будуть занижені. Приклад: посилка вагою 2 кг з габаритами 50×40×30 см дає об'ємну вагу 60000/5000=12 кг — платити доведеться за 12 кг.
Оптимізація розрахунків через кешування
Запити до API служб доставки повільні (200–800 мс) і часто платні. Кешуємо за ключем із міста відправлення, міста призначення та ваги. Тарифи змінюються рідко, тому кеш на 30 хвилин — оптимальний. При оновленні тарифів інвалідуємо за патерном.
Інтерфейс калькулятора: реактивний компонент
На сторінці товару або кошика — компактний блок з полем введення міста та списком методів з цінами та термінами. Без перезавантаження сторінки:
const ShippingCalculator = () => { const [city, setCity] = useState(''); const [options, setOptions] = useState([]); const [loading, setLoading] = useState(false); const calculate = useMemo( () => debounce(async (cityValue) => { if (cityValue.length < 3) return; setLoading(true); try { const res = await fetch('/api/shipping/calculate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ city: cityValue, cart_id: cartId }), }); const data = await res.json(); setOptions(data.options); } finally { setLoading(false); } }, 600), [cartId] ); return ( <div className="shipping-calculator"> <input value={city} onChange={(e) => { setCity(e.target.value); calculate(e.target.value); }} placeholder="Введіть ваше місто" /> {loading && <Spinner />} {options.map((opt) => ( <ShippingOption key={opt.id} option={opt} /> ))} </div> ); }; Дебаунс на 600 мс — не стріляємо запитами після кожного символу.
Скільки часу займає розробка?
- Аналітика — збір вимог, визначення списку служб доставки, тарифних зон.
- Проектування — вибір стеку (Laravel/PHP + React/Next.js), проектування схеми бази.
- Реалізація — написання калькулятора, інтеграція з API, розробка UI-компонента.
- Тестування — перевірка 100+ сценаріїв (різні міста, ваги, помилки API).
- Деплой та моніторинг — налаштування кешування, алертів при збоях.
Орієнтовні терміни:
- Калькулятор з однією службою за фіксованими тарифами — 2–3 дні.
- З реальним API однієї служби — 3–5 днів (включаючи обробку помилок та кешування).
- Агрегатор на 3–5 служб з інтерфейсом вибору — 2–3 тижні.
Економія клієнтів на доставці після впровадження агрегатора становить у середньому 20–30%, а інвестиції окупаються за 2–3 місяці. При значному обороті економія може бути суттєвою. Зв'яжіться з нами для попередньої оцінки вашого проекту.
Як швидко окупається калькулятор?
Інвестиції окупаються за 2-3 місяці, а при великих обсягах – ще швидше.Що входить у результат
- Документація: опис тарифних схем, схема бази, інструкція з додавання нових служб.
- Доступи до панелі адміністратора для керування тарифами.
- Навчання співробітників: як змінювати тарифи, додавати зони.
- Технічна підтримка протягом місяця після запуску.
Отримайте консультацію інженера: ми допоможемо вибрати оптимальну архітектуру та реалізуємо калькулятор за 2–3 тижні.







