—крыть меню * ¬ерси€ дл€ печати

API почтового калькул€тора Postcalc.RU версии 2.0



1. «апрос
2. ќтвет
3. —татус ответа и ошибки
4. ќтсутствие расчета (ключ Ќет–асчета)
5. ѕредварительна€ проверка данных
6. –есурсы в помощь разработчику
7. ѕолный пример запроса на PHP к Postcalc.RU:

¬нимание!

Ќачина€ с 25 декабр€ 2019 года, дл€ доступа к API необходим ключ домена, который следует бесплатно сгенерировать в Ћичном кабинете. Ётот ключ указываетс€ в запросах:

<QUERY_STRING>&key=domain0-8a6b4c2d
 люч домена позвол€ет делать до 500 запросов в сутки по московскому времени.
ƒл€ отладки вы можете использовать тестовый ключ:
<QUERY_STRING>&key=test
„исло запросов с тестовым ключом - не более 50 с одного адреса IP за сутки по московскому времени.
ѕодробнее - см. ”слови€ использовани€ сервиса Postcalc.RU.
¬нимание!
— 16 марта 2020 года вводитс€ переменна€ p=[список кодов отправлений через зап€тую]. ѕолный список кодов приведен в таблицах ниже, на данный момент это 21 внутреннее и 16 международных отправлений. ≈сли эта переменна€ указана, то отдаютс€ расчеты только по данным видам отправлений, что значительно экономит трафик и увеличивает скорость ответа.
Ќачина€ с 01 июн€ 2020 года, на бесплатном доступе будут отдаватьс€ расчеты не более чем по п€ти внутренним или международным отправлени€м. ѕример:
<QUERY_STRING>&p=bv,pv,b1v,p1,em,isr,isar,ip,ipa,iem
¬ ответе будут: дл€ расчетов внутренних отправлений - ценна€ бандероль, посылка, ценна€ бандероль 1 класса, посылка 1 класса, EMS; дл€ международных - мелкий пакет заказной наземный/авиа, посылка наземна€/авиа, EMS с товарным вложением.
¬нимание!
ƒл€ тестов ¬аших скриптов насто€тельно прошу использовать вместо api.postcalc.ru тестовое зеркало test.postcalc.ru.
¬ы можете видеть ¬аши запросы в реальном времени, как они доход€т до сервера и что происходит. ƒл€ этого обращайтесь по ссылке:
http://reserve.postcalc.ru/mystat.html?IP=<¬аш IP>

“естовый сервер test.postcalc.ru полностью синхронизирован с рабочим сервером api.postcalc.ru, результаты расчетов совершенно одинаковые.
¬нимание!
¬ разработке насто€тельно рекомендуетс€ использовать - полностью или частично - библиотеку PostcalcLight. ќна имеет все необходимые средства дл€ предварительной проверки аргументов на правильность, а также реализует кэширование и опрос всех доступных серверов по цепочке. “акже см. раздел –есурсы в помощь разработчику.

1. «апрос

¬ы можете щелкнуть по ссылкам и посмотреть ответ сервера в читабельном виде.

ѕример 1. ћинимальный запрос. ”казаны почтовый индекс отправител€ и получател€, вес - 1000 г., ценность - 1000 рублей. ќстальные параметры будут установлены по умолчанию.
http://api.postcalc.ru/?f=101000&t=190000&w=1000&v=1000&key=test

»счерпывающий список почтовых индексов, используемых Postcalc.RU в данный момент, можно посмотреть онлайн, а также получить в составе архива баз данных PostcalcLight в формате текста или дампа MySQL (таблица postcalc_light_post_indexes).

ѕример 1а. јналогичный минимальный запрос, вместо почтового индекса указаны населенные пункты, вес - 1000 г., ценность равна нулю (по умолчанию).
http://api.postcalc.ru/?f=ћосква&t=—анкт-ѕетербург&w=1000&key=test

»счерпывающий список названий населенных пунктов, используемых Postcalc.RU в данный момент, можно посмотреть онлайн, а также получить в составе архива баз данных PostcalcLight в формате текста или дампа MySQL (таблица postcalc_light_cities).

ѕример 1b. ћинимальный запрос на международную отправку (в √ерманию). ѕараметр t= в этом случае игнорируетс€.
http://api.postcalc.ru/?f=ћосква&t=—анкт-ѕетербург&c=DE&w=1000&key=test

»счерпывающий список названий стран, используемых Postcalc.RU в данный момент, можно посмотреть онлайн, а также получить в составе архива баз данных PostcalcLight в формате текста или дампа MySQL (таблица postcalc_light_countries).

ѕример 2. –асчет дл€ физического лица без договора с ѕочтой –оссии.
http://api.postcalc.ru/?f=101000&t=190000&w=1000&v=1000&key=test&p=bv,pv,b1v,p1,em&co=0&d=now&ib=p&sv=fr,sm
Ѕудут рассчитаны:
1. ќтправлени€ - ценна€ бандероль, посылка, ценна€ бандероль 1 класса, посылка 1 класса, EMS (p=bv,pv,b1v,p1,em).
2. “арификаци€ - дл€ физического лица без договора с ѕочтой –оссии (co=0). Ёто значит, что отправлени€ дл€ корпоративных клиентов не рассчитываютс€, даже если будут запрошены, а тарифы дл€ посылок и EMS ќптимальное будут несколько выше.
3. –асчет на сегодн€шний день (d=now).
4. Ѕаза страховки - только объ€вленна€ ценность товарного вложени€ (ib=p).
5. ƒополнительные опции - хрупкое вложение и SMS получателю (sv=fr,sm).

