Integrating 1C-Bitrix with the Boxberry Belarus delivery service

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 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