Skip to content

Instantly share code, notes, and snippets.

@reinhurd
Last active April 4, 2025 19:16
Show Gist options
  • Save reinhurd/bf16877c49140c913b1fae1095f8ca16 to your computer and use it in GitHub Desktop.
Save reinhurd/bf16877c49140c913b1fae1095f8ca16 to your computer and use it in GitHub Desktop.
Апи ФНС РФ по выдаче информации о чеках - рабочая схема подключения на ПХП
<?php
//скрыть, если не пользуетесь прокси.
$proxy="127.0.0.1:1337";
$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
curl_setopt ($ch, CURLOPT_PROXYTYPE, 7);
curl_setopt_array($ch, array(
CURLOPT_URL => "https://openapi.nalog.ru:8090/open-api/AuthService/0.1?wsdl",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"
<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"urn://x-artefacts-gnivc-ru/inplat/servin/OpenApiMessageConsumerService/types/1.0\">
<soapenv:Header/>
<soapenv:Body>
<ns:GetMessageRequest>
<ns:Message>\n<tns:AuthRequest xmlns:tns=\"urn://x-artefacts-gnivc-ru/ais3/kkt/AuthService/types/1.0\">
<tns:AuthAppInfo>
<tns:MasterToken>/*YOUR MASTER TOKEN HERE*/</tns:MasterToken>
</tns:AuthAppInfo>
</tns:AuthRequest>
</ns:Message>
</ns:GetMessageRequest>
</soapenv:Body>
</soapenv:Envelope>",
CURLOPT_HTTPHEADER => array(
"Content-Type: text/xml"
),
));
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
//echo $response;
echo $error;
//echo html_entity_decode($response);
$dom = new DOMDocument();
$dom->loadXML($response);
foreach($dom->getElementsByTagName('Token') as $element){
$tempToken = $element->nodeValue;
}
$temptoken = $tempToken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
curl_setopt ($ch, CURLOPT_PROXYTYPE, 7);
curl_setopt_array($ch, array(
CURLOPT_URL => "https://openapi.nalog.ru:8090/open-api/ais3/KktService/0.1?wsdl",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns:ns=\"urn://x-artefacts-gnivc-ru/inplat/servin/OpenApiAsyncMessageConsumerService/types/1.0\">
<soapenv:Header/>
<soapenv:Body>
<ns:SendMessageRequest>
<ns:Message>
<tns:GetTicketRequest xmlns:tns=\"urn://x-artefacts-gnivc-ru/ais3/kkt/KktTicketService/types/1.0\">
<tns:GetTicketInfo>
<tns:Sum>12500</tns:Sum>
<tns:Date>2020-04-23T12:08:00</tns:Date>
<tns:Fn>9287440300077658</tns:Fn>
<tns:TypeOperation>1</tns:TypeOperation>
<tns:FiscalDocumentId>166865</tns:FiscalDocumentId>
<tns:FiscalSign>4264393268</tns:FiscalSign>
</tns:GetTicketInfo>
</tns:GetTicketRequest>
</ns:Message>
</ns:SendMessageRequest>
</soapenv:Body>
</soapenv:Envelope>",
CURLOPT_HTTPHEADER => array(
"FNS-OpenApi-Token: ". $temptoken ."",
"FNS-OpenApi-UserToken: /*YOUR MASTER TOKEN HERE*/",
"Content-Type: text/xml"
),
));
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
//echo $response;
echo $error;
//echo html_entity_decode($response);
$dom = new DOMDocument();
$dom->loadXML($response);
foreach($dom->getElementsByTagName('MessageId') as $element ){
$messageId = $element->nodeValue;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
curl_setopt ($ch, CURLOPT_PROXYTYPE, 7);
curl_setopt_array($ch, array(
CURLOPT_URL => "https://openapi.nalog.ru:8090/open-api/ais3/KktService/0.1?wsdl",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"urn://x-artefacts-gnivc-ru/inplat/servin/OpenApiAsyncMessageConsumerService/types/1.0\">
<soapenv:Header/>
<soapenv:Body>
<ns:GetMessageRequest>
<ns:MessageId>".$messageId."</ns:MessageId>
</ns:GetMessageRequest>
</soapenv:Body>
</soapenv:Envelope>",
CURLOPT_HTTPHEADER => array(
"FNS-OpenApi-Token: ". $temptoken ."",
"FNS-OpenApi-UserToken: /*YOUR MASTER TOKEN HERE*/",
"Content-Type: text/xml"
),
));
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
//echo $response;
echo $error;
//echo html_entity_decode($response);
$dom = new DOMDocument();
$dom->loadXML($response);
foreach($dom->getElementsByTagName('Code') as $element ){
$code = $element->nodeValue;
}
foreach($dom->getElementsByTagName('Ticket') as $element ){
$message = $element->nodeValue;
}
$x = json_decode($message, true);
var_dump($x);
@dicrtarasov
Copy link

Мда..... заворачивать JSON в XML затем в SOAP ..... и это вместо простой RestAPI .... такое могли только идиоты придумать. Вот такое состояние цифровизации у нас в ФНС ...... ;)

