Возникли проблемы с 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>
Я понимаю, что возможно тут всё очень просто, но я перерыл куча форумов и в голове дикая каша. Подскажите пожалуйста, может кто знает что, хотя бы небольшой пример кода. Спасибо.
Полный черновой пример работающего запроса (по состоянию на сегодня). Необходимо вставить полученный мастер токен и обращаться с 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);
Продвижение своими сайтами как стратегия роста и независимости