Інтеграція служби доставки DHL на сайт
DHL — глобальний логістичний оператор, ключовий вибір для міжнародної доставки. API DHL Express (для термінових відправлень) та DHL eCommerce (для інтернет-торговлі) — різні продукти з різними endpoint'ами. Для російського інтернет-магазину з міжнародними відправками часто використовують DHL Express API.
Авторизація
DHL Express використовує Basic Auth з API key та secret:
class DhlExpressClient
{
private const BASE_URL = 'https://express.api.dhl.com/mydhlapi';
public function __construct(
private string $apiKey,
private string $apiSecret
) {}
public function request(string $method, string $path, array $params = []): array
{
$response = Http::withBasicAuth($this->apiKey, $this->apiSecret)
->{strtolower($method)}(self::BASE_URL . $path, $params);
if ($response->clientError()) {
throw new DhlApiException($response->json()['detail'] ?? 'DHL error');
}
return $response->json();
}
}
Sandbox: apiKey = demo-key, apiSecret = demo-secret.
Тарифи й терміни доставки
public function getRates(
array $from,
array $to,
float $weightKg,
string $plannedShipDate
): array {
$response = $this->request('GET', '/rates', [
'originCountryCode' => $from['countryCode'],
'originCityName' => $from['cityName'],
'destinationCountryCode' => $to['countryCode'],
'destinationCityName' => $to['cityName'],
'weight' => $weightKg,
'plannedShippingDateAndTime'=> $plannedShipDate . 'T10:00:00',
]);
return collect($response['products'] ?? [])
->map(fn($p) => [
'product_code' => $p['productCode'],
'total_price' => $p['totalPrice'][0]['price'],
'delivery_time' => $p['deliveryCapabilities']['deliveryTypeCode'],
])
->toArray();
}
Коди продуктів: P (DHL Express Worldwide), K (DHL Express 9:00), T (DHL Express 12:00).
Створення відправлення
public function createShipment(Order $order): array
{
$payload = [
'plannedShippingDateAndTime' => now()->addDay()->format('Y-m-d') . 'T10:00:00',
'productCode' => $order->dhl_product_code ?? 'P',
'accounts' => [['number' => config('services.dhl.account_number')]],
'customerDetails' => [
'shipperDetails' => [
'postalAddress' => [
'cityName' => config('services.dhl.shipper_city'),
'countryCode' => 'RU',
'addressLine1'=> config('services.dhl.shipper_address'),
],
],
'receiverDetails' => [
'postalAddress' => [
'cityName' => $order->shipping_city,
'countryCode' => $order->shipping_country_code,
],
'contactInformation' => [
'fullName' => $order->recipient_name,
'phone' => $order->recipient_phone,
],
],
],
'content' => [
'packages' => [[
'weight' => $order->total_weight_kg,
'dimensions' => [
'length' => $order->package_length,
'width' => $order->package_width,
'height' => $order->package_height,
],
]],
'isCustomsDeclarable' => $order->is_international,
],
];
$response = $this->request('POST', '/shipments', $payload);
return [
'shipment_id' => $response['shipmentTrackingNumber'],
'label_pdf' => base64_decode($response['documents'][0]['content'] ?? ''),
];
}
Таможенна декларація
Для міжнародних відправлень:
private function buildExportDeclaration(Order $order): array
{
return [
'lineItems' => $order->items->map(fn($item) => [
'description' => $item->product->name_en,
'price' => $item->price,
'quantity' => ['value' => $item->quantity],
])->toArray(),
'invoice' => [
'number' => 'INV-' . $order->id,
'date' => now()->format('Y-m-d'),
],
];
}
Відстеження
public function trackShipment(string $trackingNumber): array
{
$response = $this->request('GET', '/tracking', ['trackingNumber' => $trackingNumber]);
$shipment = $response['shipments'][0] ?? null;
return [
'status' => $shipment['status'] ?? '',
'location'=> $shipment['location']['address']['cityName'] ?? '',
'events' => collect($shipment['events'] ?? [])->map(fn($e) => [
'timestamp' => $e['timestamp'],
'description' => $e['description'],
])->toArray(),
];
}
Замовлення курйєра
public function schedulePickup(string $date, string $timeFrom, int $parcelCount): string
{
$response = $this->request('POST', '/pickups', [
'plannedPickupDateAndTime' => $date . 'T' . $timeFrom . ':00',
'accounts' => [['number' => config('services.dhl.account_number')]],
]);
return $response['dispatchConfirmationNumber'];
}
Обмеження
DHL суворо перевіряє адреси отримувачів. Максимальна вага 70 кг, максимальна сторона 300 см. Для деяких країн обов'язково: штат/провінція.
Терміни
Розрахунок тарифу + створення відправлення + відстеження — 5–7 днів. Додавання таможенних декларацій — 2–3 дні. Тестування в sandbox — обов'язково.







