Интеграция службы доставки Белпочты на сайт
Белпочта — национальный почтовый оператор Беларуси. Для интернет-магазинов, работающих с белорусскими покупателями, интеграция Белпочты обеспечивает доставку по всей стране с охватом самых удалённых населённых пунктов. API Белпочты менее зрелое, чем у российских служб, поэтому часть функционала реализуется через собственные расчёты на основе официальных тарифных таблиц.
Статус API
На момент написания Белпочта предоставляет API через личный кабинет корпоративным клиентам. Для небольших магазинов без договора с Белпочтой расчёт стоимости строится на основе публичных тарифных таблиц, размещённых на официальном сайте.
Расчёт по тарифным таблицам
Тарифы Белпочты структурированы по весовым категориям и зонам доставки (внутри Минска, по Беларуси, международные):
class BelpochtaTariffCalculator
{
// Тарифы на посылки внутри Беларуси (актуальны на 2025 год, BYN)
private array $domesticParcels = [
// [макс_вес_кг => базовая_цена_BYN]
0.1 => 3.20,
0.25 => 3.70,
0.5 => 4.30,
1.0 => 5.10,
2.0 => 6.40,
3.0 => 7.70,
5.0 => 9.60,
10.0 => 13.50,
15.0 => 17.20,
20.0 => 20.80,
31.5 => 25.60,
];
// Надбавка за доставку до двери (курьер)
private float $courierSurcharge = 3.50;
// Объявленная ценность: 0.5% от суммы, минимум 0.50 BYN
public function calculateDeclaredValueFee(float $value): float
{
return max(0.50, $value * 0.005);
}
public function calculate(
float $weightKg,
bool $toDoor = false,
float $declaredValue = 0,
string $type = 'parcel' // parcel, small_packet, ems
): array {
$basePrice = null;
foreach ($this->domesticParcels as $maxWeight => $price) {
if ($weightKg <= $maxWeight) {
$basePrice = $price;
break;
}
}
if ($basePrice === null) {
throw new \InvalidArgumentException('Вес превышает максимально допустимый (31.5 кг)');
}
$total = $basePrice;
if ($toDoor) {
$total += $this->courierSurcharge;
}
if ($declaredValue > 0) {
$total += $this->calculateDeclaredValueFee($declaredValue);
}
return [
'base' => $basePrice,
'courier_fee' => $toDoor ? $this->courierSurcharge : 0,
'declared_fee' => $declaredValue > 0 ? $this->calculateDeclaredValueFee($declaredValue) : 0,
'total' => round($total, 2),
'currency' => 'BYN',
'min_days' => 3,
'max_days' => 14,
];
}
}
Интеграция через корпоративный API
Для клиентов с договором доступен API через личный кабинет. Авторизация — API-ключ в заголовке:
class BelpochtaApiClient
{
private string $baseUrl = 'https://api.belpochta.by/v1';
public function calculateShipping(array $params): array
{
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . config('services.belpochta.api_key'),
'Content-Type' => 'application/json',
])->post($this->baseUrl . '/calc', [
'from_index' => $params['from_index'],
'to_index' => $params['to_index'],
'weight' => (int)($params['weight_kg'] * 1000), // граммы
'length' => $params['length'] ?? 0,
'width' => $params['width'] ?? 0,
'height' => $params['height'] ?? 0,
'service_type'=> $params['service_type'] ?? 'PARCEL',
]);
return $response->json();
}
public function createOrder(array $orderData): array
{
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . config('services.belpochta.api_key'),
])->post($this->baseUrl . '/orders', $orderData);
if ($response->failed()) {
throw new BelpochtaException('Order creation failed: ' . $response->body());
}
return $response->json();
}
}
Почтовые индексы Беларуси
Белорусские индексы — 6-значные. Формат: XXXXXX. Минск — индексы от 220000 до 220137. При вводе адреса стоит добавить валидацию:
public function validateBelarusPostalCode(string $code): bool
{
return (bool)preg_match('/^2[0-9]{5}$/', $code);
}
// Определение города по индексу через справочник ФИАС-BY
public function getCityByIndex(string $postalCode): ?string
{
return Cache::remember("belpochta_city_{$postalCode}", now()->addWeek(), function () use ($postalCode) {
$response = Http::get('https://api.belpochta.by/v1/address/by-index', [
'index' => $postalCode,
]);
return $response->json('city');
});
}
EMS Белпочта
Для срочных отправлений — сервис EMS. Сроки доставки по Беларуси: 1–3 рабочих дня до областных центров, 2–5 дней — малые населённые пункты.
public function calculateEms(string $fromIndex, string $toIndex, float $weightKg): array
{
// EMS-тарифы отличаются от обычных посылок
$emsTariffs = [
0.5 => 8.50,
1.0 => 10.20,
2.0 => 13.40,
5.0 => 19.60,
10.0 => 28.90,
20.0 => 42.50,
31.5 => 58.00,
];
$price = null;
foreach ($emsTariffs as $maxWeight => $tariff) {
if ($weightKg <= $maxWeight) {
$price = $tariff;
break;
}
}
return [
'cost' => $price,
'currency' => 'BYN',
'min_days' => 1,
'max_days' => 3,
];
}
Отслеживание через публичный трекинг
Белпочта предоставляет страницу отслеживания. Для программного отслеживания без договора используется парсинг или неофициальное API:
public function trackParcel(string $trackNumber): array
{
// Официальный трекинг: https://www.belpochta.by/track/
// Для корпоративных клиентов — API
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . config('services.belpochta.api_key'),
])->get($this->baseUrl . '/tracking/' . $trackNumber);
if ($response->notFound()) {
return ['error' => 'Отправление не найдено'];
}
return collect($response->json('events') ?? [])
->map(fn($e) => [
'date' => $e['date'],
'time' => $e['time'],
'status' => $e['operation'],
'place' => $e['place'],
'index' => $e['index'],
])
->toArray();
}
Особенности для интернет-магазинов
Наложенный платёж через Белпочту требует отдельного договора. Комиссия за наложенный платёж — 1.5% от суммы, минимум 0.70 BYN. При наложенном платеже деньги переводятся отправителю банковским переводом.
Максимальная сумма наложенного платежа — 500 BYN на одну посылку. Для более дорогих товаров нужна предоплата или другие способы расчёта.
Конвертация валют
Если магазин работает в рублях, а Белпочта — в BYN, нужна конвертация:
public function convertToDisplayCurrency(float $byn, string $targetCurrency = 'RUB'): float
{
$rate = Cache::remember("exchange_rate_BYN_{$targetCurrency}", now()->addHour(), function () use ($targetCurrency) {
$response = Http::get('https://api.nbrb.by/exrates/rates/' . $targetCurrency, [
'periodicity' => 0,
]);
return $response->json('Cur_OfficialRate');
});
return round($byn * $rate, 2);
}
Нацбанк Беларуси предоставляет бесплатное API курсов валют.
Сроки
Базовый калькулятор по тарифным таблицам — 2–3 дня. Полная интеграция с API (требует договора с Белпочтой) — 5–7 дней.







