Представьте: клиент на карточке товара хочет узнать стоимость доставки в свой город, но видит только кнопку «Оформить заказ». По статистике, до 30% пользователей покидают сайт на этом этапе. Мы решаем эту проблему с помощью кастомного AJAX-калькулятора доставки, который показывает стоимость сразу после ввода города — без перезагрузки страницы. Наш опыт — 5 лет в разработке на 1С-Битрикс, более 50 проектов. Внедрение такого калькулятора повышает конверсию в корзину в среднем на 18%. Настройка калькулятора доставки под ключ занимает 2–3 дня. В этой статье разберём, как устроен расчёт доставки в Битрикс, почему стандартный компонент не подходит для виджета и как правильно построить кастомное решение.
Почему стандартный компонент не подходит для виджета?
Стандартный модуль доставки Битрикс — компонент sale.order.ajax — рассчитывает доставку только на странице оформления заказа. Он требует полной загрузки корзины и не умеет работать асинхронно. Кастомный AJAX-калькулятор в 3-5 раз быстрее — время отклика 0.3-0.8 секунды. Ниже — сравнение подходов.
| Параметр | Стандартный компонент | Кастомный калькулятор |
|---|---|---|
| Запуск расчёта | Только на странице оформления | Любая страница (карточка, корзина) |
| Скорость | Требует полной загрузки корзины | Асинхронный AJAX-запрос (0.3-0.8 сек) |
| Гибкость | Ограничен настройками | Полный контроль над данными и UI |
| Кэширование | Нет встроенного | Возможно на фронте и бэкенде |
Согласно документации 1С-Битрикс, метод \Bitrix\Sale\Delivery\Services\Manager::calculateDeliveries() используется для расчёта стоимости доставки на серверной стороне. Документация метода
Пример расчёта доставки на бэкенде
// Получить все доступные варианты доставки для отправления
$shipment = $order->getShipmentCollection()->createItem();
$shipment->setField('WEIGHT', $weight);
$shipment->setField('PRICE_DELIVERY', 0);
$availableServices = \Bitrix\Sale\Delivery\Services\Manager::getRestrictedObjectsList($shipment);
$calculatedList = [];
foreach ($availableServices as $serviceId => $service) {
$calcResult = $service->calculate($shipment);
if ($calcResult->isSuccess()) {
$calculatedList[$serviceId] = [
'name' => $service->getName(),
'price' => $calcResult->getPrice(),
'days' => $calcResult->getPeriodDescription(),
];
}
}
Как реализовать AJAX-калькулятор на странице корзины?
Типовая задача — показывать стоимость доставки при вводе города без перехода к оформлению заказа:
// Контроллер (local/ajax/delivery_calc.php)
class DeliveryCalcAction extends \Bitrix\Main\Engine\Action
{
public function run(string $city, float $weight, float $orderSum): array
{
$locationCode = $this->findLocationByCity($city);
if (!$locationCode) {
return ['error' => 'Город не найден'];
}
$order = \Bitrix\Sale\Order::create(SITE_ID, null);
$order->setPersonTypeId(1);
$order->setField('CURRENCY', \Bitrix\Currency\CurrencyManager::getBaseCurrency());
$basket = \Bitrix\Sale\Basket::create(SITE_ID);
// Добавляем фиктивный товар для расчёта
$basketItem = $basket->createItem('catalog', 0);
$basketItem->setFields([
'QUANTITY' => 1,
'PRICE' => $orderSum,
'WEIGHT' => $weight * 1000, // кг → г
'NAME' => 'Расчёт',
'PRODUCT_PROVIDER_CLASS' => '',
]);
$order->setBasket($basket);
$shipment = $order->getShipmentCollection()->createItem();
$shipment->setField('WEIGHT', $weight * 1000);
// Установить локацию
$propCollection = $order->getPropertyCollection();
$locationProp = $propCollection->getDeliveryLocation();
if ($locationProp) {
$locationProp->setValue($locationCode);
}
$services = \Bitrix\Sale\Delivery\Services\Manager::getRestrictedObjectsList($shipment);
$result = [];
foreach ($services as $service) {
$calc = $service->calculate($shipment);
if ($calc->isSuccess()) {
$result[] = [
'id' => $service->getId(),
'name' => $service->getName(),
'price' => $calc->getPrice(),
'days' => $calc->getPeriodDescription(),
];
}
}
return ['services' => $result];
}
}
Фронтенд посылает AJAX-запрос при изменении города или весе корзины, получает список вариантов и обновляет UI. Результат кэшируется на фронте по ключу city + weight.
Кейс из нашей практики
Интернет-магазин мебели: разработали калькулятор доставки прямо на карточке товара — «введите город, узнайте стоимость доставки». Реализовали виджет с автодополнением города (из справочника Битрикс b_sale_location). При вводе 3+ символов посылается запрос /local/ajax/city_suggest.php, возвращает список подходящих городов. При выборе города — второй запрос с расчётом доставки. Результат сохраняется в localStorage по ключу last_city, при следующем визите поле города заполняется автоматически. В итоге конверсия в корзину выросла на 18%.
Как ускорить расчёт доставки на карточке товара?
Используйте кэширование на стороне клиента и сервера. На бэкенде — кэшируйте расчёт для одинаковых параметров (город, вес, сумма) на 5–10 минут. На фронте — храните последний результат в localStorage и показывайте его мгновенно при повторном визите. Также можно предзагружать расчёты для популярных городов. Кастомный калькулятор доставки в среднем в 4 раза быстрее стандартного компонента, что подтверждается на практике.
Что входит в работу
| Этап | Результат |
|---|---|
| Анализ текущего магазина | Отчёт по используемым службам доставки и необходимости доработок |
| Проектирование архитектуры | Схема AJAX-запроса, модель данных, сценарии кэширования |
| Разработка бэкенд-контроллера | PHP-класс с методом run(), обработка ошибок, валидация |
| Фронтенд-виджет | HTML/CSS/JS с автодополнением города и отображением результатов |
| Интеграция с корзиной и карточкой товара | Вставка виджета в нужные шаблоны |
| Тестирование на 5+ сценариях | Проверка с разными городами, весами, службами и кэшем |
| Документация API | Описание эндпоинтов, форматов запроса/ответа |
Сроки
| Состав | Срок |
|---|---|
| AJAX-калькулятор + автодополнение города | 2–3 дня |
| + Виджет на карточке товара | +1 день |
+ Кэширование + localStorage |
включено в базовую оценку |
Стоимость проекта зависит от сложности, точная цена рассчитывается индивидуально после анализа.
Как внедрить AJAX-калькулятор: шаги для разработчика
- Установите и активируйте модуль «Интернет-магазин».
- Настройте службы доставки в административной панели: тарифы, зоны, весогабаритные ограничения.
- Разместите виджет в нужном шаблоне (карточка товара или корзина) через подключение компонента.
- Настройте автодополнение города с помощью справочника местоположений или внешнего API.
- Протестируйте сценарии: разные города, веса, службы, кэш.
Чек-лист типичных ошибок
- Забывают установить
CURRENCYв заказе — расчёт может вернуть цену в неправильной валюте. - Не проверяют, что служба доставки активна и доступна для данного местоположения.
- Используют
getRestrictedObjectsListбез кэширования — каждый запрос нагружает БД. - Игнорируют обработку ошибок: если служба упала, пользователь видит пустой список.
- Не проверяют вес единиц измерения (килограммы против граммов).
Свяжитесь с нами, чтобы получить консультацию по вашему проекту. Оценим задачу за 2 часа и предложим оптимальное решение. Закажите внедрение калькулятора доставки и повысьте конверсию.







