Розробка калькулятора доставки на Vue.js для 1С-Бітрікс
Калькулятор доставки потрібен на картці товару, у кошику та на сторінці перед оформленням замовлення — щоб користувач знав вартість ще до того, як починає вводити дані. Стандартний Бітрікс показує варіанти доставки лише на кроці оформлення. Vue-калькулятор вирішує це через попередній розрахунок.
API розрахунку доставки у Бітрікс
Бітрікс розраховує доставку через \Bitrix\Sale\Delivery\Services\Manager. Для попереднього розрахунку створюємо «віртуальне» замовлення:
class DeliveryCalculatorController extends \Bitrix\Main\Engine\Controller
{
public function calculateAction(array $items, string $locationCode): array
{
// Створюємо тимчасовий об'єкт замовлення без збереження
$order = \Bitrix\Sale\Order::create(SITE_ID, null);
$basket = \Bitrix\Sale\Basket::create(SITE_ID);
foreach ($items as $item) {
$basketItem = $basket->createItem('catalog', $item['id']);
$basketItem->setFields([
'QUANTITY' => $item['qty'],
'CURRENCY' => 'RUB',
]);
}
$order->setBasket($basket);
// Встановлюємо адресу доставки
$shipmentCollection = $order->getShipmentCollection();
$shipment = $shipmentCollection->createItem();
$shipment->setField('DELIVERY_LOCATION', $locationCode);
// Отримуємо список доступних служб з цінами
$deliveries = \Bitrix\Sale\Delivery\Services\Manager::getRestrictedObjectsList($shipment);
$result = [];
foreach ($deliveries as $delivery) {
$calcResult = $delivery->calculate($shipment);
$result[] = [
'id' => $delivery->getId(),
'name' => $delivery->getName(),
'price' => $calcResult->isSuccess() ? $calcResult->getPrice() : null,
'days' => $calcResult->getPeriodDescription(),
];
}
return ['deliveries' => $result];
}
}
Компонент калькулятора
<script setup>
const props = defineProps(['productId', 'productWeight', 'productDimensions']);
const city = ref('');
const locationCode = ref('');
const deliveryOptions = ref([]);
const isLoading = ref(false);
// Автодоповнення міста через DaData або Bitrix API локацій
async function onCityInput(query) {
const locations = await locationApi.suggest(query);
// Користувач обирає — зберігаємо locationCode
}
async function calculate() {
if (!locationCode.value) return;
isLoading.value = true;
const result = await deliveryApi.calculate({
items: [{ id: props.productId, qty: 1 }],
locationCode: locationCode.value,
});
deliveryOptions.value = result.deliveries;
isLoading.value = false;
}
</script>
Визначення міста за замовчуванням
Бітрікс автоматично визначає місто користувача через \Bitrix\Sale\Location\LocationManager::getUserLocation() (за IP через GeoIP). Використовуйте це для попереднього заповнення:
$detectedLocation = \Bitrix\Sale\Location\LocationManager::getUserLocation();
echo '<div id="delivery-calc" data-location-code="' . $detectedLocation['CODE'] . '"
data-location-name="' . htmlspecialchars($detectedLocation['NAME']['RU']) . '"></div>';
Кешування розрахунків
Розрахунок доставки — потенційно повільна операція (зовнішні запити до API СДЕК, DPD). Кешуйте результати:
$cacheKey = md5(json_encode($items) . $locationCode);
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache(3600, $cacheKey, '/delivery-calc/')) {
return $cache->getVars();
}
// ... розрахунок ...
$cache->startDataCache();
$cache->endDataCache($result);
TTL — 1 година, тарифи змінюються рідко.
Приклад із практики
Магазин великогабаритних товарів (меблі): вартість доставки суттєво залежить від міста та габаритів товару. Користувачі додавали товар у кошик лише щоб дізнатися ціну доставки, а потім йшли. Vue-калькулятор прямо на картці товару з визначенням міста за IP: користувач одразу бачить «Доставка до Краснодара від 1 200 грн, 3–5 днів». Частота відмов на етапі checkout знизилася — дані клієнта.
Терміни виконання
| Варіант | Термін |
|---|---|
| Калькулятор із ручним введенням міста | від 3 до 5 робочих днів |
| З IP-геолокацією та автодоповненням | від 5 до 8 робочих днів |
| З інтеграцією API зовнішніх служб доставки | від 8 до 12 робочих днів |







