С 1 января 2019 года для четырёх субъектов Российской Федерации (Москвы, Московской и Калужской областей, а также республики Татарстан) был принят закон, внедряющий пилотным проектом новый Налог на Профессиональную Деятельность (НПД). Если вкратце, его главная задача — избавить профессиональных деятелей от всех трудностей малого бизнеса: налога 6% (в случае с ИП), обязательных пенсионных взносов, сумма которых с каждым годом лишь за одного себя приближается к отметке 50 тысяч рублей, налоговой декларации. Тем самым государство поддерживает малый бизнес, предоставляя начинающим предпринимателям невысокий налог (4% за доход от физических лиц и 6% — от юридических). Если желаете больше подробностей — можете посмотреть детальную информацию в интернете.

НПД вправе пользоваться даже физические лица, которые работают в сфере IT. Как это может помочь? Например, вы разработали сервис, который работает в интернете, вы хотите принимать платежи. Вам не придётся ради такой предпринимательской деятельности регистрировать юрлицо и с самого старта решать кучу вопросов. Достаточно лишь зарегистрироваться как самозанятый и на честном слове вручную забивать каждую услугу или товар. В тот же миг разработчик сервиса задумывается: «А можно ли этот процесс автоматизировать?». И ответ здесь — «Разумеется, можно!». Статья, собственно, и заключается в том, чтобы рассказать вам, как это делается.
Важное замечание: автор статьи использует знания, полученные в результате исследования приложения, только для добра — автоматизации рутины. Таких же мотивов он желает и вам.

Шаг 1. Определение HTTP трафика


Здесь потребуется официальное приложения налогоплательщика «Мой налог». Скачать его можно через Google Play.

Для данной статьи будет достаточно определить sourceDeviceId (подозреваю, что это то же самое, что и android id) и refreshToken, однако исследовать можно абсолютно все методы API, предложенные приложением к изучению. Чтобы его определить — нужно получить HTTPS запросы смартфона. Для стокового устройства без root прав можно воспользоваться компьютером, бесплатной программой Fiddler. Чтобы разобраться в работе программы, я воспользовался не совсем актуальным руководством, однако и его было достаточно, чтобы перехватить https трафик смартфона и отобразить работу приложения на экран компьютера.

После установки всего необходимого надо зарегистрироваться как налогоплательщик и закрыть приложение. Затем активизировать работу программы Fiddler, наладить прокси соединение на смартфоне и запустить приложение заново. Приложение сделает запрос авторизации с refresh token'ом, который на момент этой статьи создаётся с бессрочным сроком действия:

image

Как можно заметить на скриншоте, приложение имеет базовый домен lknpd.nalog.ru (субдомен сайта налоговой службы РФ) и версию API 1. Авторизация для методов используется Bearer, токен для него генерируется через метод /auth/token. Данные из полей запроса sourceDeviceId и refreshToken вам крайне необходимы. Я проверял работу refreshToken'a через 3 дня после эксперимента — он работает, следовательно, token на 1 час можно спокойно брать, заведомо имея один актуальный refreshToken.

Сам метод отправки прихода выглядит так и имеет все необходимые поля:

image

Учтите, что все поля обязательны к заполнению. Поле services может вызвать у вас желание отправлять несколько услуг в массиве, однако на чеке отобразится лишь первая услуга, хотя и конечная стоимость будет полной. Всё-таки сервис достаточно сыроват, да и запущен лишь недавно, зацикливаться на этом не будем (хотя обидно на самом деле, несколько позиций порой необходимы).

Стоит также обратить внимание на ответ: approvedReceiptUuid: поле содержит уникальный код чека, который безо всяких трудностей можно получить по вашему ИНН и UUID чека.

Шаг 2. Разработка скрипта


Чтобы быстро продемонстрировать концепт автоматизации используется Python 3.7.2 с библиотекой requests:

import requests
import datetime
import shutil

TIME_OFFSET = '+03:00'
DEVICE_ID = ''
REFRESH_TOKEN = ''
API_PROVIDER = 'https://lknpd.nalog.ru/api/v1/'
TOKEN = ''
INN = ''


def DO(method, params):
    headers = {"Authorization":"Bearer "+TOKEN} if TOKEN != '' else {}
    r = requests.post(API_PROVIDER+method, json=params, headers=headers)
    print(r.text)
    return r.json()

