Imagine: a courier service processes 20 orders daily. The dispatcher spends half an hour planning the route, but half of the clients are still dissatisfied with delays. What's the problem? Usually it's manual planning and lack of accurate traffic and time window data. Integrating 1C-Bitrix with routing services—Yandex.Routing or OR-Tools—solves this in 5 seconds. Mileage is reduced by 33%, and on-time delivery rates increase from 60% to 95%. This is not just fuel savings—it's fulfilling commitments to clients and reducing operational costs.
How integration solves the traveling salesman problem
The essence is simple: Bitrix collects order data—addresses, time windows, weight. The external service solves the NP-hard traveling salesman problem—builds the optimal visiting order. The result is passed back as route sheets. We make this connection transparent and reliable. Performance: 20 points processed in 5 seconds, while manual planning takes 30 minutes—a 360x difference.
More about the traveling salesman problem
The traveling salesman problem (TSP) is a classic NP-hard problem of finding the shortest route that visits all given points exactly once. In the delivery context, it is solved with time windows and vehicle capacity, making it even more complex (VRPTW). Modern algorithms such as ant colony optimization or linear programming find near-optimal solutions in seconds.Step 1: Data preparation
To build a route, you need a list of addresses with coordinates and time windows. Addresses are taken from order properties:
$deliveries = \Bitrix\Sale\OrderTable::getList([ 'filter' => [ 'STATUS_ID' => 'TD', // статус "к доставке сегодня" '>=DATE_STATUS' => new \Bitrix\Main\Type\Date(), ], 'select' => ['ID'], ])->fetchAll(); $points = []; foreach ($deliveries as $row) { $order = \Bitrix\Sale\Order::load($row['ID']); $props = $order->getPropertyCollection(); $points[] = [ 'order_id' => $row['ID'], 'address' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(), 'lat' => $props->getItemByOrderPropertyCode('LAT')?->getValue(), 'lon' => $props->getItemByOrderPropertyCode('LON')?->getValue(), 'time_from' => $props->getItemByOrderPropertyCode('DELIVERY_TIME_FROM')?->getValue(), 'time_to' => $props->getItemByOrderPropertyCode('DELIVERY_TIME_TO')?->getValue(), 'weight' => $this->getOrderWeight($order), ]; } Coordinates (LAT/LON) should be obtained during order placement—via Yandex or Google geocoding API from the entered address. Save them in the order's user properties.
Why accurate geocoding is essential for optimal routes
Without coordinates, the optimization service doesn't know exactly where the point is. Geocoding converts a text address into latitude/longitude. We implement it directly in the order form—an AJAX request to the geocoder when the address field is filled. Here's how it looks:
fetch(`https://geocode-maps.yandex.ru/1.x/?apikey=KEY&format=json&geocode=${encodeURIComponent(address)}`) .then(r => r.json()) .then(data => { const pos = data.response.GeoObjectCollection.featureMember[0]?.GeoObject?.Point?.pos; if (pos) { const [lon, lat] = pos.split(' '); document.getElementById('lat-field').value = lat; document.getElementById('lon-field').value = lon; } }); The coordinates are silently saved to hidden form fields and end up in the order properties. The driver never knows—it's all automatic.
Step 2: Integration with the optimization service
After collecting the points, send them to the route optimizer API. Example with Yandex.Routing:
$httpClient = new \Bitrix\Main\Web\HttpClient(); $response = $httpClient->post( 'https://courier.yandex.ru/api/v1/companies/{company_id}/routes', json_encode(['vehicles' => $vehicles, 'orders' => $points]), ['Authorization' => 'Bearer ' . YANDEX_COURIER_API_KEY] ); $routes = json_decode($response, true); The returned routes contain an ordered list of points for each courier. Save them to the bl_courier_routes table and assign to couriers via CRM tasks or a mobile app.
Step 3: Displaying the route to the courier
Create a mobile page or send the courier a link to the route in Google Maps or Yandex.Maps with waypoints. Format for Google Maps:
https://www.google.com/maps/dir/DEPOT_LAT,DEPOT_LON/STOP1_LAT,STOP1_LON/STOP2_LAT,STOP2_LON/... Generate this link from the bl_courier_routes data and send it to the courier via SMS or email.
What route optimization delivers
| Parameter | Manual delivery | Optimized routing |
|---|---|---|
| Average mileage for 20 points | 180 km | 120 km (33% less) |
| On-time deliveries | 60% | 95% |
| Fuel costs | 100% | 70% |
| Route planning time | 30 minutes | 5 seconds |
Optimized routing is 30 times faster than manual planning and reduces mileage by 33%. Every saved kilometer reduces fuel consumption significantly, and together with savings on courier and dispatcher time, the delivery budget can drop by 30–40%.
Typical setup mistakes
| Mistake | Consequence | Solution |
|---|---|---|
| Address without geocoding | Service cannot build a route | Add AJAX request to geocoder |
| Time windows not set | Courier drives any time | Create properties DELIVERY_TIME_FROM/DELIVERY_TIME_TO |
| Ignoring weight | Courier overload | Include weight in route calculation |
| No collection agent | Data becomes outdated | Set up agent via Cron or Bitrix agents |
How we automate delivery turnkey
We perform the full cycle of work:
- Create order user properties
LAT,LON,DELIVERY_TIME_FROM,DELIVERY_TIME_TO. - Implement AJAX geocoding via Yandex or Google.
- Set up an agent to collect points and call the optimizer API.
- Create the
bl_courier_routestable for storing routes. - Generate map links and send them to couriers.
- Train dispatchers and couriers.
- Provide source code and documentation for modifications.
Our clients save an average of 30,000 rubles per month on fuel and dispatcher salaries. Certified specialists, transparent code, post-delivery support. Contact us for a delivery system audit—we'll estimate budget and timeline within one day. Order turnkey setup and get a consultation on your task.

