Перейти к содержанию

Каталог переменных окружения

Полный справочник env-переменных Payment Manager: типы, дефолты, обязательность, место использования и пример значения. Источник истины — src/shared/config.ts (Zod-схема). Этот документ — отражение схемы, а не её замена: при расхождении приоритет у кода.

Назначение

Payment Manager инициализирует конфигурацию один раз при старте процесса через envSchema.safeParse(process.env) в src/shared/config.ts. Любая невалидная или отсутствующая обязательная переменная приводит к немедленному падению с диагностическим сообщением (Invalid environment variables: ...).

Каталог ниже покрывает все 28 переменных, объявленных в config.ts, сгруппированных по функциональным областям, а также явно фиксирует расхождения с .env.example.

Таблица env vars

Имя Тип Дефолт Обязательная Описание Где используется Пример
NODE_ENV enum (development | test | production) development нет Режим работы процесса; влияет на логирование, hot-reload и поведение тестов. src/shared/config.ts, src/server.ts production
PORT number 3000 нет TCP-порт HTTP-сервера Fastify (входящие /intents, admin endpoints, healthchecks). src/server.ts 3000
DATABASE_URL string да DSN PostgreSQL (через PgBouncer). PM использует search_path=pm,public; запись только в pm.*. src/db/client.ts, миграции Drizzle postgres://pm_user:pm_password@localhost:5433/onewallet
REDIS_URL string да Основной Redis для pub/sub (intent.{id}), кешей и временных структур координации. src/shared/redis.ts, intent streamer redis://localhost:6379
NOTIFICATIONS_REDIS_URL string нет Отдельный Redis-инстанс для очереди уведомлений (stream.notifications.jobs). Если не задан — используется основной REDIS_URL. src/notifications/* redis://notifications-redis:6379
ADMIN_SECRET string (≥32) да Bearer-токен для admin-эндпоинтов PM (диагностические запросы, ручные ремедиации). src/admin/*, middleware requireAdmin change-me-to-a-strong-secret-32chars
TB_ADDRESS string (≥10) да Адрес TigerBeetle replica (формат host:port). PM — единственный клиент TB на write. src/ledger/tb-client.ts 127.0.0.1:3001
OUTBOX_INTERVAL_MS number 1000 нет Период опроса таблицы pm.outbox воркером OutboxWorker. src/workers/outbox-worker.ts 1000
IPPS_BASE_URL string (url) https://promptpay-api-sit.ipps.cloud нет Базовый URL IPPS PromptPay eXchange (SIT/PROD). src/psp/ipps/driver.ts https://promptpay-api.ipps.cloud
IPPS_API_KEY string test-api-key нет API-ключ IPPS, выдаётся командой интеграции. В продакшене обязателен. src/psp/ipps/driver.ts sit-xxxxxxxxxxxxxxxx
IPPS_PARTNER_ID string 00 нет Идентификатор партнёра IPPS. src/psp/ipps/driver.ts 00
IPPS_HTTP_TIMEOUT_MS number (>0) 8000 нет Таймаут HTTP-запросов к IPPS. src/psp/ipps/driver.ts 8000
WORKER_ROLES string→string[] (CSV) api,outbox-worker нет Список ролей, которые запускает данный процесс. Допустимые значения: api, outbox-worker, psp-worker, invoice-expiry. src/server.ts (роутинг bootstrap) api,outbox-worker,psp-worker
PSP_NAMES string→string[] (CSV) IPPS нет Список PSP, обрабатываемых psp-worker-ролью. src/psp/worker.ts IPPS
BALANCE_MONITOR_ENABLED boolean (строка 'true' | 'false') false нет Включает фоновый мониторинг баланса IPPS-аккаунта (drift и low-balance алерты). src/psp/ipps/balance-monitor.ts true
PSP_POLL_INTERVAL_MS number (>0) 500 нет Интервал опроса очереди pm.psp_tx_map воркером PSP (FOR UPDATE SKIP LOCKED). src/psp/worker.ts 500
PSP_LEASE_SEC number (>0) 10 нет Длительность аренды (lease) задачи PSP при первичной обработке. src/psp/worker.ts 10
PSP_RETRY_LEASE_SEC number (>0) 30 нет Длительность аренды при ретрае (более длинная — даёт время IPPS ответить inquiry). src/psp/worker.ts 30
PSP_MAX_RETRIES number (>0) 3 нет Максимум попыток PSP-операции перед переводом в DEAD. src/psp/worker.ts 3
INVOICE_QR_SECRET string (≥32) да Секрет HMAC-подписи QR-кодов merchant-инвойсов. Утечка = возможность подделки QR. src/invoice/qr-signer.ts change-me-to-strong-invoice-qr-secret-min32chars
INVOICE_DEFAULT_TTL_SECONDS number (>0) 600 нет TTL инвойса по умолчанию (10 минут), если merchant не указал явно. src/invoice/create.ts 600
INVOICE_MAX_TTL_SECONDS number (>0) 3600 нет Верхний предел TTL инвойса (защита от «вечных» инвойсов). src/invoice/create.ts 3600
INVOICE_EXPIRY_SWEEP_INTERVAL_MS number (>0) 30000 нет Период сканирования просроченных инвойсов воркером invoice-expiry. src/invoice/expiry-worker.ts 30000
INVOICE_EXPIRY_BATCH_SIZE number (>0) 100 нет Размер пачки инвойсов, переводимых в EXPIRED за один проход sweep. src/invoice/expiry-worker.ts 100
BALANCE_TICK_MS number (>0) 60000 нет Период тика balance-monitor (сравнение TB vs IPPS). src/psp/ipps/balance-monitor.ts 60000
IPPS_DRIFT_THRESHOLD_SATANG number (≥0) 10000 (100 THB) нет Допустимое расхождение баланса TB↔IPPS в сатангах; превышение => алерт. src/psp/ipps/balance-monitor.ts 10000
IPPS_LOW_BALANCE_THRESHOLD_SATANG number (≥0) 100000 (1000 THB) нет Порог «низкого баланса» IPPS-аккаунта в сатангах; ниже => алерт. src/psp/ipps/balance-monitor.ts 100000
SERVICE_SECRETS string→object (JSON) {} нет (де-факто да) JSON-карта { serviceId: plainSecret } для верификации HMAC входящих запросов. Без записей PM отвергнет любые POST /intents. src/auth/hmac.ts, middleware verify {"auth-center":"...","nginx-gateway":"..."}

Расхождения с .env.example

Открытый вопрос: ниже перечислены env-переменные, объявленные в src/shared/config.ts, но отсутствующие в .env.example. Решение об обновлении .env.example принимается отдельно — этот документ только фиксирует факт.

Объявлены в config.ts, но не упомянуты в .env.example:

  • NOTIFICATIONS_REDIS_URL
  • TB_ADDRESSкритично: обязательная переменная без дефолта; локальный запуск без неё невозможен.
  • OUTBOX_INTERVAL_MS
  • WORKER_ROLES
  • PSP_NAMES
  • BALANCE_MONITOR_ENABLED
  • PSP_POLL_INTERVAL_MS
  • PSP_LEASE_SEC
  • PSP_RETRY_LEASE_SEC
  • PSP_MAX_RETRIES
  • BALANCE_TICK_MS
  • IPPS_DRIFT_THRESHOLD_SATANG
  • IPPS_LOW_BALANCE_THRESHOLD_SATANG

Упомянуты в .env.example, но отсутствуют в config.ts:

  • расхождений нет.

Открытый вопрос: SERVICE_SECRETS имеет дефолт '{}' в config.ts, но в .env.example приведён непустой набор dev-секретов. Без хотя бы одного валидного entry PM не сможет проверить HMAC ни одного клиента — фактически переменная обязательна для работы, хотя формально опциональна. Документировать ли это как breaking dependency — открытый вопрос.

Группы env по назначению

HMAC / Auth

  • SERVICE_SECRETS — JSON-карта серверных секретов: {"<serviceId>": "<plainSecret>"}. Используется middleware верификации HMAC при каждом входящем запросе (X-Service-Id, X-Timestamp, X-Signature). Минимум один entry должен быть задан, иначе ни один внешний сервис не сможет обратиться к PM.
  • ADMIN_SECRET — отдельный bearer-токен для admin-эндпоинтов PM (диагностика, ручные ремедиации). Не связан с HMAC; передаётся в заголовке Authorization: Bearer <secret>. Минимум 32 символа.

Database / Redis / TigerBeetle

  • DATABASE_URL — PostgreSQL через PgBouncer. PM пишет только в схему pm, читает из public (Auth Center). Миграции — drizzle-kit migrate.
  • REDIS_URL — основной Redis для publish событий intent.{id} (Auth Center подписывается через nginx) и временных координационных структур.
  • NOTIFICATIONS_REDIS_URL — опциональный отдельный Redis для очереди stream.notifications.jobs. Если не задан, PM использует основной REDIS_URL.
  • TB_ADDRESS — адрес TigerBeetle replica. PM — единственный клиент TB на write-операции (createAccounts, createTransfers, two-phase post/void). Read-only клиенты (Admin Panel) подключаются отдельно.

IPPS PSP

  • IPPS_BASE_URL — базовый URL IPPS PromptPay eXchange API (SIT для интеграции, PROD для боевого режима).
  • IPPS_API_KEY — API-ключ, выдаётся командой integration@ipps.cloud.
  • IPPS_PARTNER_ID — идентификатор партнёра в системе IPPS.
  • IPPS_HTTP_TIMEOUT_MS — таймаут HTTP-запросов; короткий таймаут защищает worker от зависших соединений (IPPS-операции не идемпотентны — таймаут != неуспех, см. NO-GO в CLAUDE.md).
  • IPPS_DRIFT_THRESHOLD_SATANG — порог расхождения баланса между TB и IPPS, при превышении которого balance-monitor генерирует алерт. По умолчанию 10 000 сатангов = 100 THB.
  • IPPS_LOW_BALANCE_THRESHOLD_SATANG — порог низкого баланса IPPS-аккаунта; ниже него — алерт оператору. По умолчанию 100 000 сатангов = 1000 THB.

Workers

  • WORKER_ROLES — CSV-список ролей, запускаемых процессом. Допустимые: api, outbox-worker, psp-worker, invoice-expiry. Один процесс может объединять несколько ролей; для масштабирования — разнести по отдельным деплоям.
  • PSP_NAMES — список имён PSP, обрабатываемых psp-worker. Сейчас единственный реальный PSP — IPPS.
  • BALANCE_MONITOR_ENABLED — флаг включения фонового monitor'а баланса IPPS (использует BALANCE_TICK_MS, IPPS_DRIFT_THRESHOLD_SATANG, IPPS_LOW_BALANCE_THRESHOLD_SATANG).
  • BALANCE_TICK_MS — частота тика balance-monitor.
  • OUTBOX_INTERVAL_MS — частота опроса pm.outbox воркером OutboxWorker. NO-GO: запускать одновременно более одного экземпляра OutboxWorker запрещено.
  • PSP_POLL_INTERVAL_MS — частота опроса очереди pm.psp_tx_map воркером PSP. Lock реализован через FOR UPDATE SKIP LOCKED (см. NO-GO: IPPS не идемпотентен, нельзя ретраить transfer — только inquiry).
  • PSP_LEASE_SEC — аренда задачи при первичной обработке. Короткая, чтобы быстро вернуть задачу в очередь при падении воркера.
  • PSP_RETRY_LEASE_SEC — аренда при ретрае. Длиннее, потому что ретрай делает inquiry, а IPPS может отвечать с задержкой.
  • PSP_MAX_RETRIES — лимит попыток PSP-операции. После исчерпания задача переводится в терминальный статус DEAD и требует ручного разбора.

Invoice

  • INVOICE_QR_SECRET — секрет HMAC-подписи QR-кодов merchant-инвойсов. Минимум 32 символа. Утечка позволяет подделывать QR — хранить наравне с приватными ключами.
  • INVOICE_DEFAULT_TTL_SECONDS — TTL по умолчанию (10 минут), применяется если merchant не указал ttlSeconds при создании.
  • INVOICE_MAX_TTL_SECONDS — верхний предел TTL (1 час), защищает от создания «вечных» инвойсов.
  • INVOICE_EXPIRY_SWEEP_INTERVAL_MS — период sweep'а воркером invoice-expiry: сканирует pm.invoice с status=PENDING AND expires_at < now() и переводит в EXPIRED.
  • INVOICE_EXPIRY_BATCH_SIZE — размер пачки за один sweep. Балансировка: маленькая пачка — меньше lock contention, большая — меньше overhead на цикл.

Связанные документы

  • docs/TECHNICAL.md — общее описание модулей.
  • docs/INTEGRATIONS.md — детали по TigerBeetle / IPPS / Redis.
  • docs/DEPLOYMENT.md — production env-конфиг и Docker.
  • CLAUDE.md (root и проектный) — NO-GO правила, использующие эти env'ы.