kosov / fns-check

PHP клиент API ФНС для работы с онлайн-чеками
MIT License
29 stars 16 forks source link

Библиотека больше не работает #3

Open KyberPrizrak opened 4 years ago

KyberPrizrak commented 4 years ago

Раньше все работало отлично. А сегодня получил ошибку при вызове CheckExistRequest: {"update":true,"appstore":"https://apps.apple.com/ru/app/%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D1%87%D0%B5%D0%BA%D0%BE%D0%B2-%D1%84%D0%BD%D1%81-%D1%80%D0%BE%D1%81%D1%81%D0%B8%D0%B8/id1169353005","playmarket":"https://play.google.com/store/apps/details?id=ru.fns.billchecker","appstorebutton":"Обновить","playmarketbutton":"Обновить","message":"Уважаемый пользователь! \nДоступна новая версия приложения, пожалуйста установите обновление."}

Andrey9995 commented 4 years ago

Видимо больше и не заработает, последний коммит 2 года назад. Придется использовать официальное АПИ ФНС и получать мастер-токен на организацию. Эх, как все было просто с этой библиотекой

AsuRaHan commented 4 years ago

да лазеичку прикрыли в ФНС. придется снова ломать их обновленную приложуху для того что бы использовать новое API.

KyberPrizrak commented 4 years ago

Протокол похоже вообще поменяли, т.к. приложение теперь лезет не на https://proverkacheka.nalog.ru:9999/ а на https://irkkt-mobile.nalog.ru:8888/

MaiorovYury commented 4 years ago

Протокол похоже вообще поменяли, т.к. приложение теперь лезет не на https://proverkacheka.nalog.ru:9999/ а на https://irkkt-mobile.nalog.ru:8888/

а какие там методы используются, вам не удалось понять? И как вы поняли, что именно по этому адресу идут новые запросы? Я пробовал отсканировать чек в приложении с включенным canary http сниффере, но приложение выдавало "Неизвестная ошибка" - видимо у них стоит защита от снифферов

KyberPrizrak commented 4 years ago

MaiorovYury, я же выше написал: запросы идут по https, а значит весь трафик зашифрован. Обычный сниффер тут не поможет. Тут нужна либо декомпиляция apk-файла (ищи утилиты: apktool, apkstudio, dex2jar, jd-gui), или отладка.

pch-coder commented 4 years ago

Ушел от налоговой на сервис https://proverkacheka.com/ Предоставляют API по запросу.

3bl3gamer commented 4 years ago

Судя по http://leftjoin.ru/all/sobiraem-dannye-s-chekov-gipermarketov-na-python/ (камент внизу), теперь надо слать запросы на POST https://irkkt-mobile.nalog.ru:8888/v2/ticket c {"qr":"<данные из QR-кода>"} и GET https://irkkt-mobile.nalog.ru:8888/v2/tickets/<айди из ответа выше> для получения чека.

Вот только оба запроса требуют sessionId, и откуда его брать — не ясно.

Можно попробовать декомпилить приложение через какой-нибудь http://www.javadecompilers.com и покопаться в сорцах. В файле LoginApi.java есть такой кусок:

    @GET("/v2/mobile/users/esia/auth/url")
    C4804m<Response<EsiaGetUrlResponse>> getUrlOAuthEsia();

    @POST("/v2/mobile/users/esia/auth")
    C4804m<Response<LoginResponse>> loginEsia(@Body EsiaLoginRequest esiaLoginRequest);

    @POST("/v2/mobile/users/lkfl/auth")
    C4804m<Response<LoginResponse>> loginLkFL(@Body LkFkLoginRequest lkFkLoginRequest);

    @POST("/v2/mobile/users/social/auth/ok")
    C4804m<Response<LoginResponse>> loginSocial(@Body OkLoginRequest okLoginRequest);

    @POST("/v2/mobile/users/social/auth/vk")
    C4804m<Response<LoginResponse>> loginSocial(@Body VKLoginRequest vKLoginRequest);

    @POST("v2/auth/phone/verify")
    C4804m<Response<LoginResponse>> loginUser(@Body PhoneLoginRequest phoneLoginRequest);

    @POST("/v2/mobile/users/signup")
    C4804m<Response<Void>> registerUser(@Body RegisterUserRequest registerUserRequest);

    @POST("v2/auth/phone/request")
    C4804m<Response<Void>> singInByPhone(@Body PhoneSignInRequest phoneSignInRequest);

v2/auth/phone/request — начало регистрации по номеру, там надо отправить параметры phone, client_secret, captcha и os.

v2/auth/phone/verify — продолжение, принимает phone, code и client_secret. Вроде как возвращает в том числе как раз искомый session_id.