@reinhurd
Copy link
Author

Если у кого перестало работать в декабре 20-го после обновления на стороне ФНС - необходимо заменить CheckTicketInfo на GetTicketInfo

@rilax
Copy link

rilax commented Feb 12, 2021

Почему то при последнем запросе, когда я передаю:
<ns:MessageId>".$messageId."</ns:MessageId>
Получаю ответ:
Запрос не соответствует формату hsm
Что это значит, а главное как это исправить?)

@jhaoda
Copy link

jhaoda commented Feb 12, 2021

@dicrtarasov покажи, где в коде происходит «заворачивать JSON в XML затем в SOAP»?

@reinhurd
Copy link
Author

Почему то при последнем запросе, когда я передаю:
<ns:MessageId>".$messageId."</ns:MessageId>
Получаю ответ:
Запрос не соответствует формату hsm
Что это значит, а главное как это исправить?)

  1. Точно hsm, а не xsd?
  2. $messageId - в каком формате отправляете?
  3. Если у вас официальное подключение к ФНС, вам вместе с мастер-токеном должны были прислать ссылку с доступами к их хелпдеску, попробуйте задать вопрос им, нужно будет приложить отправляемые вами запросы и ответы налоговой с меткой времени. Они, правило, быстро и более-менее по теме, помогают.

@rilax
Copy link

rilax commented Feb 12, 2021

Почему то при последнем запросе, когда я передаю:
<ns:MessageId>".$messageId."</ns:MessageId>
Получаю ответ:
Запрос не соответствует формату hsm
Что это значит, а главное как это исправить?)

  1. Точно hsm, а не xsd?
  2. $messageId - в каком формате отправляете?
  3. Если у вас официальное подключение к ФНС, вам вместе с мастер-токеном должны были прислать ссылку с доступами к их хелпдеску, попробуйте задать вопрос им, нужно будет приложить отправляемые вами запросы и ответы налоговой с меткой времени. Они, правило, быстро и более-менее по теме, помогают.
  1. Точнее некуда, код ошибки 452
  2. Какой получи такой и передаю, не меняя его, вот его пример: 48bb684c-0b75-4e95-8eac-7d1cbdfac445
  3. Конечно задам, думал возможно тут мне помогут быстрее, я же не один кто пытается работать с этой API
    $messageId может его нужно передавать как то иначе? В документации вроде ничего нет на эту тему

@reinhurd
Copy link
Author

@rilax
К сожалению, не знаю, как вам помочь, код выше крутится на одном из продакшн-серверов сейчас, и все возвращает нормально. Если уверены, что нет опечаток (и данные по самому чеку переданы так, как в примере), то поможет только запрос разработчикам этой штуки)