ѕример 3. –асчет дл€ юридического лица или »ѕ, имеющего договор с ѕочтой –оссии (" орпоративный клиент").
http://api.postcalc.ru/?f=101000&t=191167&w=1000&v=1000&key=test&p=po,co,ek,ekp,emo&co=1&d=10days&ib=f&bo=m&sv=ko,op&pk=50&pr=25
Ѕудут рассчитаны:
1. ќтправлени€ - ѕосылка ќнлайн,  урьер ќнлайн, ≈ ќћ с доставкой в ќѕ— ѕочты –оссии, ≈ ќћ с доставкой в партнерский пункт выдачи, EMS ќптимальное (p=po,co,ek,ekp,emo).
2. “арификаци€ - дл€ юридического лица или »ѕ, имеющего договор с ѕочтой –оссии (" орпоративный клиент") (co=1). ƒоступны все тарифы, при этом тарифы дл€ посылок и EMS ќптимальное несколько ниже, чем дл€ физлиц.
3. ƒата расчета: сегодн€ + 10 дней (d=10days). Ёто полезна€ возможность дл€ интернет-магазинов рассчитать тариф на предполагаемую дату отправки товара.
4. Ѕаза страховки - полный возможный ущерб при утере отправлени€: сумма ценности товарного вложени€, страховки и тарифа на доставку (ib=f).
5. ƒополнительные опции - проверка комплектности и опись вложени€ (sv=ko,op).
6. ѕри расчете ≈ ќћ использовать коробку размера "ћ" (bo=m).
7. ƒобавить на каждое отправление стоимость упаковки 50 рублей (pk=50).
8. ƒобавить 25 рублей на оформление заказа (pr=25).
ќбратите внимание, что прием и выдача большинства отправлений дл€ корпоративных клиентов возможен только в специальных отделени€х св€зи. —писок этих отделений можно скачать в формате дампа MySQL (таблица postcalc_points).

ќписание полей запроса
ћнемоника
(упрощает запоминание)
ѕеременна€ ѕо умолчанию ќписание
Key key нет
 люч доступа.  люч необходимо получить в Ћичном кабинете. ¬озможно использование тестового ключа key=test (не более 50 запросов в сутки с одного IP).
ќб€зательное поле дл€ API с 25 декабр€ 2019 года. .
Parcels p ƒл€ бесплатного доступа -
bv,pv,b1v,p1,em,
is,isa,ip,ipa,iem
ƒл€ платного доступа - все возможные отправлени€
—писок кодов отправлений через зап€тую. ƒл€ бесплатного доступа - не более 5 внутренних отправлений и не более 5 международных.  оды дл€ международных отправлений начинаютс€ с i. ѕо умолчанию в ответе будут: дл€ расчетов внутренних отправлений - ценна€ бандероль, посылка, ценна€ бандероль 1 класса, посылка 1 класса, EMS; дл€ международных - мелкий пакет заказной авиа/наземный, посылка, авиапосылка, EMS с товарным вложением.  оды отправлений см. ниже.
ќпциональное поле с 16 марта 2020 года, с 01 июн€ 2020 года - об€зательное.
ѕараметр переменной p ќписание
ls ѕростое письмо
lr «аказное письмо
lv ÷енное письмо
l1r «аказное письмо 1 класса
l1v ÷енное письмо 1 класса
bs ѕроста€ бандероль
br

«аказна€ бандероль

b1r «аказна€ бандероль 1 класс
bv ÷енна€ бандероль
pv ÷енна€ посылка
b1v ÷енна€ бандероль 1 класс
p1 ѕосылка 1 класса
em  урьерска€ доставка EMS
po ”слуга "ѕосылка ќнлайн" дл€ корпоративных клиентов
co ”слуга " урьер ќнлайн" дл€ корпоративных клиентов
ek ”слуга "≈ ќћ" дл€ корпоративных клиентов (ключ пишетс€ кириллицей!) с доставкой в ѕ¬«/јѕ— ѕочты –оссии.
ekp ”слуга "≈ ќћ" дл€ корпоративных клиентов (ключ пишетс€ кириллицей!) с доставкой в ѕ¬«/јѕ— партнеров ѕочты –оссии.
emo ”слуга "EMS ќптимальное" с доставкой до ÷¬ѕѕ. ¬ ключе EMS пишетс€ латиницей, "ќптимальное" - кириллицей.
emoc ”слуга "EMS ќптимальное" с доставкой клиенту курьером. ¬ ключе EMS пишетс€ латиницей, "ќптимальное" - кириллицей.
bc ”слуга "Ѕизнес- урьер" дл€ корпоративных клиентов ѕочты –оссии.
bce ”слуга "Ѕизнес- урьер экспресс" дл€ корпоративных клиентов ѕочты –оссии.

ѕараметр переменной p ќписание
im ћеждународный мешок ћ
ima

ћеждународный мешок ћ авиа

imr ћеждународный мешок ћ заказной
imar ћеждународный мешок ћ авиа заказной
ib ћеждународна€ бандероль
iba ћеждународна€ авиабандероль
ibr ћеждународна€ бандероль заказна€
ibar ћеждународна€ авиабандероль заказна€
is ћеждународный мелкий пакет
isa ћеждународный мелкий пакет авиа
isr ћеждународный мелкий пакет заказной
isar ћеждународный мелкий пакет авиа заказной
ied ≈MS международное - документы
iem ≈MS международное - товары
ip ћеждународна€ посылка *
ipa ћеждународна€ авиапосылка *
From f нет

2 варианта (распознаютс€ автоматически).

1. Ќазвание населенного пункта отправител€, как это определено в списке населенных пунктов.  одировка - cp1251 или utf8, распознаетс€ автоматически, регистр букв значени€ не имеет, однако должны присутствовать все пробелы, скобки и дефисы. »ндекс предпри€ти€ св€зи по умолчанию: отделение св€зи, дл€ которого возможен прием/отправка наибольшего числа видов отправлений. ѕрежде всего это касаетс€ приема ѕосылки ќнлайн, приема/выдачи ≈ ќћ и EMS ќптимальное.

2. 6-значный индекс отправител€.

To t нет

2 варианта (распознаютс€ автоматически).

1. Ќазвание населенного пункта адресата, как это определено в списке населенных пунктов.  одировка - cp1251 или utf8, распознаетс€ автоматически, регистр букв значени€ не имеет, однако должны присутствовать все пробелы, скобки и дефисы. »ндекс предпри€ти€ св€зи по умолчанию: отделение св€зи, дл€ которого возможен прием/отправка наибольшего числа видов отправлений. ѕрежде всего это касаетс€ приема ѕосылки ќнлайн, приема/выдачи ≈ ќћ и EMS ќптимальное.

2. 6-значный индекс адресата.

