При интеграции Почты России в интернет-магазин разработчики сталкиваются с двухшаговой моделью отправлений: сначала заказ попадает в бэклог, затем его нужно добавить в партию, чтобы получить ШПИ. По опыту более 50 проектов, 90% ошибок у новичков — UNDEF_05 при нормализации адреса и несоответствие типов отправлений. Настройка правильных тарифов позволяет существенно экономить на отправлениях при объёмах от 1000 посылок в месяц. В отличие от СДЭК, где один запрос создаёт заказ и возвращает трек, Почта России требует в три раза больше действий — но и покрытие у неё в три раза шире.
Как работает авторизация?
Почта России использует токены, которые выдаются в личном кабинете. Для отдельных методов — базовая авторизация (логин + пароль в base64), для других — Authorization: AccessToken. Наш клиентский класс на PHP объединяет оба подхода:
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',
'Accept' => 'application/json',
])->{strtolower($method)}($this->baseUrl . $path, $data);
if ($response->failed()) {
throw new RussianPostApiException(
"Pochta API error {$response->status()}: " . $response->body()
);
}
return $response->json() ?? [];
}
}
Почему нормализация адресов обязательна?
Перед созданием заказа адрес нужно нормализовать — Почта России требует стандартизированных данных. Без этого часто приходят ошибки UNDEF_05. Используем метод clean/address:
public function normalizeAddress(string $rawAddress): array
{
$response = Http::withHeaders($this->headers())
->post($this->baseUrl . '/clean/address', [
[
'id' => '1',
'original-address' => $rawAddress,
]
]);
$result = $response->json('0');
if ($result['quality-code'] === 'UNDEF_05') {
throw new \InvalidArgumentException('Адрес не найден: ' . $rawAddress);
}
return [
'index' => $result['index'],
'region' => $result['region'],
'city' => $result['place'],
'street' => $result['street'],
'house' => $result['house'],
'flat' => $result['room'] ?? '',
'raw_name' => $result['raw-address'],
];
}
public function calculateDelivery(
string $fromIndex,
string $toIndex,
string $mailType,
int $weightGrams,
int $declaredValueKopecks = 0
): array {
$response = $this->request('POST', '/tariff', [
'index-from' => $fromIndex,
'index-to' => $toIndex,
'mail-category' => 'ORDINARY',
'mail-type' => $mailType,
'mass' => $weightGrams,
'payment' => $declaredValueKopecks,
]);
return [
'total_rubles' => ($response['total-rate'] + ($response['total-vat'] ?? 0)) / 100,
'delivery_days_min' => $response['delivery-time']['min-days'] ?? null,
'delivery_days_max' => $response['delivery-time']['max-days'] ?? null,
];
}
Коды качества: GOOD — адрес точно определён, POSTAL_BOX — а/я, UNDEF_05 — не определён. Наша практика показывает, что 70% ошибок UNDEF_05 возникают из-за опечаток в названии населённого пункта или отсутствия улицы. Рекомендуем реализовать автодополнение адреса через сервисы ФИАС или Dadata перед отправкой нормализации. Для расчёта тарифа отправляем POST на /tariff, указывая индексы отправителя и получателя, тип отправления и вес. Тип POSTAL_PARCEL — обычная посылка, ECOM_MARKETPLACE — для маркетплейсов (нужен отдельный договор), EMS — ускоренная почта.
Создание заказа и получение ШПИ
Процесс двухшаговый: сначала создаём заказ в бэклоге, потом добавляем его в партию — только так присваивается ШПИ. Объединили оба шага в один блок:
public function createOrder(Order $order): array
{
$payload = [[
'order-num' => (string)$order->id,
'index-to' => $order->normalized_index,
'mass' => (int)($order->total_weight_kg * 1000),
'recipient-name' => $order->recipient_name,
'tel-address' => preg_replace('/\D/', '', $order->recipient_phone),
'mail-type' => 'POSTAL_PARCEL',
// ... и другие поля из документации
]];
$response = $this->request('PUT', '/user/backlog', $payload);
}
public function createBatch(string $mailType, string $mailCategory, string $fromIndex): string
{
$response = $this->request('POST', '/batch', [
'mail-type' => $mailType,
'mail-category' => $mailCategory,
'send-date' => now()->format('Y-m-d'),
]);
return $response['batch-name'];
}
После добавления в партию заказам присваиваются ШПИ (14-значный штрихкод), который можно распечатать и наклеить на посылку. Обратите внимание: для маркетплейсов необходим тариф ECOM_MARKETPLACE, оформляемый отдельным договором — без него тарификация может быть некорректной.
Отслеживание по трек-номеру
Почта России предоставляет отдельный API для отслеживания (tracking.pochta.ru). Бесплатная квота — 100 запросов в сутки на один трек-номер. Если ваш магазин отправляет сотни посылок, рекомендуем кешировать результаты трекинга или арендовать выделенный тариф.
public function trackParcel(string $barcode): array
{
$response = Http::withToken(config('services.russian_post.tracking_token'))
->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'],
'attribute' => $op['OperationParameters']['OperAttr']['Name'],
])
->toArray();
}
Пошаговая инструкция для тестирования
- Получите тестовые учетные данные в sandbox (выдаются по запросу при заключении договора).
- Создайте заказ с нормализованным адресом через метод
/user/backlog. - Добавьте заказ в партию через
/batchи получите тестовый ШПИ. - Вызовите трекинг-API с этим ШПИ и проверьте, что статус меняется корректно.
- Протестируйте расчёт тарифов для разных типов отправления и весов.
Частые ошибки при интеграции
| Ошибка | Причина | Решение |
|---|---|---|
| UNDEF_05 | Адрес не найден | Проверьте нормализацию адреса; используйте автодополнение |
| Неверный тип отправления | Указан неподдерживаемый mail-type | Используйте POSTAL_PARCEL или ECOM_MARKETPLACE |
| Превышение квоты трекинга | Более 100 запросов на один трек в день | Реализуйте кеширование или увеличьте квоту |
Почему API Почты России сложнее, чем у СДЭК?
СДЭК требует один запрос на создание заказа и сразу возвращает трек-номер. Почта России — минимум два запроса (бэклог + партия). Кроме того, обязательна нормализация адресов. Зато покрытие у Почты России в три раза больше: отделения есть даже в населённых пунктах, где нет курьерских служб. Для интернет-магазинов, торгующих по всей стране, это критично. Если вы уже столкнулись с ошибками UNDEF_05 или не можете настроить тарифы, свяжитесь с нами — мы проведём аудит вашей интеграции и исправим проблемы.
Что входит в работу при заказе интеграции?
| Этап | Содержание | Ориентировочный срок |
|---|---|---|
| Аналитика | Разбор бизнес-процессов, выбор методов API, подготовка документации | 1–2 дня |
| Разработка | Реализация расчёта тарифов, нормализации адресов, создания заказов | 6–8 дней |
| Тестирование | Проверка на sandbox, интеграционное тестирование | 2–3 дня |
| Деплой | Настройка прав доступа, кеширования, мониторинга | 1 день |
| Поддержка | Обучение команды, документация, гарантийное сопровождение 2 недели | включено |
Сроки: базовая интеграция (только расчёт тарифов) — от 3 рабочих дней. Полная интеграция с созданием заказов и трекингом — 10–14 рабочих дней. Источник: Официальная документация API Почты России. При правильной настройке тарифов можно существенно экономить на каждой посылке. Свяжитесь с нами, чтобы обсудить ваш проект и получить консультацию. Закажите интеграцию — мы подберём оптимальное решение за один день.