Теоретически, можно в приложении разгадать капчу, получить код, заслать его по последнему адресу и получить айди сессии. Практически он возвращает 400 без комменатриев. phone/request — аналогично. Более того: их кривое приложение тоже молча не принимает код из СМС.

3bl3gamer commented 4 years ago

UPD: если девайс рутован, sessionId можно вытащить из /data/data/ru.fns.billchecker/shared_prefs/ru.fns.billchecker_preferences.xml, искать KEY_ACCESS_TOKEN. На нерутованном, возможно, можно вытащить этот файл с помощью adb backup, если гугл ещё не сломал его окончательно.

Дальше можно сделать

curl -X POST 'https://irkkt-mobile.nalog.ru:8888/v2/ticket' \
  --data '{"qr":"<данные из QR-кода>"}'
  -H 'sessionId: <айди сессии>'
  -H 'Content-Type: application/json'

В ответ придёт

{"kind":"kkt","id":"<айди чека>","status":0}

Нюанс 0: Content-Type: application/json нужен для отправки JSON'а, иначе придёт ответ fiscalData parameter is required (возможно, сервер подефолту пытается парсить запрос как форму).

Нюанс 1: даже для невалидных (протухших?) чеков придёт такой же ответ, но в ответе на /v2/tickets/<id> данные чека будут пустыми.

Ну и потом

curl 'https://irkkt-mobile.nalog.ru:8888/v2/tickets/<айди чека>'
  -H 'sessionId: <айди сессии>'
  -H 'Device-OS: Android 4.4'
  -H 'Device-Id: iPhone 12'

В ответ придёт

{
  "id": "<id>",
  "status": 2,
  "kind": "kkt",
  "createdAt": "2020-08-14T10:07:19+03:00",
  "statusDescription": {},
  "qr": "<данные из куера>",
  "operation": { "date": "2020-07-26T04:41:00+03:00", "type": 1, "sum": 8080 },
  "seller": { "name": "ИП ...", "inn": "1234567890" },
  "process": [{ "time": "2020-08-14T10:07:19+03:00", "result": 2 }],
  "query": {
    "operationType": 1,
    "sum": 8080,
    "documentId": 55123,
    "fsId": "9280440300312584",
    "fiscalSign": "1857231278",
    "date": "2020-07-26T04:41"
  },
  "ticket": {
    "document": {
      "receipt": {
        "dateTime": 123546789,
        "authorityUri": "www.nalog.ru",
        "cashTotalSum": 0,
        "ecashTotalSum": 8080,
        "fiscalDocumentNumber": 55123,
        "fiscalDriveNumber": "9280440300312584",
        "fiscalSign": 1857231278,
        "items": [
          {
            "name": "083385:хлеб Гречневый 400г СП (БЕЗ НДС)",
            "price": 5790,
            "quantity": 1,
            "sum": 5790
          },
          ...
        ],
        "kktRegId": "0047419162022120",
        "ndsNo": 8080,
        "operationType": 1,
        "operator": "Глебова",
        "receiptCode": 3,
        "requestNumber": 109,
        "retailPlaceAddress": "...",
        "shiftNumber": 230,
        "taxationType": 2,
        "totalSum": 8080,
        "user": "ИП ...",
        "userInn": "1234567890"
      }
    }
  },
  "organization": { "name": "ИП ...", "inn": "1234567890" }
}

Для невалидного (протухшего?) чека придёт

{
  "id": "<id>",
  "status": 8,
  "kind": "kkt",
  "createdAt": "2020-08-14T10:15:10+03:00",
  "statusDescription": {},
  "qr": "<данные из QR-кода>",
  "operation": { "date": "2019-07-26T04:41:00+03:00", "type": 1, "sum": 8080 },
  "process": [],
  "query": {
    "operationType": 1,
    "sum": 8080,
    "documentId": 55123,
    "fsId": "9280440300312584",
    "fiscalSign": "1857231278",
    "date": "2019-07-26T04:41"
  }
}

Нюанс 0: заголовки Device-OS и Device-Id нужны, без них в ответ придёт Device-OS header is missing. / Device-Id header is missing..

keremet commented 4 years ago

Можно извлекать данные о чеке так: curl --data "fn=9251440300109733&fd=96304&fp=3341119416&n=1&s=55.00&t=02.08.2020+16%3A12&qr=0" https://proverkacheka.com/check/get

