Разработка калькулятора доставки на 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 или Битрикс-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 рабочих дней |







