1C-Bitrix Integration with Belpochta Delivery Service (Belarus)
Belpochta is the state postal operator of Belarus with nationwide coverage. For e-commerce it is indispensable where courier services do not operate: small towns, rural communities, district centers. Belpochta provides an API for working with shipments, but its functionality is more limited compared to commercial carriers.
Belpochta API: Specifics
Belpochta provides SOAP and REST API through the "Automated Data Exchange" (ADE) system. Access is by contract. REST API (newer): https://api.belpost.by/. Authorization: token in the Authorization header.
private function apiRequest(string $method, string $path, array $payload = []): array
{
$url = 'https://api.belpost.by' . $path;
$ch = curl_init($method === 'GET' ? $url . '?' . http_build_query($payload) : $url);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . $this->getOption('API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $method === 'POST' ? json_encode($payload) : null,
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code >= 400) {
throw new \RuntimeException("Belpost API {$code}: {$body}");
}
return json_decode($body, true) ?? [];
}
Address Indexing and Postal Codes
The key parameter for Belpochta is the recipient's postal code. The Belarusian postal index system is 6-digit (e.g., 220036 — Minsk). The API provides object search by address:
public function findPostcode(string $city, string $street, string $house): ?string
{
$cacheKey = 'belpost_idx_' . md5("{$city}_{$street}_{$house}");
$cached = \Bitrix\Main\Data\Cache::createInstance();
if ($cached->startDataCache(86400 * 30, $cacheKey, '/belpost')) {
$result = $this->apiRequest('GET', '/addresses/index', [
'city' => $city,
'street' => $street,
'house' => $house,
]);
$index = $result['index'] ?? null;
$cached->endDataCache(['index' => $index]);
}
return $cached->getVars()['index'];
}
Cache for 30 days — postal codes change extremely rarely.
Cost Calculation
public function calcCost(
string $fromIndex,
string $toIndex,
int $weightGram,
string $type = 'PARCEL'
): float {
$response = $this->apiRequest('POST', '/tariffs/calculate', [
'type' => $type, // PARCEL, REGISTERED_LETTER, EMS
'fromIndex' => $fromIndex,
'toIndex' => $toIndex,
'weight' => $weightGram,
'declared' => true,
]);
// Belpochta returns the tariff in Belarusian kopecks
return ($response['price'] ?? 0) / 100;
}
Creating a Postal Item
public function createItem(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$payload = [
'type' => 'PARCEL',
'category' => 'ORDINARY',
'senderName' => $this->getOption('SENDER_NAME'),
'senderIndex' => $this->getOption('SENDER_INDEX'),
'senderAddress' => $this->getOption('SENDER_ADDRESS'),
'senderPhone' => $this->getOption('SENDER_PHONE'),
'recipientName' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'recipientIndex' => $props->getItemByOrderPropertyCode('BELPOST_INDEX')?->getValue(),
'recipientAddress' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(),
'recipientPhone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'weight' => $this->getWeight($shipment),
'declaredValue' => (int)($order->getPrice() * 100), // in kopecks
'cashOnDelivery' => 0,
'description' => 'Online store goods',
];
$response = $this->apiRequest('POST', '/items', $payload);
$barcode = $response['barcode'] ?? '';
$props->getItemByOrderPropertyCode('BELPOST_BARCODE')?->setValue($barcode);
$order->save();
return $barcode;
}
Monetary values in Belpochta are in Belarusian kopecks. Same as with Kazpost: multiply by 100 when calculating and creating shipments, divide by 100 when displaying.
Cash on Delivery
Belpochta supports cash on delivery. The cashOnDelivery field — the amount in kopecks that the postal service collects from the recipient. The minimum COD amount and commission are specified in the contract.
Tracking
public function track(string $barcode): array
{
$response = $this->apiRequest('GET', '/tracking', ['barcode' => $barcode]);
$events = $response['events'] ?? [];
$last = end($events);
return [
'status' => $last['name'] ?? '',
'date' => $last['date'] ?? '',
'place' => $last['place'] ?? '',
];
}
Public tracking for Belpochta is also available at track.belpost.by. The 1C-Bitrix agent queries the status of active shipments 1–2 times per day.
Timelines
| Scope | Timeline |
|---|---|
| Tariff calculation + postal code lookup | 2–3 days |
| + Shipment creation + tracking | +2 days |