Weight w нет ¬ес отправлени€ в граммах. Ќе более 31500 г.
Valuation v 0 ÷енность отправлени€ в рубл€х. Ќе более 250 тыс. рублей.
Date d now ƒата, на которую нужно рассчитать отправку, в любом формате, который распознаетс€ функцией PHP strtotime(). ¬ частности, распознаютс€ такие варианты: 30.01.2011, 30-01-2011, 2011-01-30, now, +10days. ѕо умолчанию - текущий момент времени (now).
Country c RU ƒвузначный код страны (дл€ международных доставок) из списка.
Software sw нет Ќеоб€зательный идентификатор плагина. ѕроизвольна€ строка латиницей (не более 30 символов), подчеркивание, номер версии (например, MyBestPlugin_1.01).
ѕозвол€ет разработчикам плагинов получить доступ к списку доменов, которые используют их плагин, статистике обращений, ошибкам и журналам запросов пользователей в реальном времени. ѕри этом никака€ лична€ информаци€ пользователей (включа€ ключ домена) разработчикам недоступна.
ƒл€ доступа к этой информации разработчикам следует написать в произвольной форме в техподдержку Postcalc.RU.
Site st нет Ќеоб€зательный идентификатор домена/сайта. —трока латиницей.
ѕолезно дл€ различени€ запросов, если в рамках одного проекта их посылают разные поддомены.
Output o html

‘ормат выдачи данных. ѕоддерживаютс€ следующие форматы: php, json, wddx, html, arr, plain. –егистр букв значени€ не имеет.
1. HTML. —траница html в читабельном виде, кодировка определ€етс€ переменной cs, удобно дл€ просмотра ответа сервера пр€мо из браузера. ѕо умолчанию - UTF-8.
2. PHP. ћассив PHP, обработанный функцией serialize().  одировка определ€етс€ переменной cs. ”добно дл€ использовани€ напр€мую в скриптах PHP, дл€ чего на стороне клиента следует использовать функцию unserialize() - см. пример в конце страницы. ѕо умолчанию - UTF-8.
3. ARR. ћассив PHP, выведенный функцией var_export().  одировка определ€етс€ переменной cs, удобно дл€ контрол€ ответов сервера из браузера. ѕо умолчанию - UTF-8.
4. WDDX (разновидность xml) - массив PHP, обработанный функцией wddx_serialize_value().  одировка UTF-8.
5. JSON - массив PHP, обработанный функцией json_encode().  одировка UTF-8 + JavaScript Object Notation (JSON). ”добно дл€ использовани€ в JavaScript.
ƒл€ выдачи в формате JSONP просто добавьте в запрос переменную callback=[Ќазвание_функции_обратного_вызова].
6. PLAIN - простой текст; это единственный вариант ответа, который не сжимаетс€ gzip.  ажда€ строчка имеет 3 пол€, разделенных пробелом: код отправлени€, доставка, срок доставки. ‘ормат экспериментальный, может изменитьс€ в любой момент.

- callback нет Ќазвание функции обратного вызова JavaScript, примен€етс€ в сочетании с форматом o=json. ≈сли сервер обнаруживает такую переменную, то возвращает ответ в формате JSONP с заголовком content-type: application/javascript. ¬ названии функции допускаютс€: латиница в любом регистре, цифры, знак подчеркивани€.
IBase ib f, с 01 июн€ 2020 г - p Ѕаза дл€ расчета страховки (только при оценке товарного вложени€ больше 0!).

≈сли IBase=p или Partial, то страхуетс€ только товарное вложение. Ќапример, посылка с оценкой 1000 рублей будет застрахована на 1000 * 4% = 40 рублей независимо от стоимости доставки.
¬ случае пропажи отправлени€ почта возместит только стоимость товара, а расходы на доставку и страховку придетс€ списать в убыток.
 роме того, при отправке наложенным платежом возникает проблема расчета суммы, которую адресат должен выплатить при получении отправлени€: ведь эта сумма больше оценки товара и должна покрывать расходы интернет-магазина на доставку и страховку

≈сли IBase=f или Full, базой страховки будет ќценка “овара + “ариф + —траховка, и в случае пропажи отправлени€ почта полностью возместит ущерб. Ёто самый оптимальный вариант дл€ отправки наложенным платежом, а конечна€ сумма, которую должен заплатить адресат - это столбец "÷енность" на веб-странице или поле ќценкаѕолна€ в ответе по API.
÷енность вычисл€етс€ по формуле: ÷енность = “ариф + ќценка вложени€ + —траховка
–азмер страхового сбора вычисл€етс€ по формуле: —траховка = ( “ариф + ќценка ) * —тавка—бора / (1 - —тавка—бора)
ProcessingFee pr 0 ѕользовательска€ наценка за обработку заказа в рубл€х.
PackingFee pk 0 ѕользовательска€ наценка за упаковку одного отправлени€ в рубл€х.
Round r 0.01 ќкругление ÷енности в верхнюю сторону до [Round] рублей. –екомендуетс€ задать Round=1 или 10, чтобы не путатьс€ с копейками.
¬се остальные данные расчета (“ариф, —траховка, ƒоставка) всегда вывод€тс€ с копейками.
VAT vt 1 ≈сли 1, Ќƒ— включен в тариф, если 0 - Ќƒ— вычитаетс€ из тарифа.
¬нимание! —ледует различать вычитание Ќƒ— дл€ целей бухгалтерского учета (возможно дл€ всех отправлений) и отправку по более низким тарифам без Ќƒ— (невозможно дл€ посылок и EMS). ѕодробнее см. вопрос  акие почтовые отправлени€ можно посылать по тарифам без Ќƒ—?
Corp co 1 ≈сли 1, расчет идет по тарифам дл€ клиентов, имеющих договор с ѕочтой –оссии ("корпоративные клиенты"), если 0 - расчет по тарифам дл€ "обычных" клиентов: физических лиц и индивидуальных предпринимателей без договора.
— 23 марта 2020 года по умолчанию - 1, до этого - 0.
ѕо состо€нию на март 2020 года касаетс€: 1. расчета ценных посылок. 2. расчета "EMS ќптимальное". 3. Ќекоторых дополнительных услуг. ƒл€ "корпоративных клиентов" тарифы несколько ниже.
Box bo s “ип коробки, определ€ет т.н. объемный вес. ≈сли объемный вес больше реального, то при расчете тарифа примен€етс€ именно он.
ѕо состо€нию на март 2020 года касаетс€ только расчета "≈ ќћ".
«начени€: s (коробка "S", 260*170*80 мм), m (коробка "M", 300*200*150 мм), l (коробка "L", 400*270*180 мм), xl (коробка "XL", 530*360*220 мм), ng (негабаритна€ коробка, сумма сторон не более 1400 мм, одна сторона не более 600 мм).
Services sv пуста€ строка ќпции отправки и дополнительные услуги . —писок кодов через зап€тую, например: sv=sm,ko,cod.
—ледует учитывать, что не все виды отправлений имеют все виды услуг и опций.
 од”слуга
