Интеграция 1С-Битрикс со службой доставки DPD
DPD — международная курьерская служба с сильным покрытием в России и Европе. Отличается от большинства российских служб SOAP-интерфейсом вместо REST. Это не проблема, но требует другого подхода: работа с WSDL, SoapClient, специфический формат данных. Интеграция с Битрикс реализуется через стандартный механизм кастомных служб доставки.
API DPD: SOAP-интерфейс
DPD предоставляет несколько WSDL-сервисов:
-
https://ws.dpd.ru/services/calculator2?wsdl— расчёт стоимости -
https://ws.dpd.ru/services/geography2?wsdl— города и ПВЗ -
https://ws.dpd.ru/services/order2?wsdl— создание заказа -
https://ws.dpd.ru/services/tracking2?wsdl— трекинг
Авторизация одинаковая для всех: клиентский номер (clientNumber) и ключ (clientKey) передаются в каждом запросе как часть структуры auth.
private function createSoapClient(string $wsdl): \SoapClient
{
return new \SoapClient($wsdl, [
'soap_version' => SOAP_1_1,
'trace' => true,
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_DISK,
'encoding' => 'utf-8',
]);
}
private function getAuth(): array
{
return [
'clientNumber' => $this->getOption('CLIENT_NUMBER'),
'clientKey' => $this->getOption('CLIENT_KEY'),
];
}
Кэширование WSDL (WSDL_CACHE_DISK) обязательно — без него каждый запрос загружает схему, что критично для расчёта стоимости на странице чекаута.
Расчёт стоимости доставки
private function calcCost(
string $fromCityCode,
string $toCityCode,
int $weightGram
): float {
$client = $this->createSoapClient(
'https://ws.dpd.ru/services/calculator2?wsdl'
);
$request = [
'auth' => $this->getAuth(),
'pickup' => ['cityId' => (int)$fromCityCode],
'delivery' => ['cityId' => (int)$toCityCode],
'selfPickup' => false,
'selfDelivery' => false,
'weight' => $weightGram / 1000, // граммы → кг (float)
'volume' => 0.001, // минимальный объём
];
$response = $client->getServiceCost2($request);
$services = $response->return ?? [];
// Находим тариф "DPD Classic" (serviceCode = 'CUR')
foreach ((array)$services as $service) {
if ($service->serviceCode === 'CUR') {
return $service->cost;
}
}
return 0;
}
DPD возвращает стоимость для всех доступных тарифов. Основные: CUR (DPD Classic — доставка до двери), PCL (DPD Online Express), ECO (DPD Economy). Код тарифа выбирается в настройках модуля.
Маппинг городов DPD
DPD использует собственные идентификаторы городов (cityId). Конвертация из названия города или кода КЛАДР:
public function findCity(string $cityName): ?int
{
$client = $this->createSoapClient(
'https://ws.dpd.ru/services/geography2?wsdl'
);
// Кэшируем результат на 24 часа
$cacheKey = 'dpd_city_' . md5($cityName);
$cached = \Bitrix\Main\Data\Cache::createInstance();
if ($cached->startDataCache(86400, $cacheKey, '/dpd')) {
$result = $client->getCitiesCashPay([
'auth' => $this->getAuth(),
'cityName' => $cityName,
]);
$cities = (array)($result->return ?? []);
$cityId = !empty($cities) ? $cities[0]->cityId : null;
$cached->endDataCache(['cityId' => $cityId]);
} else {
$cityId = $cached->getVars()['cityId'];
}
return $cityId;
}
Кэш на 24 часа критичен: список городов DPD не меняется ежечасно, а без кэша каждый расчёт стоимости делает два SOAP-запроса.
Создание заказа DPD
public function createOrder(\Bitrix\Sale\Shipment $shipment): string
{
$client = $this->createSoapClient(
'https://ws.dpd.ru/services/order2?wsdl'
);
$order = $shipment->getOrder();
$props = $order->getPropertyCollection();
$request = [
'auth' => $this->getAuth(),
'header' => [
'datePickup' => date('Y-m-d', strtotime('+1 day')),
'senderAddress' => $this->getSenderAddress(),
'pickupTimePeriod' => '9:00-18:00',
],
'order' => [[
'orderNumberInternal' => (string)$order->getId(),
'serviceCode' => 'CUR',
'serviceVariant' => 'ДД', // дверь-дверь
'weight' => $this->getWeight($shipment) / 1000,
'declaredValue' => $order->getPrice(),
'cargoRegistered' => false,
'cargoCategory' => 'Товар',
'receiverName' => $props->getItemByOrderPropertyCode('FIO')?->getValue(),
'receiverPhone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
'receiverAddress' => $this->buildReceiverAddress($props),
]],
];
$response = $client->createOrder($request);
$result = $response->return->order[0] ?? null;
return $result->orderNum ?? '';
}
Трекинг
public function trackOrder(string $dpdOrderNum): array
{
$client = $this->createSoapClient(
'https://ws.dpd.ru/services/tracking2?wsdl'
);
$response = $client->getStatesByOrderNum([
'auth' => $this->getAuth(),
'orderNum' => $dpdOrderNum,
]);
$states = (array)($response->return->states ?? []);
$last = end($states);
return [
'status' => $last->newState ?? '',
'city' => $last->city ?? '',
'timestamp' => $last->transitionTime ?? '',
];
}
DPD не предоставляет push-вебхуки. Только polling — агент Битрикс раз в 2–3 часа для активных заказов.
Сроки
| Состав | Срок |
|---|---|
| SOAP-клиент + расчёт + маппинг городов | 3–4 дня |
| + Создание заказов + трекинг polling | +2 дня |
| + ПВЗ DPD на карте | +2 дня |







