Integrating 1C-Bitrix with Kuranty Delivery Service (Belarus)
Kuranty is a Belarusian courier service focused on deliveries in Minsk and the surrounding area. It works with e-commerce, offering same-day delivery, delivery at a specified time, and try-before-you-pay (relevant for fashion stores). The API is provided under contract.
Kuranty API
REST API with token-based authorization. Documentation is in Russian. The base URL is confirmed upon connection (typically https://api.kuranty.by/ or an address provided by the account manager).
private function httpRequest(string $method, string $endpoint, array $body = []): array
{
$url = rtrim($this->getOption('API_URL'), '/') . '/' . ltrim($endpoint, '/');
$ch = curl_init($method === 'GET' ? $url . '?' . http_build_query($body) : $url);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Token ' . $this->getOption('API_TOKEN'),
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => $method !== 'GET' ? json_encode($body, JSON_UNESCAPED_UNICODE) : null,
]);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code >= 400) {
$err = json_decode($response, true);
throw new \RuntimeException('Kuranty API: ' . ($err['detail'] ?? $response));
}
return json_decode($response, true) ?? [];
}
Cost calculation
Kuranty calculates cost by zones within Minsk and by cities. The zone model is typical for courier services in large cities.
public function calcCost(string $address, int $weightGram, string $timeSlot = 'standard'): float
{
$response = $this->httpRequest('POST', '/tariffs/calculate', [
'address' => $address,
'weight' => $weightGram / 1000, // g → kg
'timeSlot' => $timeSlot, // standard, express, timed
]);
return (float)($response['price'] ?? 0);
}
Slot types: standard (standard, several days), express (today), timed (at a specified time). Each slot has its own price.
Try-before-you-pay
A distinctive feature of Kuranty is try-before-you-pay support. The courier arrives with several items (for example, three sizes of the same model), the customer tries them on, keeps what they need, and returns the rest. This requires special logic in the request:
public function createFittingOrder(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$isFitting = $props->getItemByOrderPropertyCode('FITTING')?->getValue() === 'Y';
$payload = [
'externalId' => (string)$order->getId(),
'type' => $isFitting ? 'fitting' : 'standard',
'timeSlot' => $props->getItemByOrderPropertyCode('DELIVERY_SLOT')?->getValue() ?? 'standard',
'recipient' => [
'name' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'phone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'address' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(),
],
'items' => $this->buildItems($order),
'payment' => [
'type' => $isFitting ? 'after_fitting' : 'prepaid',
'amount' => $order->getPrice(),
],
];
$response = $this->httpRequest('POST', '/orders', $payload);
$orderNum = (string)($response['number'] ?? '');
$props->getItemByOrderPropertyCode('KURANTY_ORDER')?->setValue($orderNum);
$order->save();
return $orderNum;
}
With type fitting, payment occurs after the fitting — payment.type: after_fitting. The store receives from the courier only payment for the accepted items.
Time slot selection
The customer is shown a slot selection on the checkout page:
// AJAX request to retrieve available slots
fetch('/bitrix/services/main/ajax.php?action=kuranty_slots', {
method: 'POST',
body: JSON.stringify({ date: selectedDate }),
})
.then(r => r.json())
.then(data => {
data.slots.forEach(slot => {
// Add slot selection buttons
});
});
On the 1C-Bitrix server side: an AJAX component requests available slots from the Kuranty API and returns them to the frontend. The selected slot is saved to the order property DELIVERY_SLOT.
Tracking
public function getOrderStatus(string $orderNum): array
{
$response = $this->httpRequest('GET', '/orders/' . $orderNum);
return [
'status' => $response['status'] ?? '',
'courierName' => $response['courier']['name'] ?? '',
'eta' => $response['eta'] ?? '',
];
}
Limitations
Kuranty operates in Minsk and the immediate surroundings. A different delivery service is needed for other cities. In 1C-Bitrix, the zone restriction is implemented using the standard "Locations" mechanism.
Timelines
| Scope | Timeline |
|---|---|
| Cost calculation + order creation + slots | 3–4 days |
| + Try-before-you-pay + tracking | +2 days |







