Способ подсчета стоимости почтовых отправлений на PHP

в 10:56, , рубрики: curl, php, Веб-разработка, КодоБред, почта россии, тарификация, метки: , , ,

Пару дней назад мои хорошие знакомые из магазина http://www.sakura-shop.ru/ попросили меня посмотреть, почему при оформлении заказа не подсчитывается стоимость отправлений через почту России.

У меня тоже есть несколько магазинов. И на одном из них http://sumki.natropinkah.ru использовался похожий метод расчета. Проверив его работу, я был неприятно удивлен: алгоритм выдавал ошибку.

Пришлось лечить.

Мне известны несколько способов считать почту.

Один из них заключается в сборе текущих тарифов и самостоятельном подсчете стоимости пересылки. Но тарифы меняются, меняется алгоритм расчета. Более того, расчетная стоимость отличается от итоговой суммы, которую узнаешь уже в почтовом отделении. После анализа около 50-ти случайным образом взятых почтовых чеков, этот метод был отброшен.

Мною не был найден API почты, что породило другой способ подсчета. Он прост, и в его основе лежит парсинг выдаваемых скриптом http://www.russianpost.ru/autotarif/SelautotarifRus.aspx данных. Конечно, почта уже не раз меняла скрипт, и перебои с расчетом тоже случались, но этот способ мне показался более эффективным. В первую очередь потому, что сумма расчета лучше отражала реальное положение дел. Погрешность составляла не более 100 рублей.

Есть и другие способы расчета, но остановимся пока на парсинге.

Скрипт у моих друзей изначально выглядел так:

$url = "http://www.russianpost.ru/autotarif/Autotarif.aspx?viewPost=53&countryCode=643&typePost=4&viewPostName=asd&countryCodeName=asd&typePostName=asd&weight={$ves}&value1={$cennost}&postOfficeId={$indeks}";
$result = file_get_contents($url);

Далее шел парсинг и бралось содержимое тега с id=«TarifValue».

Тут я поставил брейк и пошел смотреть получаемый файл. Вот, что я увидел:

<html><head></head><body onload="document.myform.submit();"><form method="post" name="myform" style="visibility:hidden;"><input id="key" name="key" value="959114"/><input type="submit"/></form></body></html>

Интересно. Получается, почтовикам не нравится, что мы дергаем их сервер, и они решили придумать защиту.

Давайте дадим им POST.

$key = substr($result,strpos($result,'value="')+7,6);
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_POSTFIELDS, 'key='.$key);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec( $ch );

Но и тут оказалось все очень интересно.

<html><head></head><body onload="window.location.replace(window.location.toString())"></body></html>

Продублировав запрос, я получил желаемое. Вот скрипт полностью:

$url = "http://www.russianpost.ru/autotarif/Autotarif.aspx?viewPost=53&countryCode=643&typePost=4&viewPostName=asd&countryCodeName=asd&typePostName=asd&weight={$ves}&value1={$cennost}&postOfficeId={$indeks}";
$result = file_get_contents($url);
$key = substr($result,strpos($result,'value="')+7,6);
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_POSTFIELDS, 'key='.$key);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec( $ch );
$result = curl_exec( $ch );

На текущий момент систему я победил. Пока почтовики еще что-нибудь не придумают. Пользуйтесь на здоровье.

Автор: valkoivo

  1. Роман:

    Пытался адаптировать ваш скрипт для вытаскивания трекинга посылки (там механизм тот же через key) и ничего не получается :(

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js