@rilax
Copy link

rilax commented Feb 12, 2021

@rilax
К сожалению, не знаю, как вам помочь, код выше крутится на одном из продакшн-серверов сейчас, и все возвращает нормально. Если уверены, что нет опечаток (и данные по самому чеку переданы так, как в примере), то поможет только запрос разработчикам этой штуки)

Причина была в том что я указывал тег "Sum в формате с точкой, а нужно указывать значение в копейках. Получается что я передавал ему не верный формат, а он на него зачем то возвращал messageId, а должен по идее уже на том этапе начать на меня ругаться

@reinhurd
Copy link
Author

@rilax ну здорово, что разобрались. Да, у них есть такая фишка. Даже если запрос построен целиком неверно, они все равно вернут Id сообщения.
До декабря 20-го ранее сразу писали, что данные по чеку предоставлены некорректно или не в том формате, но теперь у них более непонятная система ошибок.

@vladimir-ko
Copy link

Как только не делал... на втором запросе ошибка "Произошла внутренняя ошибка"
код полностью скопировал, с данными

@reinhurd
Copy link
Author

@vladimir-ko а вы мастер токен вставили свой? запрос отправляете с одобренного ip?
Если прям нигде нет опечаток - пишите им в техподдержку, контур своего сервиса они пока еще не меняли.

@vladimir-ko
Copy link

@vladimir-ko а вы мастер токен вставили свой? запрос отправляете с одобренного ip?
Если прям нигде нет опечаток - пишите им в техподдержку, контур своего сервиса они пока еще не меняли.

Мастер токен вставил, тмп токен получаю. Код скопирован полностью. Скорее всего в ТП стучаться нужно.

@AntonK19
Copy link

А ни у кого не было вот такой ошибки ?

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <GetMessageResponse xmlns="urn://x-artefacts-gnivc-ru/inplat/servin/OpenApiAsyncMessageConsumerService/types/1.0">
            <ProcessingStatus>COMPLETED</ProcessingStatus>
            <Message>
                <GetTicketResponse xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
                    xmlns="urn://x-artefacts-gnivc-ru/ais3/kkt/KktTicketService/types/1.0">
                    <Result>
                        <Code>543</Code>
                        <Message>Внутренняя ошибка сервиса проверки фискального признака</Message>
                    </Result>
                </GetTicketResponse>
            </Message>
        </GetMessageResponse>
    </soap:Body>
</soap:Envelope>

Чек запрашиваю вот так

<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"
                 xmlns:ns=\"urn://x-artefacts-gnivc-ru/inplat/servin/OpenApiAsyncMessageConsumerService/types/1.0\">
    <soapenv:Header/>
    <soapenv:Body>
        <ns:SendMessageRequest>
            <ns:Message>
                <tns:GetTicketRequest  xmlns:tns=\"urn://x-artefacts-gnivc-ru/ais3/kkt/KktTicketService/types/1.0\">
                    <tns:GetTicketInfo>
                        <tns:Sum>73400</tns:Sum>
                        <tns:Date>2021-03-28T15:13</tns:Date>
                        <tns:Fn>9280440300746022</tns:Fn>
                        <tns:TypeOperation>1</tns:TypeOperation>
                        <tns:FiscalDocumentId>36652</tns:FiscalDocumentId>
                        <tns:FiscalSign>665700876</tns:FiscalSign>
                    </tns:GetTicketInfo>
                </tns:GetTicketRequest>
            </ns:Message>
        </ns:SendMessageRequest>
    </soapenv:Body>
</soapenv:Envelope>

@reinhurd
Copy link
Author

@vell1903
Проверьте, корректно ли внесли все данные с чека для запроса. Иногда QR бывает нечеткий, и (если вы получаете все данные из него) может давать ошибочные цифры, если старая библиотека для распознавания.

