G-SERVICE Docs
Архитектура ISP (OSS/BSS)

Billing & Finance Service

Баланс, платежи, двойная запись (ledger), dunning, счета, интеграция с банками.

Billing & Finance Service

Bounded Context: Billing & Finance
Владелец данных: Account, Transaction, Invoice, DunningState
Технологии: NestJS (Bun 1.3+), Drizzle ORM, PostgreSQL, ConnectRPC, RabbitMQ, BullMQ, Redis

Ответственность

Billing & Finance — финансовое ядро платформы. Реализует полный цикл Revenue Management — от тарификации до сверки с банками. Аналог модулей Finance в Hydra Billing и Billing в Splynx.

  • Accounts: Лицевые счета клиентов (balance, status, credit limit).
  • Ledger: Двойная запись (double-entry) — каждая операция = проводка (debit/credit). Баланс — это производная от журнала транзакций, а не отдельное поле.
  • Rating Engine: Расчёт стоимости с учётом тарифа, скидок, proration (пропорциональный перерасчёт при смене тарифа в середине периода).
  • Payments: Приём платежей от банков (Сбербанк, Тинькофф, ЮKassa, касса, терминалы), autopay (рекуррентные списания с привязанной карты через токенизацию).
  • Invoicing: Генерация счетов (PDF), актов сверки, УПД для юрлиц. Интеграция с 1С.
  • Dunning: Многоступенчатая автоматическая работа с задолженностью (напоминание → captive portal → ограничение скорости → отключение → списание безнадёжного долга).
  • Reconciliation: Ежедневная сверка баланса платформы с банковскими выписками. Автоматическое обнаружение расхождений.

Ключевые бизнес-инварианты

ИнвариантОписаниеНарушение =
Append-only ledgerБаланс никогда не обновляется напрямую — только через создание TransactionФинансовая несогласованность
Double-entryКаждая операция = debit одного счёта + credit другого (или системного)Невозможность reconciliation
Idempotent paymentsexternal_id уникален для каждого источника — повторный webhook не создаёт дубльДвойное зачисление
Balance consistencybalance_after в каждой Transaction = предыдущий balance_after ± amountПотеря денег
Audit trailВсе ручные корректировки (ManualAdjust) требуют reason и логируются в audit logНарушение комплаенса

Агрегат: Account

Loading diagram...

Правила агрегата:

  • Balance изменяется ТОЛЬКО через создание Transaction (append-only ledger).
  • Каждая Transaction фиксирует balance_after для аудита.
  • external_id уникален для каждого источника (дедупликация платежей от банков).

Dunning State Machine

Loading diagram...
СтадияДействияСрок
NoneНормальная работа
SoftSMS "Пополните баланс" + Captive PortalD+0 (сразу при < 0)
HardОграничение скорости (64kbps) + повторное SMSD+3
TerminateПолная блокировка → автоматическое расторжениеD+N (настраивается)

При каждом переходе публикуется DunningStageChangedEvent → Provisioning (suspend/resume) + Notification (SMS).

ConnectRPC API

service BillingService {
  rpc GetAccount(GetAccountRequest) returns (GetAccountResponse);
  rpc GetBalance(GetBalanceRequest) returns (GetBalanceResponse);
  rpc ListTransactions(ListTransactionsRequest) returns (ListTransactionsResponse);
  rpc RegisterPayment(RegisterPaymentRequest) returns (RegisterPaymentResponse);
  rpc ManualAdjust(ManualAdjustRequest) returns (ManualAdjustResponse);
  rpc GenerateInvoice(GenerateInvoiceRequest) returns (GenerateInvoiceResponse);
  rpc GetInvoice(GetInvoiceRequest) returns (GetInvoiceResponse);
}
МетодRBACIdempotentОписание
GetBalanceisp-viewer+Текущий баланс + dunning stage
ListTransactionsisp-viewer+История операций (курсорная пагинация)
RegisterPaymentisp-operator+✅ (external_id)Зачисление от банка/кассы
ManualAdjustisp-admin+Ручная корректировка (audit log!)
GenerateInvoiceisp-operator+Сформировать счёт за период

Доменные события

Exchange: billing.events (Topic)

Routing KeyСобытиеПотребители
payment.receivedPaymentReceivedEventOMS, Notification
balance.negativeBalanceNegativeEventNotification
dunning.stage_changedDunningStageChangedEventProvisioning, Notification
invoice.issuedInvoiceIssuedEventNotification
charge.completedChargeCompletedEvent— (audit)

Входящие команды

Exchange: billing.commands (Direct)

Routing KeyКомандаИсточникОписание
charge.accountChargeAccountCommandOMSСписание (Saga-шаг)
refundRefundCommandOMSВозврат (Saga-компенсация)

Зависимости

Loading diagram...

Background Jobs (BullMQ)

JobРасписаниеQueueОписание
billing.recurring_chargeЕжедневно, 03:00billing_criticalМассовое рекуррентное списание
billing.dunning_checkКаждые 4 часаbilling_backgroundПроверка и переходы dunning
billing.generate_invoice1-е число месяцаbilling_criticalМассовая генерация счетов
billing.generate_receiptПо событиюdefaultPDF-квитанция после оплаты
billing.reconciliationЕжедневно, 06:00billing_backgroundСверка с банковскими выписками

Интеграция с банками

Loading diagram...

Ссылки:

On this page