Integration of 1C-Bitrix with the Kuranty delivery service (Belarus)

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

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