Если все верно (и тип чека действительно 1) проверьте формат даты. Я всегда засылаю с секундами, у вас на примере их нет.

@AntonK19
Copy link

AntonK19 commented Mar 30, 2021

@reinhurd Да, дел оказалось в секундах. Спасибо

@kiwiwr
Copy link

kiwiwr commented Oct 1, 2024

Привет! Большая просьба, а пришлите, пожалуйста, пример полного ответа с информацией о чеке
Данные можно обезличить

Или может это где в документации есть..

@reinhurd
Copy link
Author

reinhurd commented Oct 1, 2024

Привет! Большая просьба, а пришлите, пожалуйста, пример полного ответа с информацией о чеке Данные можно обезличить

Или может это где в документации есть..

Здравствуйте! К сожалению у меня больше нет доступа к АПИ ФНС.

@kiwiwr
Copy link

kiwiwr commented Oct 3, 2024

@reinhurd Добрый день! Благодарю за ответ!
Может быть помните, что именно позволяет получить API:

  • Только проверку на подлинность чека?
  • Всю информацию по чеку (включая позиции и т. д)?
  • Все вышеперечисленное?

@reinhurd
Copy link
Author

reinhurd commented Oct 3, 2024

@reinhurd Добрый день! Благодарю за ответ! Может быть помните, что именно позволяет получить API:

  • Только проверку на подлинность чека?
  • Всю информацию по чеку (включая позиции и т. д)?
  • Все вышеперечисленное?

Три года назад позволял получить все вышеперечисленное - как позиции, так и факт "реальности" чека по переданным реквизитам

@kaunnikov
Copy link

Привет! Большая просьба, а пришлите, пожалуйста, пример полного ответа с информацией о чеке Данные можно обезличить

Или может это где в документации есть..

