ПЭК у Бітрікс: розрахунок, створення замовлень, трекінг
ПЭК (Перша Експедиційна Компанія) — одна з ключових транспортних компаній для вантажної та збірної доставки в Росії. Основна специфіка інтеграції: ПЭК працює з вантажами від 1 кг і вище, API заточений під параметри вантажомісця (довжина, ширина, висота, вага кожного місця окремо), а не під стандартний роздрібний формат Бітрікс. Якщо у вас інтернет-магазин з великогабаритом — дивани, будівельні матеріали, промислове обладнання — ПЭК часто стає основним перевізником.
З нашої практики: ми реалізували інтеграцію для мережі магазинів будматеріалів — розрахунок став точнішим на 25%, а донарахування припинилися. Досвід 5+ років у Бітрікс та понад 30 проєктів з доставки гарантують надійне рішення.
API ПЭК: особливості
ПЭК надає REST API з авторизацією через Bearer-токен. Токен отримується через POST /v2/sign-in з логіном і паролем з особистого кабінету. Токен не має жорстко обмеженого TTL (на практиці живе 24–48 годин), але рекомендується кешувати та оновлювати при отриманні 401.
Ключові ендпоінти:
-
POST /v2/calculator— розрахунок вартості та термінів -
POST /v2/orders— створення замовлення -
GET /v2/orders/{id}— статус замовлення -
GET /v2/departments— список терміналів ПЭК
Базовий URL: https://api.pek.ru. Документація доступна в особистому кабінеті партнера.
Як налаштувати розрахунок вартості?
class PekDeliveryHandler extends \Bitrix\Sale\Delivery\Services\Base
{
protected function calculateConcrete(
\Bitrix\Sale\Shipment $shipment
): \Bitrix\Sale\Delivery\CalculationResult {
$result = new \Bitrix\Sale\Delivery\CalculationResult();
$token = $this->getApiToken();
$payload = $this->buildCalcPayload($shipment);
$response = $this->apiPost('/v2/calculator', $payload, $token);
if (empty($response['price'])) {
$result->addError(new \Bitrix\Main\Error('Розрахунок недоступний'));
return $result;
}
$result->setDeliveryPrice((float)$response['price']);
$result->setPeriodDescription($response['period_min'] . '–' . $response['period_max'] . ' днів');
return $result;
}
private function buildCalcPayload(\Bitrix\Sale\Shipment $shipment): array
{
$order = $shipment->getOrder();
return [
'senderCityId' => (int)$this->getOption('SENDER_CITY_ID'),
'receiverCityId' => $this->getReceiverCityId($shipment),
'cargo' => $this->buildCargoPlaces($shipment),
'service' => $this->getOption('SERVICE_TYPE', 'door_door'),
'declaredValue' => round($order->getPrice(), 2),
];
}
private function buildCargoPlaces(\Bitrix\Sale\Shipment $shipment): array
{
// ПЭК вимагає параметри кожного вантажомісця окремо
$weight = max($shipment->getWeight() / 1000, 1); // г → кг, мінімум 1 кг
return [
[
'weight' => $weight,
'length' => (int)$this->getOption('DEFAULT_LENGTH', 50),
'width' => (int)$this->getOption('DEFAULT_WIDTH', 50),
'height' => (int)$this->getOption('DEFAULT_HEIGHT', 50),
],
];
}
}
Важно: ПЭК розраховує за об'ємною вагою. Якщо фактична вага менша за об'ємну (Д×Ш×В / 5000 для авіа, / 4000 для авто), рахується об'ємна. Для великогабариту це критично — передавайте реальні габарити товарів. Документація ПЭК: об'ємна вага = (Д×Ш×В)/5000 для авіа та /4000 для авто.
Як отримати cityId і не помилитися?
ПЭК використовує власні числові ідентифікатори міст. Пошук міста:
public function findCityId(string $cityName): ?int
{
$response = $this->apiGet('/v2/city?name=' . urlencode($cityName), $this->getApiToken());
return $response[0]['id'] ?? null;
}
Альтернатива: вивантажити довідник міст ПЭК і зберігати мапінг назва_міста → pek_city_id в інфоблоці або кастомній таблиці. При старті рекомендується саме цей підхід — API пошуку міста повертає неоднозначні результати для населених пунктів з однаковою назвою.
Створення замовлення та термінали
private function createPekOrder(\Bitrix\Sale\Shipment $shipment): string
{
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$payload = [
'senderCityId' => (int)$this->getOption('SENDER_CITY_ID'),
'receiverCityId' => $this->getReceiverCityId($shipment),
'cargo' => $this->buildCargoPlaces($shipment),
'service' => $this->getOption('SERVICE_TYPE', 'door_door'),
'declaredValue' => round($order->getPrice(), 2),
'sender' => [
'company' => $this->getOption('SENDER_COMPANY'),
'contact' => $this->getOption('SENDER_CONTACT'),
'phone' => $this->getOption('SENDER_PHONE'),
'address' => $this->getOption('SENDER_ADDRESS'),
],
'receiver' => [
'contact' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'phone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'address' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(),
],
];
$response = $this->apiPost('/v2/orders', $payload, $this->getApiToken());
return (string)($response['id'] ?? '');
}
При типі door_terminal або terminal_door потрібно передавати ідентифікатор терміналу ПЭК. Список терміналів: GET /v2/departments. Фільтрація за cityId. На сайті реалізується випадаючий список терміналів з картою — віджет або кастомна реалізація на Leaflet/Yandex Maps.
Чому важливо передавати реальні габарити?
Кейс з нашої практики: магазин будматеріалів, середня вага замовлення 50–200 кг, багато листового матеріалу. Проблема при впровадженні: Бітрікс зберігає вагу відправлення як одне число, а ПЭК при замовленні з кількома позиціями різних розмірів вимагає список вантажомісць з габаритами кожного. Довелося реалізувати логіку розбивки: у кожного товару в інфоблоці заведено властивості DELIVERY_LENGTH, DELIVERY_WIDTH, DELIVERY_HEIGHT. При формуванні відправлення кожна одиниця товару перетворюється на окреме вантажомісце.
Це збільшило точність розрахунку: розбіжність з реальною вартістю скоротилася з ±30% до ±5%, економія на донарахуваннях склала до 15% від вартості доставки. Така деталізація — ключова перевага перед стандартним підходом, де використовується усереднена вага.
Трекінг статусів
| Статус ПЭК | Значення |
|---|---|
accepted |
Прийнято до перевезення |
in_transit |
В дорозі |
arrived |
Прибув на термінал призначення |
out_for_delivery |
Передано кур'єру |
delivered |
Доставлено |
returned |
Повернення |
Вебхуків у ПЭК немає — тільки polling. Агент Бітрікс раз на 4 години запитує статуси активних відправлень через GET /v2/orders/{id} та оновлює статус замовлення в магазині. Наш досвід показує, що polling простіший і дешевший за вебхуки для невисоких навантажень (до 500 відправлень на день).
Типові помилки при інтеграції
| Помилка | Наслідок | Рішення |
|---|---|---|
| Передача усереднених габаритів | Донарахування до 30% | Вказати властивості товарів |
| Невірний cityId | Розрахунок невірний | Вивантажити повний довідник |
| Відсутність кешування токена | Ліміти API | Кешувати з інвалідацією по 401 |
| Ігнорування об'ємної ваги | Завищення вартості | Враховувати коефіцієнт |
Що входить в роботу під ключ
- Розробка обробника доставки на PHP 8.1+ з повним циклом: розрахунок → створення → трекінг.
- Налаштування відповідності міст ПЭК (вивантаження та мапінг).
- Генерація вантажомісць на основі властивостей товарів (якщо потрібно).
- Інтеграція карти терміналів на вітрині.
- Агент трекінгу та сповіщення клієнтів про статуси.
- Документація та консультація щодо доробок.
Отримайте консультацію з інтеграції — наші інженери сертифіковані з Бітрікс та мають 5+ років комерційного досвіду. Зв'яжіться для оцінки вашого проєкту.
Терміни
| Склад | Термін |
|---|---|
| Розрахунок вартості + створення замовлення | 4–5 днів |
| + Список терміналів + карта | +2–3 дні |
| + Розбивка на вантажомісця по товарах | +2 дні |
| + Polling статусів + сповіщення | +2 дні |
Оцінимо ваш проєкт за 1 день — зв'яжіться, щоб обговорити деталі.







