Взаимодействие с API ФНС России

182
12 мая 2021, 05:30

Возникли проблемы с API налоговой. Они используют SOAP или что-то подобное, мозгов не хватает разобраться, в общем общение идет каким то образом через XML, а мне нужно писать на PHP. Читал что в PHP есть SOAP или можно отправлять XML через cURL, но я вообще не могу разобраться в этом во всем.

Мне нужно получить временный токен. В документации сказано:

5.1.1 Получение временного токена Схема запроса для получения временного токена приведена в Приложении А. Wsdl-сервис получения временного токена должен быть доступен по адресу: https://{OPENAPISERVER}/open-api/AuthService/0.1?wsdl

Приложение А:

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn://x-artefacts-gnivc-ru/ais3/kkt/AuthService/types/1.0" elementFormDefault="qualified" targetNamespace="urn://x-artefacts-gnivc-ru/ais3/kkt/AuthService/types/1.0" version="1.0">
  <xs:element name="AuthServiceFault" type="tns:AuthServiceFault"/>
  <xs:complexType name="AuthServiceFault">
    <xs:annotation>
      <xs:documentation>Ошибка сервиса сообщений</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="Message" type="xs:string">
        <xs:annotation>
          <xs:documentation>Сообщение об ошибке</xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>   </xs:complexType>
  <xs:complexType name="AuthAppInfo">
    <xs:annotation>
      <xs:documentation>Информация о внешнем приложении используещем публичные методы ФНС</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="MasterToken" type="xs:string">
        <xs:annotation>
          <xs:documentation>Мастер токен сгенерированный приложением с помощью выданого ключа</xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>   </xs:complexType>
  <xs:element name="AuthRequest">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="AuthAppInfo" type="tns:AuthAppInfo">
          <xs:annotation>
            <xs:documentation>Данные необходимые для авторизации внешнего приложения</xs:documentation>
          </xs:annotation>
        </xs:element>
      </xs:sequence>
    </xs:complexType>   </xs:element>
  <xs:element name="AuthResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="1" name="Result">
            <xs:complexType>
                <xs:sequence>
                    <xs:element minOccurs="1" maxOccurs="1" name="Token" type="xs:string">
                      <xs:annotation>
                        <xs:documentation>Токен сгенерированный для внешнего приложения</xs:documentation>
                      </xs:annotation>
                    </xs:element>
                    <xs:element minOccurs="1" maxOccurs="1" name="ExpireTime" type="xs:dateTime">
                      <xs:annotation>
                        <xs:documentation>Дата и время истечения сгенерерированного токена</xs:documentation>
                      </xs:annotation>
                    </xs:element>
                </xs:sequence>
            </xs:complexType>       </xs:element>       <xs:element minOccurs="0" maxOccurs="1" name="Fault" type="tns:AuthServiceFault">       </xs:element>
      </xs:sequence>
    </xs:complexType>   </xs:element>
</xs:schema>

Я понимаю, что возможно тут всё очень просто, но я перерыл куча форумов и в голове дикая каша. Подскажите пожалуйста, может кто знает что, хотя бы небольшой пример кода. Спасибо.

Answer 1

Полный черновой пример работающего запроса (по состоянию на сегодня). Необходимо вставить полученный мастер токен и обращаться с IP, на который был выпущен этот токен.

$ch = curl_init();
//ПЕРВЫЙ ЗАПРОС - получаем временный токен и вставляем его в заголовки следующих запросов
    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;
//ВТОРОЙ ЗАПРОС - отправляем всю информацию о чеке (в формате, как в примере) - и получаем messageId для третьего запроса
$ch = curl_init();
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:CheckTicketInfo>
                        <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:CheckTicketInfo>
                </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();
//ТРЕТИЙ ЗАПРОС- получаем всю информацию о ранее запрошенном чеке. Возможны варианты - чек не будет найден, или запрос еще обрабатывается (статус - Processing).
    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);
READ ALSO
Wordpress - сортировка постов по дате

Wordpress - сортировка постов по дате

Объясните, пожалуйста, как сделать сортировку постов для определенной категории по дате по возрастаниюТо есть нужно добиться, чтобы пост...

103
Не понимаю как создать скрипт начисления процентов?

Не понимаю как создать скрипт начисления процентов?

Ребята помогите, пожалуйстаЯ совсем не понимаю как мне это сделать

100
Slim. Не могу запустить &ldquo;Hello World&rdquo;

Slim. Не могу запустить “Hello World”

Хочу изучить Slim v4 для RESTFull сервера

95
Изменить формат вывода по regex

Изменить формат вывода по regex

Всем привет, еще только изучаю язык, строго не судите такой вопрос: все номера телефонов в тексте записанные в формате +375XXYYYYYYY с помощью regex заменить...

74