├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── examples ├── detail.php ├── exist.php ├── helper.php ├── login.php ├── restore.php └── signup.php └── src ├── FnsCheckApi.php ├── FnsCheckApiException.php ├── FnsCheckAuth.php ├── FnsCheckHelper.php ├── FnsCheckRequest.php ├── FnsCheckResponse.php ├── request ├── CheckDetailRequest.php ├── CheckExistRequest.php ├── LoginRequest.php ├── RestoreRequest.php └── SignupRequest.php └── response ├── CheckDetailResponse.php ├── CheckExistResponse.php ├── LoginResponse.php ├── RestoreResponse.php └── SignupResponse.php /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer vendor dir 16 | /vendor 17 | 18 | # composer itself is not needed 19 | composer.phar 20 | 21 | # Mac DS_Store Files 22 | .DS_Store 23 | 24 | # Composer lock file 25 | composer.lock -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 kosov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Клиент для работы с API ФНС по проверке онлайн-чеков 2 | 3 | ## Возможности 4 | 5 | Данная библиотека предоставляет возможности, аналогичные функционалу официального мобильного приложения ФНС по проверке онлайн-чеков, а именно: 6 | 7 | - Регистрация нового пользователя; 8 | - Авторизация пользователя; 9 | - Восстановление пароля пользователя; 10 | - Проверка существования чека; 11 | - Получение детальной информации по чеку. 12 | 13 | ## Установка 14 | 15 | Установка даннной библиотеки возможна только через [Composer](https://getcomposer.org/). 16 | 17 | Так как библиотека использует HTTP клиент по стандарту [PSR-7](https://www.php-fig.org/psr/psr-7/), то вместе с библиотекой необходимо установить любой из доступных HTTP клиентов или адаптеров. Список поддерживаемых HTTP клиентов – http://docs.php-http.org/en/latest/clients.html. Подробнее об использовании можно почитать [здесь](http://docs.php-http.org/en/latest/httplug/users.html). 18 | 19 | Выполните следующую команду (если вы хотите использовать php-http/curl-client в качестве HTTP клиента) 20 | ``` 21 | composer require php-http/curl-client guzzlehttp/psr7 php-http/message kosov/fns-check 22 | ``` 23 | в директории своего проекта или добавьте 24 | ``` 25 | "kosov/fns-check": "^1.1" 26 | ``` 27 | в секцию `require` файла `composer.json` вашего проекта. 28 | 29 | ## Быстрый старт 30 | 31 | Ниже рассмотрен пример получения детальной информации по чеку. Все остальные примеры возможностей данной библиотеки рассмотрены [здесь](https://github.com/kosov/fns-check/tree/master/examples). 32 | 33 | ```php 34 | '8710000101606774', // "ФН" в чеке 46 | 'fiscalSign' => '0211560320', // "ФП" в чеке 47 | 'fiscalDocument' => '0000136962', // "ФД" в чеке 48 | ]; 49 | 50 | // Авторизация пользователя по номеру телефона и паролю из SMS 51 | $auth = new FnsCheckAuth('+79999999999', '111111'); 52 | 53 | $fnsCheckApi = new FnsCheckApi(); 54 | 55 | try { 56 | // Выполнение запроса к API ФНС 57 | $response = $fnsCheckApi->call(new CheckDetailRequest($checkData, $auth)); 58 | 59 | // Еще один метод вызова того же API метода 60 | // $response = $fnsCheckApi->checkDetail($checkData, $auth); 61 | echo $response->getContents(); 62 | } catch (FnsCheckApiException $exception) { 63 | echo "Error: {$exception->getMessage()}"; 64 | } 65 | ``` 66 | 67 | Если вы работаете с данными QR-кода чека, то для формирования массива данных запроса можете использовать `FnsCheckHelper::fromQRCode`: 68 | 69 | ```php 70 | '8710000101606774', // "ФН" в чеке 13 | 'fiscalSign' => '0211560320', // "ФП" в чеке 14 | 'fiscalDocument' => '0000136962', // "ФД" в чеке 15 | ]; 16 | 17 | // Авторизация пользователя 18 | $auth = new FnsCheckAuth('+79999999999', '111111'); 19 | 20 | $fnsCheckApi = new FnsCheckApi(); 21 | 22 | try { 23 | $response = $fnsCheckApi->call(new CheckDetailRequest($checkData, $auth)); 24 | 25 | // Еще один метод вызова того же API метода 26 | // $response = $fnsCheckApi->checkDetail($checkData, $auth); 27 | echo $response->getContents(); 28 | } catch (FnsCheckApiException $exception) { 29 | echo "Error: {$exception->getMessage()}"; 30 | } 31 | -------------------------------------------------------------------------------- /examples/exist.php: -------------------------------------------------------------------------------- 1 | '9289000100087727', // "ФН" в чеке 13 | 'fiscalSign' => '3385572166', // "ФП" в чеке 14 | 'fiscalDocument' => '5276', // "ФД" в чеке 15 | 'date' => '17.08.2018 09:26', // Дата создания чека 16 | 'operation' => 1, // Тип операции "Приход" 17 | 'sum' => 26500, // Сумма чека в копейках 18 | ]; 19 | 20 | // Авторизация пользователя 21 | $auth = new FnsCheckAuth('+79999999999', '111111'); 22 | 23 | $fnsCheckApi = new FnsCheckApi(); 24 | 25 | try { 26 | $response = $fnsCheckApi->call(new CheckExistRequest($checkData, $auth)); 27 | 28 | // Еще один метод вызова того же API метода 29 | // $response = $fnsCheckApi->checkExist($checkData, $auth); 30 | echo 'Чек найден.'; 31 | } catch (FnsCheckApiException $exception) { 32 | echo "Error: {$exception->getMessage()}"; 33 | } 34 | -------------------------------------------------------------------------------- /examples/helper.php: -------------------------------------------------------------------------------- 1 | $value) { 14 | echo "{$key}: {$value}
"; 15 | } 16 | -------------------------------------------------------------------------------- /examples/login.php: -------------------------------------------------------------------------------- 1 | call(new LoginRequest([], $auth)); 17 | 18 | // Еще один метод вызова того же API метода 19 | // $response = $fnsCheckApi->login([], $auth); 20 | echo $response->getContents(); 21 | } catch (FnsCheckApiException $exception) { 22 | echo "Error: {$exception->getMessage()}"; 23 | } 24 | -------------------------------------------------------------------------------- /examples/restore.php: -------------------------------------------------------------------------------- 1 | '+79999999999', 12 | ]; 13 | 14 | $fnsCheckApi = new FnsCheckApi(); 15 | 16 | try { 17 | $fnsCheckApi->call(new RestoreRequest($restoreData)); 18 | 19 | // Еще один метод вызова того же API метода 20 | // $fnsCheckApi->restore($restoreData); 21 | echo 'Вам отправлена SMS с новым паролем.'; 22 | } catch (FnsCheckApiException $exception) { 23 | echo "Error: {$exception->getMessage()}"; 24 | } 25 | -------------------------------------------------------------------------------- /examples/signup.php: -------------------------------------------------------------------------------- 1 | 'youremail@address.com', 12 | 'name' => 'YourName', 13 | 'phone' => '+79999999999', 14 | ]; 15 | 16 | $fnsCheckApi = new FnsCheckApi(); 17 | 18 | try { 19 | $fnsCheckApi->call(new SignupRequest($signupData)); 20 | 21 | // Еще один метод вызова того же API метода 22 | // $fnsCheckApi->signup($signupData); 23 | echo 'Вам отправлена SMS с паролем.'; 24 | } catch (FnsCheckApiException $exception) { 25 | echo "Error: {$exception->getMessage()}"; 26 | } 27 | -------------------------------------------------------------------------------- /src/FnsCheckApi.php: -------------------------------------------------------------------------------- 1 | 21 | * 22 | * @method \kosov\fnscheck\response\SignupResponse signup(array $config = [], FnsCheckAuth $auth = null) 23 | * @method \kosov\fnscheck\response\RestoreResponse restore(array $config = [], FnsCheckAuth $auth = null) 24 | * @method \kosov\fnscheck\response\LoginResponse login(array $config = [], FnsCheckAuth $auth = null) 25 | * @method \kosov\fnscheck\response\CheckExistResponse checkExist(array $config = [], FnsCheckAuth $auth = null) 26 | * @method \kosov\fnscheck\response\CheckDetailResponse checkDetail(array $config = [], FnsCheckAuth $auth = null) 27 | */ 28 | class FnsCheckApi 29 | { 30 | /** 31 | * HTTP клиент для работы с API. 32 | * 33 | * @var HttpClient 34 | */ 35 | private $httpClient; 36 | 37 | /** 38 | * Объект фабрики PSR-7 запросов. 39 | * 40 | * @var RequestFactory 41 | */ 42 | private $requestFactory; 43 | 44 | /** 45 | * FnsCheckApi constructor. 46 | * 47 | * Если HTTP клиент для работы с API не был установлен самостоятельно, 48 | * HttpClientDiscovery::find() пытается сам найти подходящий. 49 | * 50 | * @see http://docs.php-http.org/en/latest/discovery.html#http-client-discovery 51 | * 52 | * @param HttpClient|null $httpClient HTTP клиент для работы с API 53 | */ 54 | public function __construct(HttpClient $httpClient = null) 55 | { 56 | $this->setHttpClient($httpClient ?: HttpClientDiscovery::find()); 57 | } 58 | 59 | /** 60 | * Отправляет указанный запрос к API ФНС по работе с электронными чеками. 61 | * 62 | * @param FnsCheckRequest $request Объект запроса к API 63 | * 64 | * @return FnsCheckResponse Объект ответа API 65 | * 66 | * @throws FnsCheckApiException Исключение обработки запроса к API 67 | */ 68 | public function call(FnsCheckRequest $request) 69 | { 70 | $requestBody = $request->getHttpMethod() !== FnsCheckRequest::HTTP_METHOD_GET ? 71 | $request->getPayloadString() : null; 72 | 73 | $httpRequest = $this->getRequestFactory()->createRequest( 74 | $request->getHttpMethod(), 75 | $request->getUrl(), 76 | $request->getHeaders(), 77 | $requestBody 78 | ); 79 | 80 | if ($request->getAuth() instanceof FnsCheckAuth) { 81 | $httpRequest = $request->getAuth()->getHttpAuthentication()->authenticate($httpRequest); 82 | } 83 | 84 | try { 85 | $httpResponse = $this->getHttpClient()->sendRequest($httpRequest); 86 | } catch (HttpException $httpException) { 87 | throw new FnsCheckApiException("HTTP Exception: {$httpException->getMessage()}"); 88 | } catch (Exception $exception) { 89 | throw new FnsCheckApiException($exception->getMessage()); 90 | } 91 | 92 | $response = $request->getResponse($httpResponse); 93 | $response->processHttpResponse(); 94 | 95 | return $response; 96 | } 97 | 98 | /** 99 | * Устанавливает объект HTTP клиента для работы с API. 100 | * 101 | * @param HttpClient $httpClient HTTP клиент 102 | */ 103 | public function setHttpClient(HttpClient $httpClient) 104 | { 105 | $this->httpClient = $httpClient; 106 | } 107 | 108 | /** 109 | * Возвращает объект HTTP клиента для работы с API. 110 | * 111 | * @return HttpClient HTTP клиент 112 | */ 113 | public function getHttpClient() 114 | { 115 | return $this->httpClient; 116 | } 117 | 118 | /** 119 | * Устанавливает объект фабрики для генерации PSR-7 запросов. 120 | * 121 | * @param RequestFactory $requestFactory Объект фабрики PSR-7 запросов 122 | */ 123 | public function setRequestFactory(RequestFactory $requestFactory) 124 | { 125 | $this->requestFactory = $requestFactory; 126 | } 127 | 128 | /** 129 | * Возвращает объект фабрики для генерации PSR-7 запросов. 130 | * Если объект фабрики запросов не был установлен самостоятельно, 131 | * MessageFactoryDiscovery::find() пытается сам найти подходящий. 132 | * 133 | * @see http://docs.php-http.org/en/latest/discovery.html#psr-7-message-factory-discovery 134 | * 135 | * @return RequestFactory Объект фабрики PSR-7 запросов 136 | */ 137 | public function getRequestFactory() 138 | { 139 | if (!$this->requestFactory) { 140 | $this->requestFactory = MessageFactoryDiscovery::find(); 141 | } 142 | 143 | return $this->requestFactory; 144 | } 145 | 146 | /** 147 | * Выполняет запрос к API ФНС по работе с электронными чеками. 148 | * Вызов метода отправки запроса через магический метод __call(). 149 | * 150 | * @param string $name Название метода API 151 | * @param array $arguments Список аргументов метода 152 | * 153 | * @return FnsCheckResponse Объект ответа API 154 | * 155 | * @throws Exception Выбрасывается при отсутствии вызываемого метода в API 156 | */ 157 | public function __call($name, $arguments) 158 | { 159 | $requestClass = __NAMESPACE__ . '\\request\\' . ucfirst($name) . 'Request'; 160 | 161 | if (!class_exists($requestClass)) { 162 | throw new Exception("Undefined API method '{$name}'."); 163 | } 164 | 165 | /** @var FnsCheckRequest $request */ 166 | if (count($arguments) === 0) { 167 | $request = new $requestClass; 168 | } else { 169 | $reflection = new ReflectionClass($requestClass); 170 | $request = $reflection->newInstanceArgs($arguments); 171 | } 172 | 173 | return $this->call($request); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/FnsCheckApiException.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class FnsCheckApiException extends \Exception 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /src/FnsCheckAuth.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class FnsCheckAuth 16 | { 17 | /** 18 | * Логин пользователя. 19 | * В качестве логина пользователя выступает 20 | * его телефон в формате +7XXXXXXXXXX. 21 | * 22 | * @var string 23 | */ 24 | private $username; 25 | 26 | /** 27 | * Пароль пользователя. 28 | * Пароль пользователя приходит в SMS, 29 | * отправляемой при регистрации или восстановлении пароля. 30 | * 31 | * @var string 32 | */ 33 | private $password; 34 | 35 | /** 36 | * FnsCheckAuth конструктор. 37 | * 38 | * @param string $username Логин пользователя 39 | * @param string $password Пароль пользователя 40 | */ 41 | public function __construct($username, $password) 42 | { 43 | $this->setUsername($username); 44 | $this->setPassword($password); 45 | } 46 | 47 | /** 48 | * Устанавливает логин пользователя. 49 | * 50 | * @param string $username Логин пользователя 51 | */ 52 | public function setUsername($username) 53 | { 54 | $this->username = (string) $username; 55 | } 56 | 57 | /** 58 | * Возвращает логин пользователя. 59 | * 60 | * @return string Логин пользователя 61 | */ 62 | public function getUsername() 63 | { 64 | return $this->username; 65 | } 66 | 67 | /** 68 | * Устанавливает пароль пользователя. 69 | * 70 | * @param string $password Пароль пользователя 71 | */ 72 | public function setPassword($password) 73 | { 74 | $this->password = (string) $password; 75 | } 76 | 77 | /** 78 | * Возвращает пароль пользователя. 79 | * 80 | * @return string Пароль пользователя 81 | */ 82 | public function getPassword() 83 | { 84 | return $this->password; 85 | } 86 | 87 | /** 88 | * Возвращает объект HTTP-Basic аутентификаци пользователя. 89 | * 90 | * @return BasicAuth Объект HTTP-Basic аутентификаци 91 | */ 92 | public function getHttpAuthentication() 93 | { 94 | return new BasicAuth($this->username, $this->password); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/FnsCheckHelper.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class FnsCheckHelper 14 | { 15 | /** 16 | * Конвертирует данные, полученные из QR-кода, в массив данных для запроса к API. 17 | * 18 | * @param string $qrCodeString Данные QR-кода 19 | * 20 | * @return array Массив данных для запроса к API 21 | */ 22 | public static function fromQRCode($qrCodeString) 23 | { 24 | $paramsMap = [ 25 | 't' => 'date', 26 | 's' => 'sum', 27 | 'fn' => 'fiscalNumber', 28 | 'i' => 'fiscalDocument', 29 | 'fp' => 'fiscalSign', 30 | 'n' => 'operation', 31 | ]; 32 | 33 | $normalizedParams = array_fill_keys(array_values($paramsMap), null); 34 | 35 | parse_str($qrCodeString, $qrCodeParams); 36 | 37 | foreach ($paramsMap as $qrField => $normalizedField) { 38 | if (array_key_exists($qrField, $qrCodeParams)) { 39 | $normalizedParams[$normalizedField] = $qrCodeParams[$qrField]; 40 | } 41 | } 42 | 43 | $normalizedParams['sum'] = self::rub2Kopeck($normalizedParams['sum']); 44 | 45 | return $normalizedParams; 46 | } 47 | 48 | /** 49 | * Конвертирует рубли в копейки. 50 | * 51 | * @param float|int $sum Сумма в рублях 52 | * 53 | * @return int Сумма в копейках 54 | */ 55 | private static function rub2Kopeck($sum) 56 | { 57 | return $sum * 100; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/FnsCheckRequest.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | abstract class FnsCheckRequest 16 | { 17 | /** 18 | * Базовый URL API ФНС по работе с электронными чеками. 19 | */ 20 | const BASE_FNS_URL = 'https://proverkacheka.nalog.ru:9999/v1'; 21 | 22 | /** 23 | * HTTP метод запроса "GET". 24 | */ 25 | const HTTP_METHOD_GET = 'GET'; 26 | 27 | /** 28 | * HTTP метод запроса "POST". 29 | */ 30 | const HTTP_METHOD_POST = 'POST'; 31 | 32 | /** 33 | * ID устройства. 34 | * 35 | * @var string 36 | */ 37 | private $deviceId; 38 | 39 | /** 40 | * Версия операционной системы устройства. 41 | * 42 | * @var string 43 | */ 44 | private $deviceOs; 45 | 46 | /** 47 | * Объект аутентификации пользователя. 48 | * 49 | * @var FnsCheckAuth 50 | */ 51 | private $auth; 52 | 53 | /** 54 | * Возвращает URL адреса запроса. 55 | * 56 | * @return string 57 | */ 58 | abstract public function getUrlPath(); 59 | 60 | /** 61 | * Возвращает название HTTP метода запроса. 62 | * 63 | * @return string 64 | */ 65 | abstract public function getHttpMethod(); 66 | 67 | /** 68 | * Возвращает массив параметров запроса. 69 | * 70 | * @return array 71 | */ 72 | abstract public function getPayload(); 73 | 74 | /** 75 | * Возвращает параметры запроса в виде строки. 76 | * 77 | * @return string Параметры запроса 78 | */ 79 | abstract public function getPayloadString(); 80 | 81 | /** 82 | * Возвращает название класса ответа сервера API. 83 | * 84 | * @return string Название класса ответа сервера API 85 | */ 86 | abstract public function getResponseClass(); 87 | 88 | /** 89 | * FnsCheckRequest конструктор. 90 | * 91 | * @param array $config Параметры запроса 92 | * @param FnsCheckAuth $auth Объект аутентификации пользователя 93 | */ 94 | public function __construct(array $config = [], FnsCheckAuth $auth = null) 95 | { 96 | $this->configure($config); 97 | $this->setAuth($auth); 98 | } 99 | 100 | /** 101 | * Устанавливает объект аутентификации пользователя. 102 | * 103 | * @param FnsCheckAuth $auth Объект аутентификации пользователя 104 | */ 105 | public function setAuth(FnsCheckAuth $auth = null) 106 | { 107 | $this->auth = $auth; 108 | } 109 | 110 | /** 111 | * Возвращает объект аутентификации пользователя. 112 | * 113 | * @return FnsCheckAuth Объект аутентификации пользователя 114 | */ 115 | public function getAuth() 116 | { 117 | return $this->auth; 118 | } 119 | 120 | /** 121 | * Возвращает полный URL адреса запроса. 122 | * 123 | * @return string 124 | */ 125 | public function getUrl() 126 | { 127 | $url = self::BASE_FNS_URL . $this->getUrlPath(); 128 | 129 | if ($this->getHttpMethod() === self::HTTP_METHOD_GET) { 130 | $url .= '?' . http_build_query($this->getPayload()); 131 | } 132 | 133 | return $url; 134 | } 135 | 136 | /** 137 | * Возвращает объект ответа сервера API. 138 | * 139 | * @param ResponseInterface $httpResponse Объект HTTP ответа сервера API 140 | * 141 | * @return FnsCheckResponse Объект ответа сервера API 142 | */ 143 | public function getResponse(ResponseInterface $httpResponse) 144 | { 145 | $responseClass = $this->getResponseClass(); 146 | 147 | return new $responseClass($httpResponse); 148 | } 149 | 150 | /** 151 | * Устанавливает ID устройства. 152 | * 153 | * @param string $deviceId ID устройства 154 | */ 155 | public function setDeviceId($deviceId) 156 | { 157 | $this->deviceId = (string) $deviceId; 158 | } 159 | 160 | /** 161 | * Возвращает ID устройства. 162 | * Если ID устройства не был установлен, 163 | * то возвращается случайно сгенерированная строка. 164 | * Рекомендуется указывать корректный ID устройства. 165 | * 166 | * @return string ID устройства 167 | */ 168 | public function getDeviceId() 169 | { 170 | return $this->deviceId ?: md5(mt_rand()); 171 | } 172 | 173 | /** 174 | * Устанавливает версию операционной системы устройства. 175 | * 176 | * @param string $deviceOs Версия операционной системы устройства. 177 | */ 178 | public function setDeviceOs($deviceOs) 179 | { 180 | $this->deviceOs = (string) $deviceOs; 181 | } 182 | 183 | /** 184 | * Возвращает версию операционной системы устройства. 185 | * Если версию операционной системы устройства не была установлена, 186 | * то возвращается случайно сгенерированная строка. 187 | * Рекомендуется указывать корректную 188 | * версию операционной системы устройства. 189 | * 190 | * @return string Версия операционной системы устройства 191 | */ 192 | public function getDeviceOs() 193 | { 194 | return $this->deviceOs ?: md5(mt_rand()); 195 | } 196 | 197 | /** 198 | * Возвращает массив заголовков запроса. 199 | * 200 | * @return array Массив заголовков запроса 201 | */ 202 | public function getHeaders() 203 | { 204 | return [ 205 | 'device-id' => $this->getDeviceId(), 206 | 'device-os' => $this->getDeviceOs(), 207 | ]; 208 | } 209 | 210 | /** 211 | * Выполняет конфигурацию запроса. 212 | * 213 | * @param array $config Параметры запроса 214 | */ 215 | private function configure(array $config = []) 216 | { 217 | foreach ($config as $property => $value) { 218 | if (property_exists($this, $property)) { 219 | $this->{$property} = $value; 220 | } 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /src/FnsCheckResponse.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | abstract class FnsCheckResponse 16 | { 17 | /** 18 | * Объект HTTP ответа сервера API. 19 | * 20 | * @var ResponseInterface 21 | */ 22 | protected $httpResponse; 23 | 24 | /** 25 | * Обрабатывает HTTP ответ сервера API. 26 | * 27 | * @throws FnsCheckApiException Исключение обработки запроса к API 28 | */ 29 | abstract public function processHttpResponse(); 30 | 31 | /** 32 | * FnsCheckResponse конструктор. 33 | * 34 | * @param ResponseInterface $response Объект HTTP ответа сервера API 35 | */ 36 | public function __construct(ResponseInterface $response) 37 | { 38 | $this->httpResponse = $response; 39 | } 40 | 41 | /** 42 | * Возвращает объект HTTP ответа сервера API. 43 | * 44 | * @return ResponseInterface Объект HTTP ответа сервера API 45 | */ 46 | public function getHttpResponse() 47 | { 48 | return $this->httpResponse; 49 | } 50 | 51 | /** 52 | * Возвращает тело ответа сервера API. 53 | * 54 | * @return string 55 | */ 56 | public function getContents() 57 | { 58 | return $this->httpResponse->getBody()->getContents(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/request/CheckDetailRequest.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class CheckDetailRequest extends FnsCheckRequest 17 | { 18 | /** 19 | * Фискальный номер. 20 | * 21 | * @var string 22 | */ 23 | public $fiscalNumber; 24 | 25 | /** 26 | * Фискальный признак документа. 27 | * 28 | * @var string 29 | */ 30 | public $fiscalSign; 31 | 32 | /** 33 | * Фискальный документ. 34 | * 35 | * @var string 36 | */ 37 | public $fiscalDocument; 38 | 39 | /** 40 | * Признак отправки чека на Email-адрес. 41 | * 42 | * @var string 43 | */ 44 | public $sendToEmail = 'no'; 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function getUrlPath() 50 | { 51 | return "/inns/*/kkts/*/fss/{$this->fiscalNumber}/tickets/{$this->fiscalDocument}"; 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function getHttpMethod() 58 | { 59 | return self::HTTP_METHOD_GET; 60 | } 61 | 62 | /** 63 | * {@inheritdoc} 64 | */ 65 | public function getPayload() 66 | { 67 | return [ 68 | 'fiscalSign' => $this->fiscalSign, 69 | 'sendToEmail' => $this->sendToEmail, 70 | ]; 71 | } 72 | 73 | /** 74 | * {@inheritdoc} 75 | */ 76 | public function getPayloadString() 77 | { 78 | return http_build_query($this->getPayload()); 79 | } 80 | 81 | /** 82 | * {@inheritdoc} 83 | */ 84 | public function getResponseClass() 85 | { 86 | return CheckDetailResponse::class; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/request/CheckExistRequest.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class CheckExistRequest extends FnsCheckRequest 17 | { 18 | /** 19 | * Фискальный номер. 20 | * 21 | * @var string 22 | */ 23 | public $fiscalNumber; 24 | 25 | /** 26 | * Фискальный признак документа. 27 | * 28 | * @var string 29 | */ 30 | public $fiscalSign; 31 | 32 | /** 33 | * Фискальный документ. 34 | * 35 | * @var string 36 | */ 37 | public $fiscalDocument; 38 | 39 | /** 40 | * Дата создания чека. 41 | * 42 | * @var string 43 | */ 44 | public $date; 45 | 46 | /** 47 | * Сумма чека в копейках. 48 | * 49 | * @var int 50 | */ 51 | public $sum; 52 | 53 | /** 54 | * Тип операции "приход/расход". 55 | * "Приход" = 1 56 | * "Расход" = 0 57 | * 58 | * @var int 59 | */ 60 | public $operation; 61 | 62 | /** 63 | * {@inheritdoc} 64 | */ 65 | public function getUrlPath() 66 | { 67 | return "/ofds/*/inns/*/fss/{$this->fiscalNumber}/operations/1/tickets/{$this->fiscalDocument}"; 68 | } 69 | 70 | /** 71 | * {@inheritdoc} 72 | */ 73 | public function getHttpMethod() 74 | { 75 | return self::HTTP_METHOD_GET; 76 | } 77 | 78 | /** 79 | * {@inheritdoc} 80 | */ 81 | public function getPayload() 82 | { 83 | return [ 84 | 'fiscalSign' => $this->fiscalSign, 85 | 'date' => date(DATE_ATOM, strtotime($this->date)), 86 | 'sum' => $this->sum, 87 | ]; 88 | } 89 | 90 | /** 91 | * {@inheritdoc} 92 | */ 93 | public function getPayloadString() 94 | { 95 | return http_build_query($this->getPayload()); 96 | } 97 | 98 | /** 99 | * {@inheritdoc} 100 | */ 101 | public function getResponseClass() 102 | { 103 | return CheckExistResponse::class; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/request/LoginRequest.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class LoginRequest extends FnsCheckRequest 17 | { 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function getUrlPath() 22 | { 23 | return '/mobile/users/login/'; 24 | } 25 | 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function getHttpMethod() 30 | { 31 | return self::HTTP_METHOD_GET; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function getPayload() 38 | { 39 | return []; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function getPayloadString() 46 | { 47 | return http_build_query($this->getPayload()); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function getResponseClass() 54 | { 55 | return LoginResponse::class; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/request/RestoreRequest.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class RestoreRequest extends FnsCheckRequest 17 | { 18 | /** 19 | * Телефон пользователя. 20 | * 21 | * @var string 22 | */ 23 | public $phone; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getUrlPath() 29 | { 30 | return '/mobile/users/restore/'; 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getHttpMethod() 37 | { 38 | return self::HTTP_METHOD_POST; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function getPayload() 45 | { 46 | return [ 47 | 'phone' => $this->phone, 48 | ]; 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function getPayloadString() 55 | { 56 | return json_encode($this->getPayload()); 57 | } 58 | 59 | /** 60 | * {@inheritdoc} 61 | */ 62 | public function getResponseClass() 63 | { 64 | return RestoreResponse::class; 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | public function getHeaders() 71 | { 72 | return array_merge(parent::getHeaders(), [ 73 | 'Content-Type' => 'application/json; charset=UTF-8', 74 | ]); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/request/SignupRequest.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class SignupRequest extends FnsCheckRequest 17 | { 18 | /** 19 | * Email пользователя. 20 | * 21 | * @var string 22 | */ 23 | public $email; 24 | 25 | /** 26 | * Имя пользователя. 27 | * 28 | * @var string 29 | */ 30 | public $name; 31 | 32 | /** 33 | * Телефон пользователя. 34 | * 35 | * @var string 36 | */ 37 | public $phone; 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function getUrlPath() 43 | { 44 | return '/mobile/users/signup/'; 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function getHttpMethod() 51 | { 52 | return self::HTTP_METHOD_POST; 53 | } 54 | 55 | /** 56 | * {@inheritdoc} 57 | */ 58 | public function getPayload() 59 | { 60 | return [ 61 | 'email' => $this->email, 62 | 'name' => $this->name, 63 | 'phone' => $this->phone, 64 | ]; 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | public function getPayloadString() 71 | { 72 | return json_encode($this->getPayload()); 73 | } 74 | 75 | /** 76 | * {@inheritdoc} 77 | */ 78 | public function getResponseClass() 79 | { 80 | return SignupResponse::class; 81 | } 82 | 83 | /** 84 | * {@inheritdoc} 85 | */ 86 | public function getHeaders() 87 | { 88 | return array_merge(parent::getHeaders(), [ 89 | 'Content-Type' => 'application/json; charset=UTF-8', 90 | ]); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/response/CheckDetailResponse.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class CheckDetailResponse extends FnsCheckResponse 24 | { 25 | /** 26 | * Код ошибки существования чека. 27 | * Рекомендуется использовать при обработке загрузки чеков: 28 | * если исклюение имеет соответствующий код, 29 | * то необходимо повторить процедуру запроса чека. 30 | */ 31 | const ERROR_CODE_REGISTERED_CHECK = 1; 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function processHttpResponse() 37 | { 38 | $httpStatusCode = $this->httpResponse->getStatusCode(); 39 | 40 | if ($httpStatusCode === 200) { 41 | return; 42 | } 43 | 44 | if ($httpStatusCode !== 202) { 45 | throw new FnsCheckApiException($this->httpResponse->getBody()->getContents()); 46 | } else { 47 | throw new FnsCheckApiException( 48 | 'Check was registered. Try this call again.', 49 | self::ERROR_CODE_REGISTERED_CHECK 50 | ); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/response/CheckExistResponse.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class CheckExistResponse extends FnsCheckResponse 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function processHttpResponse() 28 | { 29 | $httpStatusCode = $this->httpResponse->getStatusCode(); 30 | 31 | if ($httpStatusCode === 204) { 32 | return; 33 | } 34 | 35 | throw new FnsCheckApiException($this->httpResponse->getBody()->getContents()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/response/LoginResponse.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class LoginResponse extends FnsCheckResponse 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function processHttpResponse() 27 | { 28 | if ($this->httpResponse->getStatusCode() === 200) { 29 | return; 30 | } 31 | 32 | throw new FnsCheckApiException($this->httpResponse->getBody()->getContents()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/response/RestoreResponse.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class RestoreResponse extends FnsCheckResponse 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function processHttpResponse() 28 | { 29 | if ($this->httpResponse->getStatusCode() === 204) { 30 | return; 31 | } 32 | 33 | throw new FnsCheckApiException($this->httpResponse->getBody()->getContents()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/response/SignupResponse.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class SignupResponse extends FnsCheckResponse 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function processHttpResponse() 28 | { 29 | if ($this->httpResponse->getStatusCode() === 204) { 30 | return; 31 | } 32 | 33 | throw new FnsCheckApiException($this->httpResponse->getBody()->getContents()); 34 | } 35 | } 36 | --------------------------------------------------------------------------------