def get_token():
    reqparam = {
	"deviceInfo": {
            "appVersion": "1.0.0",
	    "metaDetails": {
		"browser": "",
                "browserVersion": "",
                "os": "android"
            },
            "sourceDeviceId": DEVICE_ID,
            "sourceType": "android"
	},
	"refreshToken": REFRESH_TOKEN
    }
    res = DO('auth/token', reqparam)
    # TODO: сохранять tokenExpireIn и не вызывать авторизацию каждый раз
    return res['token']


# TODO: научиться нормально программировать
TOKEN = get_token()


def new_transaction(service, amount):
    trans_time = datetime.datetime.now().isoformat()[:-3]+TIME_OFFSET
    reqparam = {
	"ignoreMaxTotalIncomeRestriction": False,
	"operationTime": trans_time,
	"paymentType": "CASH",
	"requestTime": trans_time,
	"services": [
            {
                "amount": amount,
		"name": service,
		"quantity": 1
            }
	],
	"totalAmount": amount
    }
    res = DO('income', reqparam)
    return res['approvedReceiptUuid']

def get_receipt(receipt_uuid):
    headers = {"Authorization":"Bearer "+TOKEN}
    r = requests.get(
        'https://lknpd.nalog.ru/api/v1/receipt/'+INN+"/"+receipt_uuid+"/print",
        stream=True,
        headers=headers
    )
    with open('receipt.png', 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)
    
if __name__ == '__main__':
    rec = new_transaction('Тестовая услуга', '1.00')
    get_receipt(rec)

Подставьте необходимые значения — скрипт сработает, как надо. Можете добавлять обработчики ошибок и улучшать доставку — изложенный выше скрипт лишь показывает принцип работы с API НПД налоговой.
Замечание Возможно, в дальнейшем налоговая опубликует API, а сейчас этого не делает лишь потому, что это мало кому требуется. Следовательно, это дело отложено на потом. Однако спешу заметить, что если официальное руководство и будет опубликовано — в нём будет либо аналогичная информация, либо слегка усовершенствованная, в плане авторизации уж точно.


Заключение


В заключение хочется отметить: не повторяйте это дома нет ничего невозможного. Даже такую рутинную вещь можно спокойно автоматизировать. Копируйте код, дорабатываете на свой лад. Возможно, потом реализую библиотеку, чтобы автоматизация была намного доступнее всем желающим. Жду вашей объективной критики и продолжаю копать в сторону API. Моя следующая цель — идеализировать принцип авторизации и создать библиотеку для Python.

Комментарии (5)


  1. YuryZakharov
    18.01.2019 20:24
    -2

    Хорошо, давайте покритикую, по мере сил.
    По статье — непонятно, что за сервис такой, этот lknpd.nalog.ru, что он предоставляет, каков его официальный статус? Хотя бы тезисно. А то, получается, вот вам код, чтобы отправлять ваши данные непонятно куда.
    Про саму идею:
    Библиотека для доступа к такому сервису — это очень полезно и круто, но… Закладываться на то, что токен будет и дальше неизменным, по меньшей мере недальновидно.
    Использовать серый доступ к официальному ресурсу и распространять это среди сообщества — так себе идея.
    Вы проводили исследования на предмет получить нормальный доступ к предоставляемому API? Его просто не может не быть, мобильное-то приложение работает. Даже не заглядывая на их сайт, могу предположить, что для разработчиков предоставляют API Key или что-то подобное.

    А тут немного злобного сарказма
    # TODO: научиться нормально программировать

    Чтобы взять эту ачивку, надо научиться формулировать свои мысле прежде всего на естественном языке.
    Чтобы не писать вот такого:
    Более детальную информацию приглашаю к изучению в интернете

    Данный налог предлагает к регистрации даже физлиц

    А там и формальные языки подтянутся и прочий программизм.
    Без обид, просто тяжело читать такое.


    1. anotherpit
      19.01.2019 00:28

      Ну, так-то nalog.ru — официальный сайт Федеральной Налоговой Службы. А lknpd, очевидно поддомен, личного кабинета для НПД.


      1. YuryZakharov
        19.01.2019 14:45

        Об этом в статье должно быть сказано, а не читатель из константы в коде должен догадываться. Без всяких «очевидно».
        Разве это не очевидно?


  1. 0pauc0
    19.01.2019 01:49

    С 1 января 2019 года для четырёх субъектов Российской Федерации (Москвы, Московской, Казанской и Калужской областей)
    Казанская область? Аккуратней!


    1. Chronosmsx Автор
      19.01.2019 01:49

      Да, спасибо, немного не уследил, исправил этот момент