fr’рупка€ (только дл€ посылок)
ngЌегабаритна€ (только дл€ посылок)
opѕроверка соответстви€ вложени€ описи
koѕроверка комплектности
ppѕредпочтова€ подготовка
smSMS получателю
sm2SMS отправителю
codќплата в момент доставки (COD)
uvѕростое уведомление о вручении
uvr«аказное уведомление о вручении
uveЁлектронное уведомление о вручении
iuvћеждународное уведомление о вручении
Partible pa 0 ќтправление €вл€етс€ делимым (можно распределить на несколько).
≈сли 0 (по умолчанию), используетс€ логика официальных калькул€торов ѕочты –оссии: отправление может быть только одно, при превышении допустимого веса и/или ценности расчет не производитс€.
≈сли 1, используетс€ логика Postcalc.RU: отправление делитс€ на несколько, контроль ценности не производитс€.
Ќапример, дл€ веса 20 кг при pa=0 расчет бандероли не производитс€, при pa=1 возвращаетс€ расчет дл€ 4-х бандеролей весом по 5 кг кажда€.
јналогично: дл€ ценности 100 тыс. рублей при pa=0 расчет ценной бандероли и EMS не производитс€ (ограничение 10 тыс. и 50 тыс. рублей соответственно), при pa=1 - производитс€
¬нимание! ƒл€ внутренних писем ограничение по весу действует в любом случае (так было в расчетах Postcalc.RU с самого начала): простое, заказное, ценное письмо рассчитываютс€ при весе не более 100 г, заказное и ценное письмо 1 класса - не более 500 г.
CashOnDelivery cod 0 —тавка в процентах наложенного платежа дл€ корпоративных клиентов ѕочты –оссии. ”станавливаетс€ согласно договору. ≈сли 0 или co=0 (клиент - физическое лицо), то переменна€ игнорируетс€ и примен€етс€ шкала ставок дл€ клиентов - физических лиц.
CashOnDelivery Min codm 0 ћинимальный наложенный платеж в рубл€х дл€ корпоративных клиентов ѕочты –оссии за одно отправление. ”станавливаетс€ согласно договору. ≈сли co=0 (клиент - физическое лицо) или cod=0 (не установлена ставка наложенного платежа дл€ корпоративных клиентов), то переменна€ игнорируетс€.
Charset cs UTF-8  одировка дл€ выходных форматов php, arr, html. ¬ данный момент распознаютс€ utf-8 и windows-1251 (можно задавать как cp1251).
ѕо умолчанию - UTF-8.
¬нимание! ƒл€ форматов json и wddx кодировка - всегда UTF-8! (ограничение функций php)

2. ќтвет

ƒекомпресси€ в API 1.0+.

ќтвет сервера Postcalc.RU всегда архивируетс€ в gzip (за исключением экспериментального формата plain). ƒл€ декомпрессии добавьте строчку:
$Request = 'http://api.postcalc.ru/?'.$QueryString;
$Response = file_get_contents($Request) or die('Can not connect!');
// ƒобавл€ем распаковку:
if ( substr($Response,0,3) == "\x1f\x8b\x08" ) $Response=gzinflate(substr($Response,10,-8));
¬нимание! Ќа платформе Ѕитрикс обнаружилось следующее нестандартное поведение: функци€ gzinflate не блокируетс€, однако после распаковки поток усекаетс€ на несколько байт (?).
ѕо всей видимости, это св€зано с установкой PHP mbstring.func_overload. ѕоэтому проводите распаковку так:
if (substr($Response, 0, 3) ==  "\x1f\x8b\x08") {
 $funcOverload = ini_get("mbstring.func_overload");
 if (in_array($funcOverload, array(2, 3, 6, 7,))) {
  $Response = gzinflate( substr($Response, 10, -1) );
  } else {
  $Response = gzinflate( substr($Response, 10, -8) );
 }
}
≈сли это не поможет, замените полностью вызов file_get_contents() с последующей декомпрессией функцией gzinflate() на аналогичный вызов fopen() с применением обработчиков компрессии:
$Request = 'http://api.postcalc.ru/?'.$QueryString;
$fp = fopen("compress.zlib://$Request", "rb");
$Response = stream_get_contents($fp);
fclose($fp);

¬нимание! ƒл€ разархивации на платформе 1C можно применить вызов из командной строки внешней программы:
ѕараметрыGET = "?f=101000&t=190000&w=1000&c=RU&o=wddx&key=test" +
"&w=" + ‘ормат(¬ес,"„√=0") +
"&v=" + ‘ормат(ќкр(÷енность),"„√=0") +
"&t=" + »ндекс;