{"code":1,"data":{"json":{"user":"ООО Бэст Прайс","items":[{"sum":5500,"name":"Водная игра с колечками ИМП","price":5500,"ndsSum":500,"ndsRate":2,"quantity":1,"calculationTypeSign":4,"calculationSubjectSign":1}],"nds10":500,"fnsUrl":"www.nalog.ru","rawData":"AwCKAREEEAA5MjUxNDQwMzAwMTA5NzMzDQQUADAwMDEyODk4MDgwMDE0NzggICAg+gMMADUwNDcwODUwOTQgIBAEBAAweAEA9AMEANDlJl81BAYAMQTHJW+4DgQEABUBAAASBAQA8QAAAB4EAQAB\/AMCAHwVIwRIAAYEGwCCrqStoO8gqKPgoCDhIKquq6XnqqCsqCCIjI83BAIAfBX\/AwQABkBCDxMEAgB8Fa8EAQACsAQCAPQBvgQBAAS8BAEAAf0DQACMqOWgqauuoqAgkaKl4qugraAgjaiqrqugpaKtoCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgBwQBAAA5BAIAfBW\/BAEAAMAEAQAAwQQBAAAkBAwAd3d3Lm5hbG9nLnJ1owQMAKygo6CnqK0gMjQ3ObkEAQACTwQCAPQBGAQQAI6OjiAige3h4iCP4KCp4SLxAycANjEwMDAwLCCjLoqo4K6iLCDjqy6CruCuouGqrqOuLCCkLjcxLzgwHwQBAAE=","userInn":"5047085094","dateTime":"2020-08-02T16:12:00","kktRegId":"0001289808001478 ","metadata":{"id":"202008022021fc7ea9992270f30dd9b3f6c4f839fea1e328dc816b85d105b68ab8e9dea6","_id":{"$oid":"5f26bbd238ded66ec74df101"},"fsId":"9251440300109733","ofdId":"ofd1","subtype":"receipt","kktRegId":"0001289808001478","documentId":96304,"receiveDate":{"$date":1596373969620},"v2ValidateErr":"[\"#\/: Additional properties not allowed: prepaymentSum,postpaymentSum,counterSubmissionSum,fnsUrl,protocolVersion,retailPlace\"]","protocolVersion":"2","protocolSubversion":1},"operator":"Михайлова Светлана Николаевна ","totalSum":5500,"fiscalSign":"3341119416","receiptCode":3,"retailPlace":"магазин 2479","shiftNumber":277,"cashTotalSum":0,"taxationType":1,"ecashTotalSum":5500,"operationType":1,"prepaymentSum":0,"requestNumber":241,"postpaymentSum":0,"protocolVersion":2,"fiscalDriveNumber":"9251440300109733","retailPlaceAddress":"610000, г.Киров, ул.Воровского, д.71\/80","counterSubmissionSum":0,"fiscalDocumentNumber":96304},"html":"<table class=\"b-check_table table\"><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">ООО Бэст Прайс<\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">610000, г.Киров, ул.Воровского, д.71\/80<\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">ИНН 5047085094<\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\"> <\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">02.08.2020 16:12<\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">Чек № 241<\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">Смена № 277<\/td><\/tr><tr class=\"b-check_vblock-middle b-check_center\"><td colspan=\"5\">Кассир Михайлова Светлана Николаевна <\/td><\/tr><tr class=\"b-check_vblock-last b-check_center\"><td colspan=\"5\">Приход<\/td><\/tr>№<\/strong><\/td>Название<\/strong><\/td>Цена<\/strong><\/td>Кол.<\/strong><\/td>Сумма<\/strong><\/td><\/tr><tr class=\"b-check_item\">1<\/td>Водная игра с колечками ИМП<\/td>55.00<\/td>1<\/td>55.00<\/td><\/tr><tr class=\"b-check_vblock-first\"><td colspan=\"3\" class=\"b-check_itogo\">ИТОГО:<\/td><\/td><td class=\"b-check_itogo\">55.00<\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"3\">Наличные<\/td><\/td>0.00<\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"3\">Карта<\/td><\/td>55.00<\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"3\">НДС итога чека со ставкой 10%<\/td><\/td>5.00<\/td><\/tr><tr class=\"b-check_vblock-last\"><td colspan=\"5\">ВИД НАЛОГООБЛОЖЕНИЯ: ОСН<\/td><\/tr><tr class=\"b-check_vblock-first\"><td colspan=\"5\">РЕГ.НОМЕР ККТ: 0001289808001478 <\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"5\">ЗАВОД. №: <\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"5\">ФН: 9251440300109733<\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"5\">ФД: 96304<\/td><\/tr><tr class=\"b-check_vblock-middle\"><td colspan=\"5\">ФПД#: 3341119416<\/td><\/tr><tr class=\"b-check_vblock-last\"><td colspan=\"5\" class=\"b-check_center\"><img src=\"\/qrcode\/generate?text=t%3D20200802T1612%26s%3D55.00%26fn%3D9251440300109733%26i%3D96304%26fp%3D3341119416%26n%3D1\" alt=\"QR код чека\" width=\"35%\" loading=\"lazy\"><\/td><\/tr><\/tbody><\/table>"}}

