Быстрый расчет доставки посылок почтой РФ

Приветствую.
На одном сайте понадобилось считать стоимость доставки посылок почтой РФ из г. Благовещенск в г. Москва. Решил с помощью API сайта postcalc.ru



Делюсь. Конструктивная критика и советы приветствуются.

1. Создаем сниппет postCalc
<?php
// Инициализируем curl
$curl = curl_init();
curl_setopt_array($curl, 
    array( 
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_HTTPHEADER => array('Connection: close', 'Accept-Encoding: gzip'),
        CURLOPT_USERAGENT => phpversion()
    )
);

//Значения по умолчанию
if (!$from) $from = "675011";       //индекс отправителя (г.Благовещенск Амурской обл.)
if (!$to) $to = "101000";           //индекс получателя (г.Москва)
if (!$weight) $weight = "1000";     //вес в граммах
if (!$val) $val = "0";              //ценность посылки в рублях
if (!$post_type) $post_type = 0;    //тип отправления

//Формируем запрос
curl_setopt($curl, CURLOPT_URL, "http://api.postcalc.ru/?f=".$from."&t=".$to."&w=".$weight."&v=".$val."&o=php");

//Отправляем запрос на сервер
$Response = curl_exec($curl);
curl_close($curl);

// Разархивируем ответ сервера api.postcalc.ru
if (substr($Response,0,3) == "\x1f\x8b\x08") &#123;
    $Response = gzinflate(substr($Response,10,-8));
&#125;

//Преобразуем ответ в массив
$arrResponse = unserialize($Response);  

switch ($post_type)&#123;
    case 0: $post_type = "ЦеннаяПосылка";break;
    case 1: $post_type = "Посылка1Класс";break;
    case 2: $post_type = "EMS";break;
&#125;;

//Массив плейсхолдеров
$placeholders = array(
    'from_index' => $from,
    'to_index' => $to,
    'weight' => $weight,
    'val_price' => $val,
    'type' => $arrResponse&#91;'Отправления'&#93;&#91;$post_type&#93;&#91;'Название'&#93;,
    'price' => $arrResponse&#91;'Отправления'&#93;&#91;$post_type&#93;&#91;'Тариф'&#93;,
    'insurance' => $arrResponse&#91;'Отправления'&#93;&#91;$post_type&#93;&#91;'Страховка'&#93;,
    'cost' => $arrResponse&#91;'Отправления'&#93;&#91;$post_type&#93;&#91;'Доставка'&#93;,
    'time' => $arrResponse&#91;'Отправления'&#93;&#91;$post_type&#93;&#91;'СрокДоставки'&#93;
);
// Устанавливаем плейсхолдеры с префиксом
$modx->setPlaceholders($placeholders, 'postcalc.');

2. Создаем ресурс Расчет доставки
&#91;&#91;!postCalc? 
    &from=&#96;675011&#96;
    &to=&#96;101000&#96;
    &weight=&#96;1000&#96;
    &val=&#96;100&#96;
    &post_type=&#96;1&#96;
&#93;&#93;

<p>Тип отправления: <b>&#91;&#91;+postcalc.type&#93;&#93;</b></p>
<p>Индекс отправителя: <b>&#91;&#91;+postcalc.from_index&#93;&#93;</b></p>
<p>Индекс получателя: <b>&#91;&#91;+postcalc.to_index&#93;&#93;</b></p>
<p>Вес отправления: <b>&#91;&#91;+postcalc.weight&#93;&#93; г.</b></p>
<p>Ценность отправления: <b>&#91;&#91;+postcalc.val_price&#93;&#93; р.</b></p>
<p>Тариф: <b>&#91;&#91;+postcalc.price&#93;&#93; р.</b> <br />(Почтовый тариф в рублях без учета страховки)</p>
<p>Страховка: <b>&#91;&#91;+postcalc.insurance&#93;&#93; р.</b> <br />(Только для ценных отправлений с оценкой больше 0: страховка в рублях)</p>
<p>Полная стоимость: <b>&#91;&#91;+postcalc.cost&#93;&#93; р.</b> <br />(Для ценных отправлений с оценкой больше 0: тариф + страховка в рублях. Для остальных отправлений - то же самое, что тариф)</p>
<p>Срок доставки: <b>&#91;&#91;+postcalc.time&#93;&#93; дн.</b> <br />(Сроки примерные, но ориентироваться можно, как показала практика)</p>

Здесь параметры:
&from — индекс города отправителя
&to — индекс города получателя
&weight — вес посылки в граммах
&val — ценность посылки в рублях
&post_type — тип отправления (0 — ценная посылка, 1 — отправление первым классом, 2 — отправление ЕМС)

Сумма наложенного платежа в районах Крайнего Севера отличается, смотри документацию к API.

Ссылки:
http://postcalc.ru/api.html — документация к API
Василий Stepanov
05 июня 2018, 20:20
2
325
+6

Комментарии: 1

Пётр Молчанов
06 июня 2018, 09:39
+1
Раньше тоже их использовал, но у почты есть собственный калькулятор otpravka.pochta.ru/specification#/nogroup-rate_calculate
100% актуальность данных + был момент, что postcalc.ru не передавал данные, что доставка до указанного пункта не доступна (из-за погоды было)