Integrating 1C-Bitrix with the Boxberry 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

1C-Bitrix Integration with Boxberry Delivery Service

Boxberry is a courier service with an extensive network of pickup points (PVZ) across Russia. The main e-commerce use case is pickup point delivery, which is cheaper than door-to-door delivery. The Boxberry API is quite specific: authentication is via a token passed as a query parameter (not in the header), some methods work via GET with JSON in the query string. There are nuances in cost calculation and passing product data.

Boxberry API Specifics

The Boxberry API works through a single endpoint: https://api.boxberry.ru/json.php. The method is passed as the method parameter, the token as the token parameter. Response format — JSON.

Key methods:

  • ListPoints — full list of pickup points
  • ListPointsShort — short list of pickup points (faster)
  • DeliveryCosts — delivery cost calculation
  • ParselCreate — create a shipment
  • ParselCheck — shipment status by tracking number

A non-standard detail: data for ParselCreate is sent via POST, but the parameters are URL-encoded, not JSON. This must be accounted for when building requests.

Delivery Cost Calculation

private function calcDeliveryCost(
    string $pvzCode,
    int $weightGram,
    float $orderSum
): float {
    $params = [
        'token'      => $this->token,
        'method'     => 'DeliveryCosts',
        'zip'        => $pvzCode,
        'weight'     => ceil($weightGram / 1000 * 1000), // in grams
        'ordersum'   => $orderSum,
        'api_version' => '1.0',
    ];

    $url = 'https://api.boxberry.ru/json.php?' . http_build_query($params);
    $response = json_decode(file_get_contents($url), true);

    return (float)($response['price'] ?? 0);
}

Boxberry returns the cost in rubles in the price field. If the pickup point is not found or delivery is not available for it — the response contains an err field. Always check for the error before using the price.

Delivery Service Class

class BoxberryDeliveryService extends \Bitrix\Sale\Delivery\Services\Base
{
    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;
        }

        $weight = max($this->getShipmentWeight($shipment), 50);
        $orderSum = $shipment->getOrder()->getPrice();

        $cost = $this->calcDeliveryCost($pvzCode, $weight, $orderSum);

        if ($cost <= 0) {
            $result->addError(new \Bitrix\Main\Error('Unable to calculate delivery cost'));
            return $result;
        }

        $result->setDeliveryPrice($cost);
        return $result;
    }
}

The selected pickup point code is stored in the session or in the order property BOXBERRY_PVZ_CODE — added at checkout via the widget.

Pickup Point Selection Widget

Boxberry provides a JavaScript widget for displaying pickup points on a map:

<script type="text/javascript" src="https://points.boxberry.ru/js/boxberry.js"></script>
<script>
boxberry.open(function(result) {
    if (result && result.id) {
        document.getElementById('boxberry_pvz').value = result.id;
        document.getElementById('boxberry_pvz_name').value = result.name + ', ' + result.address;
        // Update delivery cost via AJAX
        recalculateDelivery();
    }
}, 'TOKEN_HERE', 'Moscow', '', 0, 'e');
</script>

The function accepts a callback, token, default city, and additional parameters. result.id — the pickup point code for the API.

Creating a Shipment

private function createParsel(\Bitrix\Sale\Shipment $shipment): string
{
    $order = $shipment->getOrder();
    $props = $order->getPropertyCollection();

    $parselData = [
        'token'          => $this->token,
        'method'         => 'ParselCreate',
        'senderName'     => $this->getOption('SENDER_NAME'),
        'weight'         => $this->getShipmentWeight($shipment),
        'price'          => $order->getPrice(),
        'delivery_sum'   => $shipment->getPrice(),
        'vid'            => 1, // 1-to pickup point
        'PVZ'            => $props->getItemByOrderPropertyCode('BOXBERRY_PVZ_CODE')?->getValue(),
        'customerName'   => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
        'customerPhone'  => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
        'customerEmail'  => $props->getItemByOrderPropertyCode('EMAIL')?->getValue(),
        'items'          => $this->buildItems($order),
    ];

    $response = $this->apiRequest($parselData);
    return $response['track'] ?? '';
}

The vid field: 1 — delivery to a pickup point, 2 — door-to-door delivery. The tracking number from the response (track) is saved to the order property BOXBERRY_TRACK for subsequent tracking.

Shipment Tracking

public function checkStatus(string $trackCode): array
{
    $params = [
        'token'  => $this->token,
        'method' => 'ParselCheck',
        'ImId'   => $trackCode,
    ];

    $url = 'https://api.boxberry.ru/json.php?' . http_build_query($params);
    $data = json_decode(file_get_contents($url), true);

    return [
        'status'     => $data[0]['Name'] ?? 'Unknown',
        'date'       => $data[0]['Date'] ?? '',
        'city'       => $data[0]['CityName'] ?? '',
    ];
}

Boxberry does not support webhooks — only polling. A Bitrix agent checks the status of active shipments once per hour. When the status changes to "Delivered to recipient", the order is moved to its final status.

Boxberry Status Mapping

Boxberry Status Action in Bitrix
Accepted at Boxberry warehouse Transferred to delivery
In transit Dispatched
Arrived at destination pickup point Arrived at pickup point
Issued to recipient Delivered
Return to sender Return

Timeline

Scope Duration
Calculation + pickup widget + shipment creation 4–5 days
+ Status polling + mapping +2 days
+ Shipping label printing +1 day