Integrating 1C-Bitrix with Boxberry Delivery Service (Belarus)
Boxberry operates in Belarus through a partner network of pickup points. The API is identical to the Russian Boxberry — the same unified endpoint https://api.boxberry.ru/json.php, the same methods. The differences: the token is issued by the Belarusian office, the pickup point list is filtered by country, and tariffs differ.
Specifics of Belarusian integration
The token for operating in Belarus is obtained separately — the Russian token cannot be used for Belarusian pickup points. When requesting the pickup point list, filtering by country is required:
public function getBelarusPoints(): array
{
$cacheKey = 'boxberry_pvz_by';
$cached = \Bitrix\Main\Data\Cache::createInstance();
if ($cached->startDataCache(3600 * 12, $cacheKey, '/boxberry')) {
$url = 'https://api.boxberry.ru/json.php?' . http_build_query([
'token' => $this->getOption('BY_TOKEN'),
'method' => 'ListPoints',
'prepaid' => 1,
'CityCode' => '', // all Belarusian cities
]);
$points = json_decode(file_get_contents($url), true) ?? [];
// Filter only Belarusian pickup points
$byPoints = array_filter($points, fn($p) => ($p['CountryCode'] ?? '') === 'BY');
$cached->endDataCache(['points' => array_values($byPoints)]);
}
return $cached->getVars()['points'];
}
If the API does not return the CountryCode field, filter by city — maintain a list of Belarusian cities in the module config.
Cost calculation
public function calcCostBelarus(
string $pvzCode,
int $weightGram,
float $orderSum
): float {
$url = 'https://api.boxberry.ru/json.php?' . http_build_query([
'token' => $this->getOption('BY_TOKEN'),
'method' => 'DeliveryCosts',
'zip' => $pvzCode,
'weight' => $weightGram,
'ordersum' => $orderSum,
'targetstart' => $this->getOption('BY_FROM_POINT'), // dispatch point in Belarus
]);
$response = json_decode(file_get_contents($url), true);
if (!empty($response['err'])) {
return 0;
}
return (float)($response['price'] ?? 0);
}
The cost is returned in Belarusian rubles when using the Belarusian token.
Delivery service class
class BoxberryByDelivery extends \Bitrix\Sale\Delivery\Services\Base
{
protected static function getClassTitle(): string
{
return 'Boxberry (Belarus)';
}
protected function calculateConcrete(
\Bitrix\Sale\Shipment $shipment
): \Bitrix\Sale\Delivery\CalculationResult {
$result = new \Bitrix\Sale\Delivery\CalculationResult();
$pvzCode = $this->getSelectedPvzCode($shipment);
if (!$pvzCode) {
$result->addError(new \Bitrix\Main\Error('Please select a pickup point'));
return $result;
}
$cost = $this->calcCostBelarus(
$pvzCode,
$this->getWeight($shipment),
$shipment->getOrder()->getPrice()
);
if ($cost > 0) {
$result->setDeliveryPrice($cost);
} else {
$result->addError(new \Bitrix\Main\Error('Delivery unavailable'));
}
return $result;
}
}
If the store operates in both Russia and Belarus, two separate delivery service classes are created: BoxberryRuDelivery and BoxberryByDelivery with different tokens and dispatch points.
Creating a shipment in Belarus
public function createParselBelarus(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$parselData = [
'token' => $this->getOption('BY_TOKEN'),
'method' => 'ParselCreate',
'senderName' => $this->getOption('SENDER_NAME'),
'weight' => $this->getWeight($shipment),
'price' => $order->getPrice(),
'delivery_sum' => $shipment->getPrice(),
'vid' => 1,
'PVZ' => $props->getItemByOrderPropertyCode('BOXBERRY_BY_PVZ')?->getValue(),
'customerName' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'customerPhone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'customerEmail' => $props->getItemByOrderPropertyCode('EMAIL')?->getValue(),
'items' => $this->buildItems($order),
];
$response = $this->apiPost('https://api.boxberry.ru/json.php', $parselData);
return $response['track'] ?? '';
}
Pickup point selection widget
The same Boxberry JavaScript widget, but with the Belarusian token and a country restriction:
boxberry.open(function(result) {
if (result && result.id) {
document.getElementById('boxberry_by_pvz').value = result.id;
document.getElementById('boxberry_by_pvz_name').value = result.name;
}
}, 'BY_TOKEN', 'Минск', '', 0, 'e');
Tracking
The ParselCheck method works with the Belarusian token identically to the Russian one. Polling via an agent every 2–3 hours.
Timelines
| Scope | Timeline |
|---|---|
| Separate setup (Russian integration already in place) | 1–2 days |
| Full integration from scratch | 4–5 days |
| + Tracking + pickup point widget | +2 days |