3bl3gamer commented 4 years ago

Как минимум для некоторых старых (2019 год) чеков proverkacheka.com возвращает ошибку {"code":5,"data":"Нет информации по чеку (прочее)."}. А вот апи ФНС возвращает чек.

3bl3gamer commented 4 years ago

UPD: /v2/auth/phone/verify всё-таки работает, для неё нужно передать валидный client_secret. Его можно достать из файлов приложения из /data/data/ru.fns.billchecker/shared_prefs/ru.fns.billchecker_preferences.xml из значения VERSION. Этот секрет вычисляется внутри приложения из его подписи и, возможно, одинаковый для всех. Но я в этом не уверен, потому выкладывать свой не буду.

В общем...

План работы с АПИ

Все запросы идут на https://irkkt-mobile.nalog.ru:8888. POST'ы — c Content-Type: application/json. client_secret вынимается из VERSION приложения (см. выше).

POST /v2/auth/phone/request

Туда:

{"phone": "+79876543210", "client_secret": "sec123", "captcha": "???", "os": "Android"}

Оттуда:

Неизвестно.

Начало регистрации по номеру. Чтоб метод сработал, нужно отправить значение из гуглокапчи. Как его получать — не знаю, можно этот шаг пройти руками через приложение (разгадать капчу, выслать СМС-код себе на номер).

POST /v2/auth/phone/verify

Туда:

{"phone": "+79876543210", "code": "1234", "client_secret": "sec123"}
Доп.заголовки:
Device-OS: Android
Device-Id: Android

Оттуда:

{"sessionId": "sess12345", "refresh_token": "refr12345", "phone": "+79876543210"}

Подтверждение номера по коду из СМС. Возвращает айди сессии, с которым можно выполнять остальные запросы, и токен для обновления айди сессии (последний протухает через день-два).

Этот этап тоже можно пойти вручную через приложение и вынуть из ru.fns.billchecker_preferences.xml ещё и KEY_REFRESH_TOKEN.

POST /v2/mobile/users/refresh

Туда:

{"client_secret":"sec123", "refresh_token":"refr12345"}

Оттуда:

{"sessionId":"sess23456","refresh_token":"refr34567"}

Запрашивает новые айди сессии и токен (сессия протухает через 1-2 суток). Принимает предыдущий токен (полученный из /auth/phone/verify или /mobile/users/refresh).

POST /v2/ticket

"Создаёт" чек на сервере ФНС, возвращает айди, по котром уможно получить данные чека. Подробнее: https://github.com/kosov/fns-check/issues/3#issuecomment-674007910

GET /v2/tickets/<айди чека>

Возвращает данные чека. Подробнее: https://github.com/kosov/fns-check/issues/3#issuecomment-674007910

Статусы

У чеков есть status, его возвращает и /v2/ticket, и /v2/tickets/<id>. В декомпиленных сорцах рядом с некоторыми значениями есть текст:

5:  Ожидает соединения
8:  Автономная касса / Чек корректен, но отсутствует в хранилище: касса автономна
9:  Ошибка получения
15: Не кассовый чек / Чек не является кассовым чеком или БСО

Если передать неправильные параметры из QR-кода, тоже может придти статус 8 (Автономная касса).

Иногда приходят статусы 0/1/3. Точное их значение неизвестно, это что-то вроде "чек есть, ещё не загружен". При получении такого статуса стоит перезапросить чек через несколько секунд.

Для валидных чеков приходит статус 2.

kuznetsov-m commented 4 years ago

Можно извлекать данные о чеке так: curl --data "fn=9251440300109733&fd=96304&fp=3341119416&n=1&s=55.00&t=02.08.2020+16%3A12&qr=0" https://proverkacheka.com/check/get

