PEK ב-Bitrix: חישוב, יצירת הזמנה, מעקב
PEK (חברת השליחויות הראשונה) היא אחת מחברות התובלה המרכזיות למשלוחי מטען ומשלוחים מאוחדים ברוסיה. המוזרות העיקרית של האינטגרציה: PEK עובדת עם מטען מ-1 ק"ג ומעלה, ה-API מותאם לפרמטרים של מקומות מטען (אורך, רוחב, גובה, משקל של כל מקום בנפרד), ולא לפורמט הקמעונאי הסטנדרטי של Bitrix. אם יש לך חנות מקוונת עם פריטים גדולים — ספות, חומרי בניין, ציוד תעשייתי — PEK הופכת פעמים רבות למוביל הראשי.
מהניסיון שלנו: יישמנו אינטגרציה לרשת חנויות חומרי בניין — החישוב הפך מדויק ב-25%, והתוספות נפסקו. עם ניסיון של 5+ שנים ב-Bitrix ולמעלה מ-30 פרויקטי משלוחים, אנו מבטיחים פתרון אמין.
תכונות API של PEK
PEK מספקת REST API עם אימות באמצעות Bearer token. ה-token מתקבל דרך POST /v2/sign-in עם שם משתמש וסיסמה מהחשבון האישי. ל-token אין TTL קפדני (בפועל הוא חי 24–48 שעות), אך מומלץ לשמור אותו במטמון ולרענן אותו בקבלת 401.
נקודות קצה מרכזיות:
-
POST /v2/calculator— חישוב עלות וזמן -
POST /v2/orders— יצירת הזמנה -
GET /v2/orders/{id}— סטטוס הזמנה -
GET /v2/departments— רשימת מסופי PEK
כתובת בסיס: 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),
],
];
}
}חשוב: PEK מחשבת על בסיס משקל נפחי. אם המשקל בפועל קטן מהמשקל הנפחי (אורך×רוחב×גובה / 5000 לאוויר, / 4000 לקרקע), נעשה שימוש במשקל הנפחי. עבור פריטים גדולים זה קריטי — העבר את מידות המוצר האמיתיות. תיעוד PEK: משקל נפחי = (אורך×רוחב×גובה)/5000 לאוויר ו-/4000 לקרקע.
איך לקבל cityId ולהימנע מטעויות?
PEK משתמשת במזהי ערים מספריים משלה. חיפוש עיר:
public function findCityId(string $cityName): ?int {
$response = $this->apiGet('/v2/city?name=' . urlencode($cityName), $this->getApiToken());
return $response[0]['id'] ?? null;
}חלופה: הורד את ספריית הערים של PEK ושמור את המיפוי 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), ], ]; } } ב-infoblock או בטבלה מותאמת אישית. בתחילת הפרויקט, אנו ממליצים על גישה זו — 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'] ?? '');
}עבור סוגים public function findCityId(string $cityName): ?int { $response = $this->apiGet('/v2/city?name=' . urlencode($cityName), $this->getApiToken()); return $response[0]['id'] ?? null; } או название_города → pek_city_id, יש להעביר את מזהה מסוף PEK. רשימת מסופים: 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'] ?? ''); } . סנן לפי cityId. באתר, יישם רשימה נפתחת של מסופים עם מפה — ווידג'ט או יישום מותאם אישית על Leaflet/Yandex Maps.
למה חשוב להעביר מידות אמיתיות?
מקרה מהניסיון שלנו: חנות חומרי בניין, משקל הזמנה ממוצע 50–200 ק"ג, הרבה חומרי יריעות. בעיה במהלך היישום: Bitrix שומרת משקל משלוח כמספר יחיד, אך PEK עבור הזמנות עם מספר פריטים בגדלים שונים דורשת רשימה של מקומות מטען עם מידות לכל אחד. נאלצנו ליישם לוגיקת פיצול: לכל מוצר ב-infoblock יש מאפיינים door_terminal, terminal_door, GET /v2/departments. בעת יצירת המשלוח, כל יחידת פריט הופכת למקום מטען נפרד.
זה הגדיל את דיוק החישוב: הסטייה מהעלות האמיתית ירדה מ-±30% ל-±5%, החיסכון בתוספות הגיע עד 15% מעלות המשלוח. פירוט כזה הוא יתרון מרכזי על פני הגישה הסטנדרטית המשתמשת במשקל ממוצע.
מעקב סטטוסים
| סטטוס PEK | משמעות |
|---|---|
DELIVERY_LENGTH |
התקבל להובלה |
DELIVERY_WIDTH |
במעבר |
DELIVERY_HEIGHT |
הגיע למסוף היעד |
accepted |
נמסר לשליח |
in_transit |
נמסר |
arrived |
הוחזר |
ל-PEK אין webhooks — רק סקירה תקופתית (polling). סוכן Bitrix מבקש סטטוסים של משלוחים פעילים כל 4 שעות דרך out_for_delivery ומעדכן את סטטוס ההזמנה בחנות. הניסיון שלנו מראה שסקירה תקופתית פשוטה וזולה יותר מ-webhooks לעומסים נמוכים (עד 500 משלוחים ביום).
טעויות אינטגרציה אופייניות
| טעות | תוצאה | פתרון |
|---|---|---|
| העברת מידות ממוצעות | תוספת עד 30% | ציין מאפייני מוצר |
| cityId שגוי | חישוב לא נכון | הורד ספרייה מלאה |
| אין שמירת token במטמון | מגבלות API | שמור במטמון עם פסילה על 401 |
| התעלמות ממשקל נפחי | מחיר מופרז | התחשב במקדם |
מה כלול בעבודה במפתח מלא
- פיתוח handler משלוחים ב-PHP 8.1+ עם מחזור מלא: חישוב → יצירה → מעקב.
- הגדרת התאמת ערים של PEK (הורדה ומיפוי).
- יצירת מקומות מטען על בסיס מאפייני מוצר (אם נדרש).
- אינטגרציה של מפת מסופים בחנות המקוונת.
- סוכן מעקב והתראות סטטוס ללקוח.
- תיעוד וייעוץ לגבי שינויים.
קבל ייעוץ על אינטגרציה — המהנדסים שלנו מוסמכי Bitrix ויש להם ניסיון מסחרי של 5+ שנים. צור קשר כדי להעריך את הפרויקט שלך.
לוח זמנים
| מודול | זמן |
|---|---|
| חישוב עלות + יצירת הזמנה | 4–5 ימים |
| + רשימת מסופים + מפה | +2–3 ימים |
| + פיצול למקומות מטען לפי מוצר | +2 ימים |
| + סקירת סטטוסים + התראות | +2 ימים |
נעריך את הפרויקט שלך תוך יום אחד — צור קשר כדי לדון בפרטים.

