Integration of 1C-Bitrix with Kuranty Delivery Service (Belarus)
Integrating the Kuranty delivery service with 1C-Bitrix is a task faced by Belarusian online stores when standard modules don't fit. Kuranty's API requires JWT authorization and proper status handling. Our team has implemented several such integrations—from a simple calculator to a full cycle with pickup points and tracking. Here's how to do it right and what's important to consider.
Why Choose Kuranty for Delivery in Belarus?
Kuranty is a Belarusian logistics company specializing in courier delivery and a network of pickup points across the country. Compared to large federal operators, Kuranty offers more flexible tariffs for small and medium e-commerce. For example, delivery within Minsk is often 15–20% cheaper, and times are 1 day faster than traditional postal services. The API is provided to partners through a personal account after signing a contract.
How Does the Kuranty API Work?
The API is REST with JWT authorization. Base URL: https://api.kuranty.by/v2. A token is obtained via POST /auth/token with login and password, and lives for 24 hours. We cache the token for 23 hours to avoid hitting the API on every calculation.
Main methods:
-
POST /delivery/cost— cost calculation -
POST /delivery/create— create delivery -
GET /delivery/{uuid}/status— delivery status -
GET /pickup-points— list of pickup points
Cost Calculation
We implement a handler class extending \Bitrix\Sale\Delivery\Services\Base. In the calculateConcrete method, we get the recipient's city from order properties, send a request with weight and order total. The response includes cost and delivery time.
class KurantyHandler extends \Bitrix\Sale\Delivery\Services\Base { private function getAuthToken(): string { $cache = \Bitrix\Main\Data\Cache::createInstance(); if ($cache->initCache(3600 * 23, 'kuranty_token', '/kuranty/')) { return $cache->getVars(); } $response = $this->apiPost('/auth/token', [ 'login' => $this->getOption('LOGIN'), 'password' => $this->getOption('PASSWORD'), ]); $token = $response['token'] ?? ''; $cache->startDataCache(); $cache->endDataCache($token); return $token; } protected function calculateConcrete( \Bitrix\Sale\Shipment $shipment ): \Bitrix\Sale\Delivery\CalculationResult { $result = new \Bitrix\Sale\Delivery\CalculationResult(); $order = $shipment->getOrder(); $props = $order->getPropertyCollection(); $city = $this->getOrderCity($props); if (!$city) { $result->addError(new \Bitrix\Main\Error('Delivery city not defined')); return $result; } $response = $this->apiPost('/delivery/cost', [ 'from_city' => $this->getOption('SENDER_CITY'), 'to_city' => $city, 'weight' => max($shipment->getWeight() / 1000, 0.1), 'sum' => round($order->getPrice()), 'type' => $this->getOption('DELIVERY_TYPE', 'pickup'), // pickup or courier ], $this->getAuthToken()); if (!empty($response['cost'])) { $result->setDeliveryPrice((float)$response['cost']); $days = $response['days_min'] . '–' . $response['days_max']; $result->setPeriodDescription("{$days} days"); } return $result; } } An important nuance: if the delivery city is not defined (e.g., the user didn't select a locality), an error is returned. In practice, this rarely happens, but we always add validation on the checkout form side.
Creating a Delivery
After order placement, a delivery must be created in the Kuranty system. The createDelivery method builds a payload: weight, total, cash on delivery, address, and contact data. The response contains the UUID of the order in Kuranty, which we save in an order property.
public function createDelivery(\Bitrix\Sale\Shipment $shipment): string { $order = $shipment->getOrder(); $props = $order->getPropertyCollection(); $payload = [ 'external_id' => 'bx_' . $order->getId(), 'type' => $this->getOption('DELIVERY_TYPE', 'pickup'), 'from_city' => $this->getOption('SENDER_CITY'), 'to_city' => $this->getOrderCity($props), 'pickup_point' => $props->getItemByOrderPropertyCode('KURANTY_POINT')?->getValue(), 'recipient' => [ 'name' => $props->getItemByOrderPropertyCode('FIO')?->getValue(), 'phone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(), ], 'address' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(), 'weight' => max($shipment->getWeight() / 1000, 0.1), 'sum' => round($order->getPrice()), 'cod' => $order->isPaid() ? 0.0 : round($order->getPrice()), 'comment' => 'Order #' . $order->getId(), ]; $response = $this->apiPost('/delivery/create', $payload, $this->getAuthToken()); return (string)($response['uuid'] ?? ''); } Pickup Points on the Site
To display pickup points on a map, we use the /pickup-points API. We cache the data for 6 hours—Kuranty updates the list infrequently. The response includes coordinates (lat, lon), allowing us to plot points on Yandex Maps with custom markers.
public function getPickupPoints(?string $city = null): array { $cacheKey = 'kuranty_pvz_' . md5((string)$city); $cache = \Bitrix\Main\Data\Cache::createInstance(); if ($cache->initCache(3600 * 6, $cacheKey, '/kuranty/')) { return $cache->getVars(); } $params = $city ? ['city' => $city] : []; $points = $this->apiGet('/pickup-points', $params, $this->getAuthToken()); $cache->startDataCache(); $cache->endDataCache($points ?? []); return $points ?? []; } Tracking
Kuranty does not provide webhooks—delivery status must be polled manually. We implement a Bitrix agent that queries status for each active order every 2–3 hours and updates it in order properties. The getStatus method accepts a UUID and returns the current status array.
public function getStatus(string $uuid): array { return $this->apiGet("/delivery/{$uuid}/status", [], $this->getAuthToken()) ?? []; } What's Included in the Integration
| Task | Description |
|---|---|
| Current system audit | Analyze infoblock structure, order properties, delivery settings |
| Calculator development | Implement handler class for cost calculation with token caching |
| Order creation | Write code to send orders to Kuranty after checkout |
| Pickup point display | Integrate pickup points list with map on the site |
| Tracking and notifications | Set up agent for status updates and email notifications to customers |
| Testing and documentation | Test all scenarios, create admin instruction |
Comparison of Kuranty with Other Belarusian Delivery Services
| Parameter | Kuranty | Europochetta | Belpochta |
|---|---|---|---|
| Delivery time in Minsk | 1 day | 1–2 days | 2–3 days |
| Delivery time to regions | 1–3 days | 2–4 days | 3–7 days |
| Pickup points | 200+ | 100+ | none (only post office) |
| API | REST with JWT | REST with key | outdated XML |
Kuranty wins on speed in cities and number of pickup points but loses to Belpochta on cost. For high-volume online stores, combining services is more advantageous.
Timeline Estimates
| Component | Duration |
|---|---|
| Cost calculation + order creation | 3–4 days |
| + Pickup points on map | +2 days |
| + Tracking + notifications | +2 days |
| + Cash on delivery | +1 day |
Why Commission Our Integration?
Our team brings over 5 years of experience with 1C-Bitrix and more than 50 successful projects integrating delivery services. We provide a warranty on the code and post-launch support. All our specialists are vendor-certified. You'll receive a detailed quote and roadmap within 1 day after contacting us.
Order a turnkey integration—contact us to evaluate your project.