{"code":1,"data":{"json":{"user":"ООО Бэст Прайс","items":[{"sum":5500,"name":"Водная игра с колечками ИМП","price":5500,"ndsSum":500,"ndsRate":2,"quantity":1,"calculationTypeSign":4,"calculationSubjectSign":1}],"nds10":500,"fnsUrl":"www.nalog.ru","rawData":"AwCKAREEEAA5MjUxNDQwMzAwMTA5NzMzDQQUADAwMDEyODk4MDgwMDE0NzggICAg+gMMADUwNDcwODUwOTQgIBAEBAAweAEA9AMEANDlJl81BAYAMQTHJW+4DgQEABUBAAASBAQA8QAAAB4EAQAB/AMCAHwVIwRIAAYEGwCCrqStoO8gqKPgoCDhIKquq6XnqqCsqCCIjI83BAIAfBX/AwQABkBCDxMEAgB8Fa8EAQACsAQCAPQBvgQBAAS8BAEAAf0DQACMqOWgqauuoqAgkaKl4qugraAgjaiqrqugpaKtoCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgBwQBAAA5BAIAfBW/BAEAAMAEAQAAwQQBAAAkBAwAd3d3Lm5hbG9nLnJ1owQMAKygo6CnqK0gMjQ3ObkEAQACTwQCAPQBGAQQAI6OjiAige3h4iCP4KCp4SLxAycANjEwMDAwLCCjLoqo4K6iLCDjqy6CruCuouGqrqOuLCCkLjcxLzgwHwQBAAE=","userInn":"5047085094","dateTime":"2020-08-02T16:12:00","kktRegId":"0001289808001478 ","metadata":{"id":"202008022021fc7ea9992270f30dd9b3f6c4f839fea1e328dc816b85d105b68ab8e9dea6","_id":{"$oid":"5f26bbd238ded66ec74df101"},"fsId":"9251440300109733","ofdId":"ofd1","subtype":"receipt","kktRegId":"0001289808001478","documentId":96304,"receiveDate":{"$date":1596373969620},"v2ValidateErr":"["#/: Additional properties not allowed: prepaymentSum,postpaymentSum,counterSubmissionSum,fnsUrl,protocolVersion,retailPlace"]","protocolVersion":"2","protocolSubversion":1},"operator":"Михайлова Светлана Николаевна ","totalSum":5500,"fiscalSign":"3341119416","receiptCode":3,"retailPlace":"магазин 2479","shiftNumber":277,"cashTotalSum":0,"taxationType":1,"ecashTotalSum":5500,"operationType":1,"prepaymentSum":0,"requestNumber":241,"postpaymentSum":0,"protocolVersion":2,"fiscalDriveNumber":"9251440300109733","retailPlaceAddress":"610000, г.Киров, ул.Воровского, д.71/80","counterSubmissionSum":0,"fiscalDocumentNumber":96304},"html":"

НазваниеЦенаКол.Сумма1Водная игра с колечками ИМП55.00155.000.0055.005.00
ООО Бэст Прайс
610000, г.Киров, ул.Воровского, д.71/80
ИНН 5047085094
 
02.08.2020 16:12
Чек № 241
Смена № 277
Кассир Михайлова Светлана Николаевна
Приход
ИТОГО:55.00
Наличные
Карта
НДС итога чека со ставкой 10%
ВИД НАЛОГООБЛОЖЕНИЯ: ОСН
РЕГ.НОМЕР ККТ: 0001289808001478
ЗАВОД. №:
ФН: 9251440300109733
ФД: 96304
ФПД#: 3341119416
QR код чека
"}}****

Спасибо за альтернативный API. К сожалению, многие чеки (даже этого месяца) не извлекаются. Кажется, тут собираются данные только некоторых ОФД. :(

pch-coder commented 4 years ago

Спасибо за альтернативный API. К сожалению, многие чеки (даже этого месяца) не извлекаются. Кажется, тут собираются данные только некоторых ОФД. :(

Насколько мне известно, на сервисе proverkacheka.com используется как официальный API в качестве источника данных, так и не официальный. Можете привести пару примеров чеков, которые не возвращаются. С ОФД точно сервис не работает.

titov-vv commented 4 years ago

Вот только оба запроса требуют sessionId, и откуда его брать — не ясно. Теоретически, можно в приложении разгадать капчу, получить код, заслать его по последнему адресу и получить айди сессии. Практически он возвращает 400 без комменатриев. phone/request — аналогично. Более того: их кривое приложение тоже молча не принимает код из СМС.

SessionId можно брать тремя путями: 1) через номер телефона. Тут проблема только в reCAPTCHA для андроид - на андроиде это вызов одной функции, которая возвращает токен. Как сделать точно такой же вызов google API не с андроид - непонятно. 2) через логин-пароль личного кабинета налоговой. Тут всё просто, даже писать не о чем. 3) через ЕСИА - логин на госуслугах. В целом несложно - сервер возвращает URL на госуслуги, его надо отобразить пользователю в виде вебстранички. Далее всё делается пользователем через браузер и при успешном логине идёт редирект на irkkt-mobile.ru через 302-й код ответа. Его нужно перехватить и забрать оттуда ответный токен госуслуг.

titov-vv commented 4 years ago

POST /v2/auth/phone/request

Туда:

{"phone": "+79876543210", "client_secret": "sec123", "captcha": "???", "os": "Android"}

Оттуда:

Неизвестно.

Известно. Если запрос выполнится успешно (капча пройдёт) то в ответ прилетит код ответа 204 No Content и SMS на телефон.

Начало регистрации по номеру. Чтоб метод сработал, нужно отправить значение из гуглокапчи. Как его получать — не знаю, можно этот шаг пройти руками через приложение (разгадать капчу, выслать СМС-код себе на номер).

POST /v2/auth/phone/verify

Известно. Токен получается в ответ на вызов функции verifyWithRecaptcha из гугл-апи на Андроиде. Там также есть привязка к имени приложения - т.е. просто вызвать эту функцию с нужными параметрами из другого приложения не получится :( Если пробовать эмулировать с компа - то она шлёт POST-запрос на https://www.google.com/recaptcha/api2/mframe с кучей не всегда очевидных параметров - в ответ прилетает HTML-страница для разгадки капчи (у меня толком не получилось её отобразить....)

titov-vv commented 4 years ago

Ещё пара моментов 1) есть запрос GET https://irkkt-mobile.nalog.ru:8888/v2/tickets - он выдаёт JSON со всеми чеками, которые проверялись с этого аккаунта (не знаю правда есть ли ограничение по длине или разбивка по сегментам...) 2) помимо SessionId после успешной аутентификации прилетает "refresh_token" - что это и как используется пока не ясно. UPD. Прочитал выше, понял что с его помощью можно продлить сессию. 3) client_secret разных для разных установок приложения - вероятно Device-Id из заголовков используется (или не используется) только на уровне http, а далее связка sessionId с конкретным устройством идёт по client_secret, который представляет из себя base64-хэш чего-то там (ну так показалось...)

kuznetsov-m commented 4 years ago

Спасибо за альтернативный API. К сожалению, многие чеки (даже этого месяца) не извлекаются. Кажется, тут собираются данные только некоторых ОФД. :(

Насколько мне известно, на сервисе proverkacheka.com используется как официальный API в качестве источника данных, так и не официальный. Можете привести пару примеров чеков, которые не возвращаются. С ОФД точно сервис не работает.

t=20200810T1807&s=225.95&fn=9289000100589506&i=8411&fp=171824441&n=1 t=20200709T131900&s=257.16&fn=9289000100516985&i=145099&fp=1980379027&n=1

gidbrn commented 4 years ago

Спасибо за альтернативный API. К сожалению, многие чеки (даже этого месяца) не извлекаются. Кажется, тут собираются данные только некоторых ОФД. :(

Насколько мне известно, на сервисе proverkacheka.com используется как официальный API в качестве источника данных, так и не официальный. Можете привести пару примеров чеков, которые не возвращаются. С ОФД точно сервис не работает.

t=20200810T1807&s=225.95&fn=9289000100589506&i=8411&fp=171824441&n=1 t=20200709T131900&s=257.16&fn=9289000100516985&i=145099&fp=1980379027&n=1

Проверил, сервис все возвращает, у вас параметры запроса указаны не верно, Ошибка при передачи в формате времени. Вот верные: fn=9289000100589506&fd=8411&fp=171824441&n=1&s=225.95&t=10.08.2020+18%3A07&qr=0 fn=9289000100516985&fd=145099&fp=1980379027&n=1&s=257.16&t=09.07.2020+13%3A19&qr=0

kuznetsov-m commented 4 years ago

Спасибо за альтернативный API. К сожалению, многие чеки (даже этого месяца) не извлекаются. Кажется, тут собираются данные только некоторых ОФД. :(

Насколько мне известно, на сервисе proverkacheka.com используется как официальный API в качестве источника данных, так и не официальный. Можете привести пару примеров чеков, которые не возвращаются. С ОФД точно сервис не работает.

t=20200810T1807&s=225.95&fn=9289000100589506&i=8411&fp=171824441&n=1 t=20200709T131900&s=257.16&fn=9289000100516985&i=145099&fp=1980379027&n=1

Проверил, сервис все возвращает, у вас параметры запроса указаны не верно, Ошибка при передачи в формате времени. Вот верные: fn=9289000100589506&fd=8411&fp=171824441&n=1&s=225.95&t=10.08.2020+18%3A07&qr=0 fn=9289000100516985&fd=145099&fp=1980379027&n=1&s=257.16&t=09.07.2020+13%3A19&qr=0

Это я скидывал в формате как в qr коде данные лежат, но вы правы я не правильно формировал request. Тогда оставлю тут другие чеки, которые успешно проверяются в приложении ФНС, но отсутствуют в proverkacheka.com
t=20200810T211400&s=119.80&fn=9282440300472854&i=3414&fp=2264802964&n=1 t=20200802T1652&s=250.00&fn=9280440300582341&i=5308&fp=527693213&n=1

gidbrn commented 4 years ago

Спасибо за альтернативный API. К сожалению, многие чеки (даже этого месяца) не извлекаются. Кажется, тут собираются данные только некоторых ОФД. :(

Насколько мне известно, на сервисе proverkacheka.com используется как официальный API в качестве источника данных, так и не официальный. Можете привести пару примеров чеков, которые не возвращаются. С ОФД точно сервис не работает.

t=20200810T1807&s=225.95&fn=9289000100589506&i=8411&fp=171824441&n=1 t=20200709T131900&s=257.16&fn=9289000100516985&i=145099&fp=1980379027&n=1

Проверил, сервис все возвращает, у вас параметры запроса указаны не верно, Ошибка при передачи в формате времени. Вот верные: fn=9289000100589506&fd=8411&fp=171824441&n=1&s=225.95&t=10.08.2020+18%3A07&qr=0 fn=9289000100516985&fd=145099&fp=1980379027&n=1&s=257.16&t=09.07.2020+13%3A19&qr=0

Это я скидывал в формате как в qr коде данные лежат, но вы правы я не правильно формировал request. Тогда оставлю тут другие чеки, которые успешно проверяются в приложении ФНС, но отсутствуют в proverkacheka.com t=20200810T211400&s=119.80&fn=9282440300472854&i=3414&fp=2264802964&n=1 t=20200802T1652&s=250.00&fn=9280440300582341&i=5308&fp=527693213&n=1

По строке t=20200810T211400&s=119.80&fn=9282440300472854&i=3414&fp=2264802964&n=1 время запроса не верно через API запрашивали.

По строке t=20200802T1652&s=250.00&fn=9280440300582341&i=5308&fp=527693213&n=1 получил чек со второй попытки, ваша первая была (такое бывает)

titov-vv commented 4 years ago

Небольшое наблюдение по статусам. По свежему чеку обычно прилетает status=0. При следующем запросе приходит status=3. И на третий раз прилетает сам чек и status=2. Такое ощущение, что есть как минимум 2 различных хранилища - одно, там где всё лежит в общей куче и непонятно будет нужно или нет. И другое - откуда чек форматируется и отдаётся клиенту. Т.е. первым запросом мы как бы инициируем загрузку чека из "храналища" в "кэш" и status 0 подтверждает успештую обработку запроса. Далее чек какое-то время "передаётся" из одного места в другое и status 3 это что-то вроде "in progress". Ну и финальное status 2 - чек доступен.

Могу заподозрить, что в этой парадигме status 1 может означать, что запрос на загрузку в кэш отклонён, а status 4 - что что-то сломалось при зарузке и чек не доехал до "кэша"... Но последнее предложение - это лишь предположение.

kuznetsov-m commented 4 years ago

@gidbrn Для большинства моих чеков при проверке через api сервис возвращает:

{"code": 5, "data": "Нет информации по чеку (прочее)."}

Эти же чеки, при проверке через web интерфейс, не загружаются и сервис предлагает оставить почту и получить чек позже. Через час, чек уже на почте, и после этого, при проверке через api я уже могу получить чек. Вы не сталкивались с такой проблемой?

Вот этот чек я изначально не мог получить, но после того как в web версии оставил свою почту, чек появился.

(привожу в формате, как в qr коде)
t=20200829T153200&s=955.00&fn=9280440300613855&i=99094&fp=1926717587&n=1

а для этого не оставлял почту, и сейчас api и web не находят чек

t=20200903T1729&s=1031.01&fn=9282440300783448&i=9421&fp=509186154&n=1
gidbrn commented 4 years ago

@kuznetsov-m Обратите внимание, у вас в вызове: t=20200903T1729&s=1031.01&fn=9282440300783448&i=9421&fp=509186154&n=1

параметр i должен стать параметром fd: t=20200903T1729&s=1031.01&fn=9282440300783448&fd=9421&fp=509186154&n=1

kuznetsov-m commented 4 years ago

@gidbrn Обновил сообщение, выше, кажется дело не в запросе.

Строки я привожу в том виде, в котором они в qr коде записаны. При формировании api запроса, конечно я меняю и формат времени и название переменной i заменяю на fd.

gidbrn commented 4 years ago

@kuznetsov-m а что вы понимаете под API и WEB вариантами? WEB через браузер - чек смотрю в базе получен API - так там обращения через персональный токен, необходимо зарегистрироваться в личном кабинете и написать на почту на запрос токена, в ответ придет и документация API - по тому формату как обращается браузер возможно изменится (планируем)

Странно, но по строке ниже, данные пришли в БД: t=20200903T1729&s=1031.01&fn=9282440300783448&i=9421&fp=509186154&n=1

Указание почты не на что не влияет. Фактически если чек не был получен в течении 30 секунд - запрос прерывается и показывается окно диалога с запросом почты. По статистике - 98% чеков по информации с QR кода отдаются API. при ручном вводе из-за ошибок - меньше.

PS В API есть возможность прямо строку с QR кода отправлять

kuznetsov-m commented 4 years ago

@gidbrn web - это вариант зайти на сайт proverkacheka.com, ввести данные чека в соответствующие поля, запросить чек. api - это послать запрос на https://proverkacheka.com/check/get с параметрами

так вот, оба выше названных чека не проверялись, ни через веб ни через api. Первый мне удалось получить только после того как в веб версии я оставил почту. А второй, получил после того как вы его сами проверили в базе. Есть еще пачка чеков, которые по прежнему невозможно получить ни через web, ни через api.

По поводу токена для запросов в proverkacheka.com: запрос в https://proverkacheka.com/check/get же без токена работает? (кстати, токен платный?)

gidbrn commented 4 years ago

@kuznetsov-m

Запрос в https://proverkacheka.com/check/get работает без токена, но интерфейс может меняться и не рекомендуется к использованию. Рекомендую получить API и токен по запросу (токен бесплатный для личного использования), плюс чеки в публичке не выводятся

Делайте запрос чека и пишите на почту webmaster@proverkacheka.com реквизиты чека, будем смотреть что получилось, а что нет.

kuznetsov-m commented 4 years ago

@titov-vv

По свежему чеку обычно прилетает status=0. При следующем запросе приходит status=3. И на третий раз прилетает сам чек и status=2.

У меня по свежему чеку (операция прошла 2 часа назад). Висит статус "2" уже более 15 минут, проверил чек уже раз 5-6 за это время. Видимо загрузка в кэш не всегда оперативная и не зависит от количества запросов.

Приложение ФНС пишет статус: Получение

3bl3gamer commented 4 years ago

Такое ощущение, что есть как минимум 2 различных хранилища - одно, там где всё лежит в общей куче и непонятно будет нужно или нет. И другое - откуда чек форматируется и отдаётся клиенту.

Да, и скорее всего первое хранилищие — это ОФД (точнее, хранилища: Операторы Фискальных Данных), второе — сама ФНС. Судя по ссылке, ОФД много (18 было 2 года назад), они должны хранить чеки 5 лет и отдавать их по запросу в налоговую. У некоторых ОФД на сайте есть своя проверка чеков, но работает она только по базе этой ОФД. И тут может быть одна из причин задержки: сервер ОФД может прилечь.

А ещё касса может отправить чек своему ОФД далеко не сразу: судя по тому же сайту, Фискальный накопитель кассы способен работать 30 дней в автономном режиме. И это ещё одна (и наверно набиолее вероятная) причина задержки.

pawellrus commented 3 years ago

Может кто нибудь пробовал получать чеки через https://irkkt-mobile.nalog.ru:8888/v2/tickets с фильтрацией по дате? Это вообще возможно? Получать все чеки и потом отбирать по id те, которые еще не обрабатывались - конечно вариант хороший, но что будет когда чеков будет 1000 или 10000?

sasha127 commented 3 years ago

@pawellrus чеки можно удалять из списка отправкой HTTP запроса: DELETE /v2/tickets/<id чека> После этого чек пропадёт из общего списка и будет недоступен по своему id. При повторном запросе чека он опять станет доступным по тому же id.

nikolaynau commented 2 years ago

Собрал всю информацию воедино и описал в спецификации FNS API Specification. Также по своей спецификации сделал библиотеку на typescript fns-api.

Chuvi-w commented 2 years ago

@nikolaynau, а можно вопрос: зачем на английском-то? Я понимаю когда на английском документируется что-то, что полезно всему миру. Но эта же штуковина - чисто российская. В других странах она не нужна.

nikolaynau commented 2 years ago

@nikolaynau, а можно вопрос: зачем на английском-то? Я понимаю когда на английском документируется что-то, что полезно всему миру. Но эта же штуковина - чисто российская. В других странах она не нужна.

Добавил русскую версию Спецификация ФНС API.

nikolaynau commented 2 years ago

Еще добавил библиотеку fns-client. Она использует библиотеку fns-api и скрывает детали с обновлением токена авторизации.