array(6) { ["id"]=> int(5502405252208916736) ["ofdId"]=> string(4) "ofd9" ["receiveDate"]=> string(20) "2024-10-03T15:21:49Z" ["subtype"]=> string(7) "receipt" ["address"]=> string(152) "456040,Россия,Челябинская область,Усть-Катавский г.о.,,Усть-Катав г,,МКР-3 ул,,д. 11,стр. 1,,," ["content"]=> array(31) { ["messageFiscalSign"]=> float(9.29716277294925E+18) ["code"]=> int(3) ["fiscalDocumentFormatVer"]=> int(4) ["fiscalDriveNumber"]=> string(16) "7282440500298251" ["kktRegId"]=> string(20) "0005765590024540 " ["userInn"]=> string(12) "5834027545 " ["fiscalDocumentNumber"]=> int(37343) ["dateTime"]=> int(1727986860) ["fiscalSign"]=> int(4009403681) ["shiftNumber"]=> int(285) ["requestNumber"]=> int(135) ["operationType"]=> int(1) ["totalSum"]=> int(105480) ["operator"]=> string(28) "Неваленова К. Н." ["items"]=> array(3) { [0]=> array(14) { ["propertiesItem"]=> string(4) "mdlp" ["name"]=> string(50) "Називин капли 0.025% кор 10 мл x1" ["price"]=> int(27100) ["quantity"]=> int(1) ["nds"]=> int(2) ["ndsSum"]=> int(2463) ["productType"]=> int(1) ["paymentType"]=> int(4) ["sum"]=> int(27100) ["itemsIndustryDetails"]=> array(1) { [0]=> array(4) { ["idFoiv"]=> string(3) "020" ["foundationDocDateTime"]=> string(10) "14.12.2018" ["foundationDocNumber"]=> string(4) "1556" ["industryPropValue"]=> string(27) "tm=mdlp&sid=00000000454790&" } } ["itemsQuantityMeasure"]=> int(0) ["productCodeNew"]=> array(1) { ["gs1m"]=> array(4) { ["rawProductCode"]=> string(31) "010405483947257221F298GRX86SVX4" ["productIdType"]=> int(6) ["gtin"]=> string(14) "04054839472572" ["sernum"]=> string(13) "F298GRX86SVX4" } } ["labelCodeProcesMode"]=> int(0) ["checkingProdInformationResult"]=> int(15) } [1]=> array(14) { ["propertiesItem"]=> string(4) "mdlp" ["name"]=> string(47) "Трамицент спрей наз 15 мл x1" ["price"]=> int(48050) ["quantity"]=> int(1) ["nds"]=> int(2) ["ndsSum"]=> int(4368) ["productType"]=> int(1) ["paymentType"]=> int(4) ["sum"]=> int(48050) ["itemsIndustryDetails"]=> array(1) { [0]=> array(4) { ["idFoiv"]=> string(3) "020" ["foundationDocDateTime"]=> string(10) "14.12.2018" ["foundationDocNumber"]=> string(4) "1556" ["industryPropValue"]=> string(27) "tm=mdlp&sid=00000000454790&" } } ["itemsQuantityMeasure"]=> int(0) ["productCodeNew"]=> array(1) { ["gs1m"]=> array(4) { ["rawProductCode"]=> string(31) "0104630179305901213MZNTZFXRS4M9" ["productIdType"]=> int(6) ["gtin"]=> string(14) "04630179305901" ["sernum"]=> string(13) "3MZNTZFXRS4M9" } } ["labelCodeProcesMode"]=> int(0) ["checkingProdInformationResult"]=> int(15) } [2]=> array(14) { ["propertiesItem"]=> string(4) "mdlp" ["name"]=> string(66) "Амоксиклав пор д/сусп вн прим 250 мг+62." ["price"]=> int(30330) ["quantity"]=> int(1) ["nds"]=> int(2) ["ndsSum"]=> int(2757) ["productType"]=> int(1) ["paymentType"]=> int(4) ["sum"]=> int(30330) ["itemsIndustryDetails"]=> array(1) { [0]=> array(4) { ["idFoiv"]=> string(3) "020" ["foundationDocDateTime"]=> string(10) "14.12.2018" ["foundationDocNumber"]=> string(4) "1556" ["industryPropValue"]=> string(27) "tm=mdlp&sid=00000000454790&" } } ["itemsQuantityMeasure"]=> int(0) ["productCodeNew"]=> array(1) { ["gs1m"]=> array(4) { ["rawProductCode"]=> string(31) "0107613421107208211381687784947" ["productIdType"]=> int(6) ["gtin"]=> string(14) "07613421107208" ["sernum"]=> string(13) "1381687784947" } } ["labelCodeProcesMode"]=> int(0) ["checkingProdInformationResult"]=> int(15) } } ["nds10"]=> int(9589) ["user"]=> string(52) "ООО "Аптека "Домашний доктор"" ["retailPlaceAddress"]=> string(97) "456040,Челябинская область, г.Усть-Катав,ул.МКР-3,д.11,стр.1" ["retailPlace"]=> string(53) "Аптечный пункт, a-plus.ru, aptekiplus.ru" ["appliedTaxationType"]=> int(1) ["fnsUrl"]=> string(16) "www.nalog.gov.ru" ["cashTotalSum"]=> int(0) ["ecashTotalSum"]=> int(105480) ["prepaidSum"]=> int(0) ["creditSum"]=> int(0) ["provisionSum"]=> int(0) ["checkingLabeledProdResult"]=> int(0) ["properties"]=> array(2) { ["propertyName"]=> string(4) "mdlp" ["propertyValue"]=> string(18) "sid00000000454790&" } ["region"]=> string(2) "74" ["numberKkt"]=> string(10) "0128051822" ["redefine_mask"]=> int(0) } }

@kaunnikov
Copy link

photo_2024-10-04_11-13-14

@kiwiwr
Copy link

kiwiwr commented Oct 4, 2024

@kaunnikov, @reinhurd Добрый день! Огромное спасибо за ответы

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment