agoalofalife / fnsapi
通过 SOAP 协议与俄罗斯联邦税务服务局 API 的交互(现金收据)
Requires
- php: >=7.1.0
- ext-json: *
- nesbot/carbon: ^2.0
- psr/simple-cache: ^1.0
Requires (Dev)
- fzaninotto/faker: ^1.9@dev
- mockery/mockery: ^1.3@dev
- phpunit/phpunit: ^6
README
该包提供了通过俄罗斯联邦税务服务局(FNS)官方 API 检查收据的功能。
安装
composer require agoalofalife/fnsapi
身份验证
要开始使用此服务,您需要获取临时令牌。在编写本文件时,其有效期为一个小时。
$cachePSR16 = new Sarahman\SimpleCache\FileSystemCache(__DIR__); $master_token = 'ourMasterToken'; $auth = new Fns\Auth\AuthRequest($master_token, $cachePSR16); $auth->authenticate();
您需要传递由 FNS 发出并存储的 master 令牌和实现 PSR-16 的存储。
存储将根据 PSR-16 参数 ttl 及时更新新令牌。
PSR-16 允许在许多现代框架中使用此包等。
如果没有获取到令牌,类将抛出 UnexpectedValueException 异常。
时区
令牌的有效期根据您的 PHP: 运行时配置 - 手册 date.timezone 设置。
创建 Ticket(现金收据)
建议检查您的 php.ini 文件并设置正确的时区。
$ticket = new \Fns\Ticket(); $ticket->setDate('2019-12-16T12:22:00'); $ticket->setFiscalDocumentId(11222); $ticket->setFiscalSign(111111122); $ticket->setFn(1234000123440000); $ticket->setSum(11220); $ticket->setTypeOperation(1); // случайные данные
创建 SOAP 客户端
为了获取收据信息,您需要创建一个 Ticket
类的实例。有关这些数据的更多信息,请参阅代码和 FNS 的官方文档。
- 我们创建了收据并填充了数据。现在我们需要创建一个 SOAP 客户端。这是一个非常了解我们正在与 FNS 交互的客户端,因此它需要
- 一个用于会话的唯一字符串。这个字符串将被 base64 编码(这将增加大约 30% 的长度),不应超过 160 个字符。
- 与创建用于获取临时令牌的相同数据存储,PSR-16,创建的对象。
$client = new \Fns\ClientSoap('uniqueStringOrNumber', $cache);
检查或获取收据信息
启用调试模式(默认为 false),可以通过如 __getLastRequest
等方法查看请求。
- 创建收据和客户端后,一切就绪,可以开始工作!现在只剩下选择
- 检查收据
\Fns\GetMessage\CheckTicketRequest
Для справки
API ФНС реализованно через асинхроннсть.
Для начала вам надо отправить запрос для получения `MessageId`
с информацией по чеку и типом(проверка или полной информацией по чеку)
Далее новым запросом с `MessageId` получить информацию.
Нюанс заключается в том, что последующий запрос, имеет время исполнения и сетевые задержки.
К примеру вы можете получить информацию по `MessageId` в течении 60 секунд.
Для своей реализации обработки timeout читайте в разделе Алгоритмы обработки timeout
-
获取详细信息
\Fns\GetMessage\GetTicketRequest
-
创建带有请求类型的对象
-
实现
Fns\Contracts\TimeoutStrategyHandler
接口以实现自己的超时处理策略 -
创建
SendMessageRequest
对象,传递我们之前创建的客户端和具体请求对象。 -
传递收据
-
执行
execute
请求,它返回ResponseSendMessage
接口
$message = new \Fns\GetMessage\GetTicketRequest(); $message->setTimeoutStrategy(new ExponentialBackoff($message)); // можно установить свое максимальное значение time out $message->setTimeoutStrategy(new ExponentialBackoff($message), 600000000); $request = new SendMessageRequest($client, $message); $request->setTicket($ticket); $response = $request->execute(); if ($response->getCode() === 200) { dump(json_decode($response->getBody())); // или получить в виде структуры $response->getReceipt(); }
获取请求的信息,包括代码和响应体。
准备好的结构化响应
响应将以 json 或 Receipt 对象的形式返回。
- Receipt 类
- ProductCollection 类
- Product 类
解决以下问题
- 更明显地获取数据
- 封装转换以简化客户代码中的修改和易于维护
但您始终可以获取原始版本。
检查收据 CheckTicketRequest
要获取收据是否正确的信息,只需比较响应代码与 200 即可。
Из старой документации
если 200, то "Отправленные данные корректны"
если 400, то "Формат отправленных данных некорректен"
если 406, то "Данные не прошли проверку"
если 503, то "Сервис недоступен".
获取收据信息 GetTicketRequest
Из старой документации
Содержимое ФД, если код возврата равен 200
если 400, то "Формат отправленных данных некорректен"
если 404, то "Чек не найден"
если 406, то "Данные не прошли проверку"
если 453, то "Чек неккоректен".
Из нового сервиса опытным путем:
452 - Запрос не соответствует формату hsm
454 - Обращение к hsm было произведено и получен отрицательный результат проверки
455 - Не найдены данные в сервисе поиска чека
531 - "" (Происходит когда были отпроавлены неккоректные данные)
528 - Фискальный признак не может быть проверен, поскольку в hsm отсутствует необходимый ключ
531 - "" (Происходит когда были отпроавлены неккоректные данные)
После обновления API пока не предоставлен конечный список ответов!
处理超时算法
要获取检查信息,需要发送带有 messageId
参数的 SendMessageRequest
请求。在第一次(第二次等)请求后,可能会立即收到 messageId
但缺少检查信息。默认情况下,该包实现了 指数退避。
您可以通过实现接口 Fns\Contracts\TimeoutStrategyHandler\TimeoutStrategyHandler
来实现自己的算法。
为了监控请求执行过程及其结果,请在 Fns\Contracts\RequestsManager
的构造函数中传递。
例如,您可以实现一个 Interval
算法,该算法将通过恒定的时间间隔向服务器请求数据。
作者提供的信息
目前所有操作都是同步进行的。可以将获取 messageId
和获取其信息的过程分解为两个不同的过程。对于包的初始版本,目前仍然如此。
请喝茶 😌
此包免费创建,以节省您的宝贵时间。希望我做到了这一点,并且我会很高兴得到任何形式的感谢。一颗星或小额捐款将支持我,并增强我对人们的信心。 https://money.yandex.ru/to/410019109036855