»м€‘айлајрхива =  аталог¬ременных‘айлов() + "postcalc_new.zip";
’“ћЋ = Ќовый HTTP—оединение("api.postcalc.ru");
’“ћЋ.ѕолучить(ѕараметрыGET,»м€‘айлајрхива);
—трока оманды = """C:\Program Files\WinRar\winrar.exe"" e -y """ +  »м€‘айлајрхива + """ """ +   аталог¬ременных‘айлов() + """";
Ўелл=Ќовый COMќбъект("Wscript.Shell");
Ўелл.run(—трока оманды,1,True);
»м€‘айлаќтвета =   аталог¬ременных‘айлов() + "postcalc_new";
ј это полное решение другого программиста: 1c_postcalc_request.txt
ќчень признателен авторам, которые поделились своими решени€ми дл€ платформы 1—!

 лючи ответа

ќтвет - иерархический массив в одном из 5 форматов (см. описание ключа Output в запросе). ќбратите внимание, что большинство ключей написано кириллицей - это, на мой взгл€д, значительно упрощает работу русско€зычных программистов. 

ј. ќбщие ключи - дл€ всех видов отправлений.

 люч «начение
Status ≈сли ошибки нет, возвращает OK, иначе - код ошибки
API ¬ерси€ API.
Message —ообщение об ошибке.  люч устанавливаетс€, только если возникла ошибка (Status!='OK').
_request

Ёхо-массив переменных запроса, полученных сервером от клиента. ћожет быть полезно при отладке.

_server

ћассив следующих переменных сервера: SERVER_ADDR, REMOTE_ADDR, HTTP_HOST, HTTP_USER_AGENT, HTTP_ACCEPT_ENCODING. ћожет быть полезно при отладке.

ƒата ƒата расчета тарифа в формате √√√√-ћћ-ƒƒ.
¬ес ¬ес отправлени€ в граммах, использовавшийс€ при расчетах.
ќценка ќценка вложени€ в рубл€х, использовавша€с€ при расчетах.
—рокƒоставки Ќормативный срок доставки в сутках. ƒл€ международных отправлений устанавливаетс€ только дл€ EMS.

 лючи ќткуда и  уда - устанавливаютс€ дл€ всех отправлений; дл€ международных отправлений значени€  уда следует игнорировать. 

 люч1  люч2 «начение
ќткуда
=или=
 уда
»ндекс 6-значный индекс предпри€ти€ св€зи.
Ќазвание Ќазвание отделени€ св€зи, например, ћќ— ¬ј-523.
јдрес  јдрес отделени€ св€зи.
“елефон “елефоны отделени€ св€зи.
ћестоположениеEMS Ќазвание центра региона или субъекта федерации (см. список ћестоположений EMS).
÷ентр–егиона Ќазвание центра региона.

 люч ќграничени€ устанавливаетс€ только дл€ внутренних отправлений и только если дл€ данного почтового индекса имеютс€ ограничени€ по доставке. 

 люч1  люч2  люч3 «начение
ќграничени€ ќткуда
=или=
 уда
“ип Ѕуквенное обозначение типа ограничени€, используетс€ во внутренних процедурах PostCalc.RU. ¬арианты: 
1. «апрет - установлен только период(ы) полного запрета доставки, в остальное врем€ доставка наземна€.
2. јвиа¬есь√од-јвиа - авиадоставка от центра региона круглый год, установлен период(ы), когда возможна только авиадоставка.
3. јвиа¬есь√од-Ќаземный - комбинированна€ доставка от центра региона круглый год; установлен период(ы), когда возможна только комбинированна€ доставка. 
4. јвиа—езонно - установлен период, когда возможна только авиадоставка, в остальное врем€ доставки нет вообще.
5. «апрет* - особа€ ситуаци€, св€занна€ с ошибкой в Ёталонном справочнике ограничений: установлены периоды запрета доставки, однако имеетс€ сноска, что доставка авиа разрешена. ƒл€ этих ќѕ— точный расчет тарифа в периоды закрыти€ дл€ наземной доставки невозможен (в основном якути€).
ƒействует ƒействует ли ограничение на момент расчета. ≈сли действует, принимает значение '«јѕ–≈“' или 'ј¬»ј'.
јвиаƒоставка ѕериод доставки только авиатранспортом в формате ƒƒ.ћћ-ƒƒ.ћћ;ƒƒ.ћћ-ƒƒ.ћћ...
«апретƒоставки ѕериод полного запрета доставки в формате ƒƒ.ћћ-ƒƒ.ћћ;ƒƒ.ћћ-ƒƒ.ћћ...

 люч ћагистраль - устанавливаетс€ только дл€ внутренних отправлений, и только если имеетс€ доставка по магистрали (между центрами регионов). 

 люч1  люч2 «начение
ћагистраль ќписание ќписание маршрута, например, ћќ— ¬ј=>—јЌ “-ѕ≈“≈–Ѕ”–√
ƒоставка—тандарт  Ќормативный срок доставки посылки наземным (водным) транспортом в сутках, не счита€ дн€ подачи отправлени€.
ƒоставкајвиа Ќормативный срок доставки письменной корреспонденции, он же установлен и дл€ доставки посылок авиатранспортом. 
ƒоставка ласс1 Ќормативный срок доставки 1-м классом.

 

Ѕ.  лючи запроса, ключи ответа и значени€ дл€ внутренних отправлений (Country=RU или параметр в запросе опущен):

¬ 1-й колонке - параметры переменной p (Parcels). Ќа бесплатном доступе можно указать до 5 видов внутренних и до 5 видов международных отправлений через зап€тую.
ѕараметр переменной p јнглийский ключ ответа –усский ключ ответа ќписание
ls LetterSimple ѕростоеѕисьмо ѕростое письмо
lr LetterReg «аказноеѕисьмо «аказное письмо
lv LetterValued ÷енноеѕисьмо ÷енное письмо
l1r Letter1ClassReg «аказноеѕисьмо1 ласс «аказное письмо 1 класса
l1v Letter1ClassValued ÷енноеѕисьмо1 ласс ÷енное письмо 1 класса
bs BookpostSimple ѕроста€Ѕандероль ѕроста€ бандероль
br BookpostReg «аказна€Ѕандероль

«аказна€ бандероль

b1r Bookpost1ClassReg «аказна€Ѕандероль1 ласс «аказна€ бандероль 1 класс
bv BookpostValued ÷енна€Ѕандероль ÷енна€ бандероль
pv ParcelValued ÷енна€ѕосылка ÷енна€ посылка
b1v Bookpost1ClassValued ÷енна€Ѕандероль1 ласс ÷енна€ бандероль 1 класс
p1 Parcel1Class ѕосылка1 ласс ѕосылка 1 класса
em EMS EMS  урьерска€ доставка EMS
po ParcelOnline ѕосылкаќнлайн ”слуга "ѕосылка ќнлайн" дл€ корпоративных клиентов
co CourierOnline  урьерќнлайн ”слуга " урьер ќнлайн" дл€ корпоративных клиентов
ek EKOM ≈ ќћ ”слуга "≈ ќћ" дл€ корпоративных клиентов (ключ пишетс€ кириллицей!) с доставкой в ѕ¬«/јѕ— ѕочты –оссии.
ekp EKOMPartner ≈ ќћѕартнер ”слуга "≈ ќћ" дл€ корпоративных клиентов (ключ пишетс€ кириллицей!) с доставкой в ѕ¬«/јѕ— партнеров ѕочты –оссии.
emo EMSOptimal EMSќптимальное ”слуга "EMS ќптимальное" с доставкой до ÷¬ѕѕ. ¬ ключе EMS пишетс€ латиницей, "ќптимальное" - кириллицей.
emoc EMSOptimalCourier EMSќптимальное урьер ”слуга "EMS ќптимальное" с доставкой клиенту курьером. ¬ ключе EMS пишетс€ латиницей, "ќптимальное" - кириллицей.
bc BusinessCourier Ѕизнес урьер ”слуга "Ѕизнес- урьер" дл€ корпоративных клиентов ѕочты –оссии.
bce BusinessCourierExpress Ѕизнес урьерЁкспресс ”слуга "Ѕизнес- урьер экспресс" дл€ корпоративных клиентов ѕочты –оссии.

¬нимание! — 01 €нвар€ 2018 года вводитс€ новый ключ - ѕосылка1 ласс. ≈сли ценность посылки - 0 рублей, рассчитываетс€ тариф "обычной" посылки 1-го класса, если ценность - более 0 рублей, рассчитываетс€ тариф ценной посылки 1-го класса.

 лючи и значени€ дл€ внутренних отправлений на примере ценной бандероли:

¬ерхний уровень  люч1  люч2 «начение
$arrReply["ќтправлени€"]   ["÷енна€Ѕандероль"]   ["Ќазвание"] Ќазвание почтового отправлени€
[" оличество"] „исло почтовых отправлений с учетом максимального разрешенного веса.
["“ариф"] ѕочтовый тариф в рубл€х (без учета страховки).
["—траховка"] “олько дл€ ценных отправлений с оценкой больше 0: страховка в рубл€х.
["ƒоставка"] ƒл€ ценных отправлений с оценкой больше 0: тариф+страховка в рубл€х. ƒл€ остальных отправлений - то же самое, что тариф.
["ќценкаѕолна€"] “олько дл€ ценных отправлений: сумма оценки в рубл€х, которую необходимо дать почтовому отправлению, чтобы получить на расчетный счет сумму, равную оценке товарного вложени€. –авна: ќценка товарного вложени€ + “ариф + —траховка.
["Ќаложенныйѕлатеж"] “олько дл€ ценных отправлений: сумма в рубл€х, которую платит адресат на почте при наложенном платеже.
["Ќет–асчета"]

 люч устанавливаетс€, если тариф дл€ данного отправлени€ не может быть достоверно рассчитан. —одержит описание причины. —ледующие варианты:
1. ѕроста€, заказна€ и ценна€ бандероль/письмо по маршруту, который включает отрезки с авиадоставкой (возможен только расчет ценных отправлений).
2. ќтделение отправител€ или получател€ временно закрыто.
3. ќшибка в Ёталонном справочнике ограничений по доставке.

 

¬.  лючи запроса, ключи ответа и значени€ дл€ международных отправлений:

¬ 1-й колонке - параметры переменной p (Parcels). Ќа бесплатном доступе можно указать до 5 видов внутренних и до 5 видов международных отправлений через зап€тую.
ѕараметр переменной p јнглийский ключ ответа  люч ответа ќписание
im IntlParcelM ћждћешокћ ћеждународный мешок ћ
ima IntlParcelMAvia ћждћешокћјвиа

ћеждународный мешок ћ авиа

imr IntlParcelMReg ћждћешокћ«аказной ћеждународный мешок ћ заказной
imar IntlParcelMAviaReg ћждћешокћјвиа«аказной ћеждународный мешок ћ авиа заказной
ib IntlBookpost ћждЅандероль ћеждународна€ бандероль
iba IntlBookpostAvia ћждЅандерольјвиа ћеждународна€ авиабандероль
ibr IntlBookpostReg ћждЅандероль«аказна€ ћеждународна€ бандероль заказна€
ibar IntlBookpostAviaReg ћждЅандерольјвиа«аказна€ ћеждународна€ авиабандероль заказна€
is IntlSmallPacket ћждћелкийѕакет ћеждународный мелкий пакет
isa IntlSmallPacketAvia ћждћелкийѕакетјвиа ћеждународный мелкий пакет авиа
isr IntlSmallPacketReg ћждћелкийѕакет«аказной ћеждународный мелкий пакет заказной
isar IntlSmallPacketAviaReg ћждћелкийѕакетјвиа«аказной ћеждународный мелкий пакет авиа заказной
ied IntlEMSDocs EMS_ћждƒокументы ≈MS международное - документы
iem IntlEMSMerchandise EMS_ћжд“овары ≈MS международное - товары
ip IntlParcel ћждѕосылка ћеждународна€ посылка *
ipa IntlParcelAvia ћждѕосылкајвиа ћеждународна€ авиапосылка *
* ќфициально тарифы на посылки считаютс€ от места международного обмена почтой (ћосква или —анкт-ѕетербург). “.е. если вы отправл€ете международную посылку из ¬ладивостока, то необходимо также добавить тариф доставки до ћосквы или —анкт-ѕетербурга. ќднако на практике почтовики обычно доставку по –оссии к тарифам на международные посылки не добавл€ют.

 лючи и значени€ дл€ международных отправлений на примере международного отправлени€ EMS с товарным вложением:

 люч1  люч2 «начение
≈MS международное - товары
 
Ќазвание Ќазвание почтового отправлени€
 оличество „исло почтовых отправлений с учетом максимального разрешенного веса.
“ариф ѕочтовый тариф в рубл€х (без учета страховки).
—траховка “олько дл€ ценных отправлений с оценкой больше 0: страховка в рубл€х.
ƒоставка ƒл€ ценных отправлений с оценкой больше 0: тариф+страховка в рубл€х. ƒл€ остальных отправлений - то же самое, что тариф.
ќценкаѕолна€ “олько дл€ ценных отправлений: сумма оценки в рубл€х, которую необходимо дать почтовому отправлению, чтобы получить на расчетный счет сумму, равную оценке товарного вложени€. –авна: ќценка товарного вложени€ + “ариф + —траховка.
¬ычетЌƒ—

‘лаг. ≈сли 1, вычет Ќƒ— возможен. ≈сли 0 - Ќƒ— вычитатьс€ не будет, даже если в запросе vt=0.

÷енное

‘лаг. ≈сли 1 - допускает оценку и, соответственно, расчет страховки. ≈сли 0 - оценка отправлени€ невозможна.

“оварное

‘лаг. ≈сли 0 - таким отправлением можно посылать только книжно-журнальную продукцию и документы. ≈сли 1 - возможно товарное вложение.

 лассƒоставки

 ласс доставки. ≈сли 0 - наземна€ доставка, если 1 - премиум (авиа), если 2 - курьерска€.

3. —татус ответа и ошибки

ќтвет - иерархический массив.  люч Status содержит либо OK, либо код ошибки. ¬ последнем случае также устанавливаетс€ ключ Message с текстом ошибки.
ќшибка возвращаетс€, если невозможно выполнить расчет ни одного тарифа в принципе: неверное значение веса, нет такого почтового индекса и т.п..
≈сли невозможно выполнить только расчет конкретного тарифа, то устанавливаетс€ ключ ответа Ќет–асчета (ќтправлени€->»м€ќтправлени€->Ќет–асчета).
Ќасто€тельно рекомендуетс€ перед отправкой запроса провер€ть данные, чтобы избежать ошибок и отсутстви€ расчета.

ќшибки
Status Message ќписание
OK  орректный ответ
ERROR_NOKEY No domain key found in request. You should get the key in personal cabinet: http://www.postcalc.ru/lk. ¬ запросе имеетс€ ключ домена key=[ключ_домена]. Ёта ошибка не возникает у платных клиентов, подключенных через "белый список" адресов IP.
ERROR_BAD_KEY Domain key [key] is bad. You should get correct key in personal cabinet: http://www.postcalc.ru/lk. ¬ запросе найден ключ домена, но он не найден в списке зарегистрированных ключей.
ERROR_TESTKEY_LIMIT_50 Limit for test key reached: 50 requests in one day from one IP address (IP $RemoteIP, total $i_total). ѕревышен дневной лимит запросов с тестовым ключом key=test: не более 50 с одного IP в календарные сутки по московскому времени.
ERROR_DOMAIN_BANNED_LIMIT_500 Your domain $Domain is banned. You should pay Start Plan in Personal Cabinet: http://www.postcalc.ru/lk. ѕревышен дневной лимит запросов с ключом домена: не более 500 в календарные сутки по московскому времени.  люч блокирован. Ќеобходимо оплатить план "—тартовый" через Ћичный кабинет.
ERROR_NO_VAR_F Every request should contain correct variable f= ќтсутствует переменна€ f (почтовый индекс или населенный пункт отправител€), либо она заведомо неверна.
ERROR_NO_VAR_T Every request should contain correct variable t= ќтсутствует переменна€ t (почтовый индекс или населенный пункт получател€), либо она заведомо неверна. “олько дл€ внутренних отправлений.
ERROR_NO_VAR_W Every request should contain correct variable w= ќтсутствует переменна€ w (вес отправлени€), либо она заведомо неверна (пуста€ строка, буквы и т.п.).
ERROR_WEIGHT_EXCEEDS_LIMITS Parcel weight cannot be less than 0 and more than 31500 g. ¬ес отправлени€ превышает максимально допустимый (31500 г).
BAD_FROM_INDEX
или
BAD_TO_INDEX
Cannot find postal code - почтовый_индекс. Ќе найден почтовый 6-значный индекс отправител€ или получател€. »счерпывающий список ќѕ— онлайн находитс€ по ссылке. ≈го также можно скачать в виде таблицы MySQL.
BAD_FROM_CITY
или
BAD_TO_CITY
Cannot find city - населенный_пункт. Ќе найден почтовый населенный пункт отправител€ или получател€, заданный в переменной f= или t=. »счерпывающий список населенных пунктов онлайн находитс€ по ссылке. “ам же описание принципов, по которым этот список формируетс€. ≈го также можно скачать в виде таблицы MySQL.
BAD_COUNTRY Cannot find country - название_страны. Ќе найден двузначный код страны дл€ международной доставки (переменна€ c=).

4. ќтсутствие расчета (ключ Ќет–асчета)

¬ следующих случа€х ключ ответа “ариф равен 0 и устанавливаетс€ ключ Ќет–асчета с объ€снением причины:
1. ¬ес бандероли менее 100 г. Ќе рассчитываютс€ проста€, заказна€ и ценна€ бандероли. Ѕандероль 1 класса может весить и менее 100 г.
2. ¬ес простого, заказного, ценного письма более 100 г, вес письма 1-го класса более 500 г. Ёто ограничение действует вне зависимости от ключа pa.
3. ”становлен ключ pa=0 (неделимое отправление), при этом вес отправлени€ превышает максимально допустимый дл€ данного вида. Ќапример, если вес отправлени€ - 20 кг, не будет расчета дл€ отправки бандеролью.
4. ќѕ— полностью закрыто дл€ доставки в св€зи с сезонными ограничени€ми. Ќе рассчитываетс€ ни одно из отправлений.
5. ќѕ— закрыто дл€ наземной доставки (временно или посто€нно). Ќе рассчитываютс€ отправлени€, которые могут быть доставлены только наземным способом: простое, заказное, ценное письмо/бандероль.
6. ќѕ— не принимает данный тип отправлений. “олько дл€ отправлений ≈ ќћ и EMS ќптимальное.


5. ѕредварительна€ проверка данных

Ќасто€тельно рекомендуетс€ реализовать предварительную проверку данных до их отправки. ƒл€ этого имеютс€ следующие ресурсы.

1. ѕроверка почтового индекса, населенного пункта, кода страны - по таблицам postcalc_light_cities (населенные пункты и их индексы по умолчанию), postcalc_light_post_indexes (почтовые индексы), postcalc_light_countries (страны):
http://www.postcalc.ru/download/PostcalcLight_SQL.zip

2. ѕроверка списков пунктов приема/выдачи ≈ ќћ, приема ѕосылки ќнлайн, ÷¬ѕѕ - по таблице postcalc_points.
https://www.postcalc.ru/download/dev/tables/postcalc_points.sql.gz

3. ѕроверка допустимого веса и ценности отправлений - по таблице postcalc_parcels.
https://www.postcalc.ru/download/dev/tables/postcalc_parcels.sql.gz

6. –есурсы в помощь разработчику

1. ѕримеры на €зыке PHP:
https://www.postcalc.ru/download/dev/examples/

2 –абочие таблицы Postcalc.RU:
https://www.postcalc.ru/download/dev/tables/
postcalc_parcels - ѕолный список отправлений и их характеристики (максимальный вес, ценность, габариты, доступные опции и т.п.). ћарт 2020 года.
ekom_delivery_points - —писок пунктов приема и выдачи ≈ ќћ с опци€ми. ћарт 2020 года.
postcalc_points - —писок пунктов приема/выдачи ≈ ќћ, приема ѕосылки ќнлайн, ÷¬ѕѕ. ћарт 2020 года.
PostcalcLight_SQL.zip - “аблицы postcalc_light_cities (населенные пункты и их индексы по умолчанию), postcalc_light_post_indexes (почтовые индексы), postcalc_light_countries (страны). ќбновл€ютс€ 2 раза в мес€ц.

3 Ќекоторые источники с официального сайта ѕочты –оссии:
https://www.postcalc.ru/download/dev/pochta/

ѕо любым вопросам пишите в техподдержку на postcalc@mail.ru.

7. ѕолный пример запроса на PHP к Postcalc.RU:

ѕример использует библиотеку php-curl, которую насто€тельно рекомендуетс€ использовать в разработке, так как функци€ PHP file_get_contents() имеет р€д архитектурных недостатков.

ѕолный текст примера можно скачать здесь . ≈сли пакет php-curl не установлен и нет возможности его установить, вы можете скачать аналогичный пример без применени€ функций curl.

¬ целом насто€тельно рекомендуетс€ использовать бесплатную библиотеку PostcalcLight, котора€ дополнительно провер€ет аргументы на правильность и предлагает веб-интерфейс.

<?php
/*
ѕример обращени€ к API сервиса расчета почтовых тарифов Postcalc.RU.
–еализованы переключение на резервный сервер и кэширование ответов.
 эшировать можно в любом каталоге, который доступен дл€ записи веб-сервером.
ѕример требует библиотеки php-curl.
*/

// === »—’ќƒЌџ≈ ƒјЌЌџ≈
// = ƒанные запроса
$From      '101000';
$To        '190000';
$Weight    1000;
$Valuation 500;
$Country   'RU';
$Charset   'utf-8';    // Ќабор символов.
$Key       'test';     // “естовый ключ, не более 50 запросов в сутки. –абочий ключ необходимо получить в личном кабинете.
$Parcels   'bv,pv,p1'// «апросить расчеты по ценной бандероли, ценной посылке, ценной посылке 1-го класса.
$Corp      0;          // –асчеты дл€ физ. лиц, не имеющих договора с ѕочтой –оссии
$Services  'sm,uv';    // ќпции: пакет SMS получателю и простое уведомление
$Partible  0;          // Ќеделимое отправление (товар нельз€ отправить в нескольких посылках). 

// = ƒанные дл€ подключени€
$PostcalcServer1 'api.postcalc.ru';  // –абочий сервер Postcalc.RU
$PostcalcServer2 'test.postcalc.ru'// –езервное зеркало Postcalc.RU
$Timeout 3// ѕри недоступности рабочего сервера переключитьс€ на резервный через 3 сек.

// = ƒанные дл€ кэшировани€
$CacheDir sys_get_temp_dir(); //  аталог дл€ хранени€ кэшированных данных.
$CacheValid 600//  эш действителен в течение 600 сек.

// === —ќЅ—“¬≈ЌЌќ –ј—„≈“ 
header("Content-Type: text/html; charset=$Charset");

// ‘ормируем строку запроса со всеми необходимыми переменными
// ‘ункци€ rawurlencode об€зательна, если в качестве $From и $To выступают названи€ населенных пунктов. 
$QueryString  'f='  .rawurlencode$From );
$QueryString .= '&t=' .rawurlencode$To );
$QueryString .= "&w=$Weight&v=$Valuation&c=RU&o=php&cs=$Charset&key=$Key";
$QueryString .= "&p=$Parcels&co=$Corp&sv=$Services&pa=$Partible";

// ќчищаем кэш от устарелых данных - все файлы старше $CacheValid сек.
$TimestampNow time();
foreach ( 
glob("$CacheDir/postcalc_*.txt") as $CacheFile 
    if ( (
$TimestampNow filemtime($CacheFile) )  > $CacheValid unlink$CacheFile );

// ѕровер€ем в кэше, не было ли уже такого запроса
$CacheFile $CacheDir'/postcalc_' .md5($QueryString) .'.txt';

if ( 
file_exists$CacheFile ) ) {
    echo 
"Ќайдено в кэше!<br>\n";
    
$arrResponse unserializefile_get_contents($CacheFile) );
} else {
    
// »нициализируем curl
    
if ( function_exists('curl_init') ) {
        
$curl curl_init();
        
curl_setopt_array($curl
            array( 
                
CURLOPT_RETURNTRANSFER => 1,
                
CURLOPT_CONNECTTIMEOUT => $Timeout,
                
CURLOPT_HTTPHEADER => array('Connection: close''Accept-Encoding: gzip'),
                
CURLOPT_USERAGENT => phpversion()
            )
        );
    } else {
        die(
"Ќе установлен пакет php-curl!");
    }
    
    
// —оедин€емс€ с рабочим сервером
    
curl_setopt($curlCURLOPT_URL"http://$PostcalcServer1/?$QueryString");
    
$Response curl_exec($curl);
    if ( !
$Response curl_exec($curl) ) {
       
// ≈сли по какой-то причине рабочий сервер недоступен, переходим на резервное зеркало
       
curl_setopt($curlCURLOPT_URL"http://$PostcalcServer2/?$QueryString");
       if ( !
$Response curl_exec($curl) ) {
           die(
"Ќе удалось соединитьс€ с $PostcalcServer1 и $PostcalcServer2 в течение $Timeout сек.!");
       }    
    }
    
curl_close($curl);
    
    
// –азархивируем ответ
    
if ( substr($Response,0,3) == "\x1f\x8b\x08" )  $Response=gzinflate(substr($Response,10,-8));
    
    
// ѕереводим ответ в массив PHP
    
$arrResponse unserialize($Response);
    
    
// ќбработка ошибки
    
if ( $arrResponse['Status'] != 'OK' ) die("—ервер вернул ошибку: $arrResponse[Status]!");

    
// ≈сли ошибки не было, сохран€ем ответ в кэше
    
file_put_contents($CacheFile$Response);

}

// === ¬џ¬ќƒ –≈«”Ћ№“ј“ќ¬

// ¬ыводим значение тарифа дл€ ценной посылки
echo '“ариф на ценную посылку: '$arrResponse['ќтправлени€']['÷енна€ѕосылка']['“ариф'];
//  ¬ыводим в цикле стоимость доставки дл€ всех доступных отправлений:
echo "\n<pre>ѕолна€ стоимость доставки\n";
foreach  ( 
$arrResponse['ќтправлени€'] as $parcel )
                          echo 
"$parcel[Ќазвание]\t$parcel[ƒоставка]\n";

echo 
"</pre>\n";

(c) PostCalc.RU 2010-20



яндекс.ћетрика

Time elapsed: 0.01515