Інтеграція служби доставки Пошти России на сайт
Пошта Росії — найширша мережа доставки в країні: відділення є навіть там, де немає інших служб. API Пошти (pochta.ru) дозволяє розраховувати вартість, створювати замовлення, замовляти курйєра й відстежувати посилки. REST + JSON з авторизацією через токен.
Авторизація
Пошта Росії використовує токени, які видаються в особистому кабінеті. Для деяких методів — базова авторизація (логін + пароль у base64), для інших — AccessToken:
class RussianPostClient
{
private string $baseUrl = 'https://otpravka-api.pochta.ru/1.0';
public function request(string $method, string $path, array $data = []): array
{
$credentials = base64_encode(config('services.russian_post.login') . ':' . config('services.russian_post.password'));
$response = Http::withHeaders([
'Authorization' => 'AccessToken ' . config('services.russian_post.token'),
'X-User-Authorization' => 'Basic ' . $credentials,
'Content-Type' => 'application/json;charset=UTF-8',
])->{strtolower($method)}($this->baseUrl . $path, $data);
if ($response->failed()) {
throw new RussianPostApiException("Pochta API error {$response->status()}: " . $response->body());
}
return $response->json() ?? [];
}
}
Нормалізація адреси
Перед створенням замовлення адреса повинна бути нормалізована:
public function normalizeAddress(string $rawAddress): array
{
$response = Http::post($this->baseUrl . '/clean/address', [
['id' => '1', 'original-address' => $rawAddress]
]);
$result = $response->json('0');
if ($result['quality-code'] === 'UNDEF_05') {
throw new \InvalidArgumentException('Адреса не знайдена');
}
return [
'index' => $result['index'],
'city' => $result['place'],
'street' => $result['street'],
];
}
Розрахунок стоимости
public function calculateDelivery(
string $fromIndex,
string $toIndex,
string $mailType,
int $weightGrams
): array {
$response = $this->request('POST', '/tariff', [
'index-from' => $fromIndex,
'index-to' => $toIndex,
'mail-category' => 'ORDINARY',
'mail-type' => $mailType,
'mass' => $weightGrams,
]);
return [
'total_kopecks' => $response['total-rate'],
'delivery_days_min' => $response['delivery-time']['min-days'] ?? null,
'delivery_days_max' => $response['delivery-time']['max-days'] ?? null,
];
}
Тип відправлення: POSTAL_PARCEL, ECOM_MARKETPLACE, EMS.
Створення замовлення й пакетна обробка
public function createOrder(Order $order): array
{
$payload = [[
'order-num' => (string)$order->id,
'index-to' => $order->normalized_index,
'place-to' => $order->normalized_city,
'street-to' => $order->normalized_street,
'mail-type' => 'POSTAL_PARCEL',
'mass' => (int)($order->total_weight_kg * 1000),
'recipient-name' => $order->recipient_name,
'tel-address' => preg_replace('/\D/', '', $order->recipient_phone),
]];
$response = $this->request('PUT', '/user/backlog', $payload);
return [
'result_id' => $response[0]['result-id'],
'barcode' => $response[0]['barcode'] ?? null,
];
}
public function createBatch(string $batchName, array $orderIds): void
{
$this->request('POST', "/batch/{$batchName}/backlog", $orderIds);
}
Відстеження
Пошта Росії надає окремий API для відстеження:
public function trackParcel(string $barcode): array
{
$response = Http::get('https://tracking.pochta.ru/tracking/api/v1/operations-history', [
'Barcode' => $barcode,
'Language' => 'RUS',
]);
return collect($response->json('OperationHistoryData.historyRecord'))
->map(fn($op) => [
'date' => $op['OperationParameters']['OperDate'],
'type' => $op['OperationParameters']['OperType']['Name'],
'city' => $op['AddressParameters']['DestinationAddress']['PostalAddress']['City'] ?? '',
])->toArray();
}
Пакетна друк етикеток
public function printLabels(array $orderIds, string $sendingType = 'ONE_SIDED'): string
{
$response = Http::post($this->baseUrl . '/forms/orders/backlog?' . http_build_query([
'print-type' => $sendingType,
]), $orderIds);
return $response->body();
}
Особливості
Максимальна вага 20 кг, максимальний обсяг 2 м³. Sandbox: той же URL з тестовими credentials. Реальні посилки не створюються, але ШПІ генеруються.
Терміни
Розрахунок тарифу + нормалізація адреси + створення замовлень + етикетки — 6–8 робочих днів. Складніше, ніж CDEK, через двошаговую модель і окремий API відстеження.







