| public | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| error.json | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.MD | ||
| server.js | ||
FNS Receipt Service
Express-сервис на Node.js 22 для создания чеков через ФНС и отправки ссылки на чек по email.
Локальный запуск
npm install
cp .env.example .env
npm start
Сервис запустится на порту из PORT или на 4000 по умолчанию.
Админ-интерфейс доступен по адресу:
GET /admin
Для входа используется значение API_PASS. Через интерфейс можно смотреть локальный журнал чеков, синхронизировать последние чеки из кабинета ФНС, создавать чек вручную, проверять ФНС/SMTP и менять параметры сервиса без отдельного фронтенд-фреймворка.
Swagger UI доступен по адресу:
GET /swagger
OpenAPI JSON доступен по адресу:
GET /openapi.json
Docker
Сборка образа:
docker build -t fns-receipt-service .
Запуск контейнера:
docker run --env-file .env -p 3000:3000 fns-receipt-service
Переменные окружения
Заполните эти переменные в Timeweb Cloud в разделе переменных окружения:
INN=123456789012
PASSWORD=your_fns_password
APPNAME=Название проекта
ADMIN_EMAIL=admin@example.com
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=noreply@example.com
SMTP_PASS=email_app_password
SMTP_MAIL_FROM=noreply@example.com
API_PASS=strong_api_password
JWT_SECRET=long_random_jwt_secret
ADMIN_SESSION_HOURS=12
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_USER=default
REDIS_PASS=redis_password
REDIS_DB=0
REDIS_KEY_PREFIX=fns-receipt-service
REDIS_TIMEOUT_MS=5000
PORT=3000
HOST=0.0.0.0
FNS_TIMEOUT_MS=30000
SMTP_TIMEOUT_MS=15000
API_PASS используется как пароль входа в админ-панель и должен совпадать с api_pass в старых запросах к POST /api/v1/create-receipt. После входа UI получает JWT и дальше отправляет запросы с Authorization: Bearer <token>.
JWT_SECRET лучше задавать отдельно от API_PASS. Если JWT_SECRET не задан, сервис подпишет JWT через API_PASS, но для продакшена это менее удобно при ротации пароля.
Настройки, измененные через UI, сохраняются в data/config.json и перекрывают значения из .env. Сетевые параметры PORT и HOST применятся после перезапуска процесса.
Чеки сохраняются в Redis, если задан REDIS_URL или REDIS_HOST. Основной ключ:
fns-receipt-service:receipts
Префикс можно изменить через REDIS_KEY_PREFIX. Если Redis не настроен или временно недоступен, сервис использует локальный fallback data/receipts.json.
Timeweb Cloud
Что заполнить при Docker-деплое:
| Поле | Значение |
|---|---|
| Dockerfile | Dockerfile |
| Порт | 3000 |
| Путь до директории проекта | /fns-receipt-service |
| Путь проверки состояния | /health |
Команду запуска для Docker-деплоя отдельно указывать не нужно: она уже задана в Dockerfile как CMD ["node", "/app/server.js"].
API
Документация доступна в Swagger UI:
GET /swagger
Авторизация API поддерживает два способа:
Authorization: Bearer <token>после логина черезPOST /api/v1/auth/loginx-api-key: <API_PASS>для серверных интеграций
Для совместимости POST /api/v1/create-receipt также принимает api_pass в JSON body.
Проверка состояния:
GET /health
Получить JWT:
POST /api/v1/auth/login
Content-Type: application/json
{
"password": "strong_api_password"
}
Создание чека:
POST /api/v1/create-receipt
Content-Type: application/json
X-Api-Key: strong_api_password
{
"email": "client@example.com",
"items": [
{
"id": "order-1",
"name": "Услуга",
"price": 1000,
"quantity": 1
}
]
}
Поле email обязательно: на этот адрес сервис отправит письмо со ссылкой на чек после успешного создания чека в ФНС.
Получить журнал чеков:
GET /api/v1/receipts?limit=50&offset=0&status=created&clientType=individual&search=client@example.com
X-Api-Key: strong_api_password
Журнал можно фильтровать по периоду через dateFrom и dateTo:
GET /api/v1/receipts?dateFrom=2026-06-01&dateTo=2026-06-30
X-Api-Key: strong_api_password
Экспортировать все чеки за период в CSV без пагинации:
GET /api/v1/receipts/export?dateFrom=2026-06-01&dateTo=2026-06-30
X-Api-Key: strong_api_password
Получить один чек:
GET /api/v1/receipts/{receiptId}
X-Api-Key: strong_api_password
Синхронизировать чеки из ФНС за месяц:
POST /api/v1/receipts/sync
Content-Type: application/json
X-Api-Key: strong_api_password
{
"month": "2026-06"
}
Если чек создан в ФНС, но письмо клиенту не отправилось, API вернет success: true, receiptCreated: true, emailSent: false, receiptId, printLink и technicalError. Ошибка отправки сохранится в error.json.
Все успешно созданные чеки сохраняются в Redis, чтобы в UI была связь между чеком, email пользователя и позициями заказа. Синхронизация с ФНС выполняется за выбранный месяц, подтягивает страницы по 50 записей до конца месяца и помечает аннулированные чеки как cancelled. Аннулированные чеки показываются в списке, но не учитываются в количестве действующих чеков и итоговой сумме.
В UI и API по каждому чеку рассчитываются суммы grossAmount (грязными), taxAmount (налог) и netAmount (чистыми). Для физлиц используется ставка 4%, для юрлиц 6%.