1C-Bitrix Integration with Delovye Linii Delivery Service
Delovye Linii is a major transport company with a terminal network across Russia. Like PEK, it specializes in cargo transportation: from small parcels to pallet shipments. A notable characteristic — in a number of regions it is the only alternative to Russian Post for delivery with reasonable timelines to industrial centers.
The Delovye Linii API is REST with JWT authorization. Documentation is in Russian and covers the main operations.
Delovye Linii API: Structure
Base URL: https://api.dellin.ru/v3/. Authorization is two-step: first obtain a session token via /v3/auth/login.json, then use it in the Cookie: session=TOKEN header or as a parameter.
private function getSession(): string
{
$cacheKey = 'dellin_session_' . md5($this->appKey);
$cached = \Bitrix\Main\Data\Cache::createInstance();
if ($cached->startDataCache(3600 * 8, $cacheKey, '/dellin')) {
$response = $this->httpPost('/v3/auth/login.json', [
'appkey' => $this->appKey,
'login' => $this->login,
'password' => $this->password,
]);
$session = $response['data']['sessionID'] ?? '';
$cached->endDataCache(['session' => $session]);
}
return $cached->getVars()['session'];
}
The session lives 8+ hours. Cache for 8 hours to avoid re-authorizing on every cost calculation.
Cost Calculation
private function calcCost(
string $fromCity,
string $toCity,
float $weightKg,
float $volumeM3
): float {
$response = $this->apiPost('/v3/calculator.json', [
'appkey' => $this->appKey,
'sessionID' => $this->getSession(),
'delivery' => [
'deliveryType' => ['type' => 'auto'],
'arrival' => ['variant' => 'address'],
'dispatch' => ['variant' => 'terminal'],
],
'cargo' => [
'quantity' => 1,
'weight' => $weightKg,
'volume' => $volumeM3,
'totalEnvelopesWeight' => 0,
],
'members' => [
'from' => ['terminalID' => $this->findTerminalId($fromCity)],
'to' => ['city' => $toCity],
],
]);
return (float)($response['data']['price'] ?? 0);
}
The parameter delivery.dispatch.variant: terminal means the store will deliver the cargo to the terminal itself. arrival.variant: address — delivery to the customer's door. Variant combinations affect the price: terminal-to-terminal is cheaper, address-to-address is more expensive.
Finding a Terminal by City
public function findTerminalId(string $cityName): string
{
$response = $this->apiPost('/v3/public/terminals.json', [
'appkey' => $this->appKey,
]);
foreach ($response['data']['terminals'] ?? [] as $terminal) {
if (mb_stripos($terminal['city']['name'], $cityName) !== false) {
return $terminal['id'];
}
}
return '';
}
The terminal list is large — cache the search result for one day.
Order Creation
public function createOrder(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$payload = [
'appkey' => $this->appKey,
'sessionID' => $this->getSession(),
'delivery' => [
'deliveryType' => ['type' => 'auto'],
'dispatch' => ['variant' => 'terminal'],
'arrival' => [
'variant' => 'address',
'address' => [
'search' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(),
],
],
],
'cargo' => $this->buildCargo($shipment),
'members' => [
'from' => ['terminalID' => $this->getOption('FROM_TERMINAL_ID')],
'to' => [
'contactPersons' => [[
'name' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'phone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
]],
],
],
'payment' => [
'type' => 'cash',
'payer' => 'receiver', // recipient pays for delivery (cash on delivery)
],
];
$response = $this->apiPost('/v3/orders.json', $payload);
return (string)($response['data']['orderID'] ?? '');
}
The parameter payment.payer: receiver — delivery is paid by the recipient. sender — paid by the sender (store). The choice depends on the store's business model.
Order Tracking
public function getOrderState(string $orderId): array
{
$response = $this->apiPost('/v3/orders/state.json', [
'appkey' => $this->appKey,
'sessionID' => $this->getSession(),
'orders' => [['orderID' => $orderId]],
]);
$state = $response['data'][0] ?? [];
return [
'status' => $state['orderState']['name'] ?? '',
'deliveryDate' => $state['deliveryDate'] ?? '',
];
}
Delovye Linii does not support webhooks for tracking. A 1C-Bitrix agent polls active shipment statuses every 3–4 hours.
Specifics for Oversized Goods
Delovye Linii supports pallet shipments. For furniture or building materials stores, shipments need to be split into multiple units with individual dimensions. The cargo.oversizedWeight field is used for non-standard units (> 80 kg or > 3 m in length).
Timelines
| Scope | Timeline |
|---|---|
| Authorization + calculation + terminal mapping | 3–4 days |
| + Order creation + tracking | +2 days |
| + Dimensional calculation + pallets | +1 day |







