Разработка системы биллинга Node-as-a-Service

Правильный учёт потребления ресурсов — ключ к прибыльности NaaS-платформы, но без точного биллинга легко потерять доход и доверие клиентов. Мы разрабатываем системы биллинга Node-as-a-Service, которые учитывают Compute Units, тарифы и crypto-платежи, автоматизируя весь цикл — от сбора метрик до выставления счетов. Наша команда реализует проект под ключ с многолетним опытом и последующей поддержкой, обеспечивая прозрачность и надёжность расчётов.
Часто задаваемые вопросы

Запустить ноду несложно. Сложно правильно считать деньги — особенно когда unit of consumption это не запрос, а время работы ноды, тип сети, версия клиента и тариф, который выбрал пользователь три недели назад. NaaS биллинг провален в большинстве молодых провайдеров не потому что задача технически трудная, а потому что между "считать деньги примерно верно" и "считать деньги точно и прозрачно" — пропасть в несколько месяцев инженерной работы. Мы разрабатываем системы биллинга для NaaS уже много лет и знаем, как избежать типовых ошибок. За это время реализовали более 20 проектов, от простых MVP до полноценных crypto-native платформ. В этой статье разберем архитектуру, с которой не стыдно выходить в production, модели тарификации, которые выбирают зрелые провайдеры, и подводные камни, которые ломают биллинг в продакшене. Вы узнаете, как построить слой сбора метрик без потери данных, настроить rating engine на PostgreSQL и интегрировать crypto-платежи в USDC. Также расскажем, какие проблемы возникают с clock skew и duplicate events, и как их решить.

Какие модели тарификации используются в NaaS?

Pay-per-request — классика для RPC провайдеров (Alchemy, Infura, QuickNode). Считаем количество JSON-RPC вызовов, с весовыми коэффициентами по методам:

Метод Compute Units
eth_blockNumber 10
eth_getBalance 19
eth_call 26
eth_getLogs 75
trace_transaction 150
debug_traceTransaction 500

eth_getLogs с широким диапазоном блоков — это атака на ноду. Без весовых коэффициентов пользователь может сделать один запрос стоимостью тысячи "обычных". Alchemy называет это Compute Units, QuickNode — Credits. Названия разные, смысл один.

Time-based (subscription) — выделенная нода фиксированной мощности оплачивается помесячно. Понятнее для пользователя, предсказуемый revenue для провайдера. Минус: пользователь переплачивает при низкой нагрузке.

Hybrid — базовый план с месячным включённым объёмом, overage billing сверху. Используют большинство зрелых провайдеров.

Модель Преимущества Недостатки
Pay-per-request Точно платишь за использование, легко масштабируется Непредсказуемый счёт, сложность rate limiting
Time-based (subscription) Предсказуемый доход, простота для пользователя Переплата при низкой нагрузке
Hybrid Баланс гибкости и предсказуемости Сложность реализации overage billing

Как устроена архитектура биллинговой системы?

Как организовать слой сбора метрик? — разработка системы биллинга

Критический путь: каждый RPC запрос должен быть залогирован до ответа пользователю — иначе при краше теряем данные об использовании. Допустимый процент потерь (sampling loss) — менее 0.01%. Если теряем больше — backpressure или нода умирает под нагрузкой.

Архитектура:

Client Request ↓
API Gateway (Nginx / Envoy / Kong) ↓
[access log + request metadata]
Billing Proxy (sidecar) — async write to queue ↓
RPC Node Cluster ↓
Response → Client

Billing proxy пишет в Apache Kafka или NATS JetStream — оба дают at-least-once delivery. Синхронная запись в базу на каждый запрос убивает latency (мы добавляем 100–500мс к каждому RPC вызову, что недопустимо). Использование очереди позволяет обрабатывать события в 10 раз быстрее по сравнению с прямой записью в БД.

// Async metric emission — не блокирует запрос
func (b *BillingMiddleware) RecordUsage(ctx context.Context, event UsageEvent) {
    select {
    case b.eventChan <- event:
        // успешно поставлено в буфер
    default:
        // буфер полон — метрика потеряна, логируем как sampling loss
        b.metrics.IncSamplingLoss()
    }
}

Агрегация и rating engine

Raw события из Kafka → rating pipeline → billable records в PostgreSQL. Rating — это применение тарифных правил к raw usage. Для NaaS:

class RatingEngine:
    def rate_event(self, event: UsageEvent, plan: Plan) -> Decimal:
        method_weight = self.compute_unit_table.get(
            event.method, DEFAULT_WEIGHT
        )
        # Применяем тарифный план
        if plan.type == "included_pool":
            remaining = plan.included_units - plan.used_units
            if remaining > 0:
                billable = max(0, method_weight - remaining)
                plan.used_units += method_weight
            else:
                billable = method_weight
        elif plan.type == "pay_per_use":
            billable = method_weight
        return Decimal(billable) * plan.unit_price

Агрегация происходит по временным окнам (5-минутные buckets), финальная запись — в конце расчётного периода. Это создаёт billing lag — пользователь потратил деньги, но видит обновление баланса через 5 минут. Это норма для NaaS.

Хранение данных

Для биллинга PostgreSQL — правильный выбор. Не ClickHouse, не MongoDB. Биллинг требует ACID при списании средств. Схема:

-- Immutable usage log
CREATE TABLE usage_events (
    id BIGSERIAL PRIMARY KEY,
    account_id UUID NOT NULL,
    node_id UUID NOT NULL,
    method VARCHAR(64),
    chain_id INTEGER,
    weight INTEGER,
    occurred_at TIMESTAMPTZ NOT NULL,
    billed_at TIMESTAMPTZ
) PARTITION BY RANGE (occurred_at);

-- Billing periods
CREATE TABLE billing_records (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID NOT NULL,
    period_start TIMESTAMPTZ NOT NULL,
    period_end TIMESTAMPTZ NOT NULL,
    total_units BIGINT,
    total_amount NUMERIC(20, 8),
    currency VARCHAR(10), -- 'USD', 'USDC', 'ETH'
    status VARCHAR(20), -- 'pending', 'invoiced', 'paid', 'overdue'
    created_at TIMESTAMPTZ DEFAULT NOW()
);

usage_events партиционируется по дате — иначе через год таблица перестанет вмещаться в индексы оперативной памяти. Retention policy: raw events хранятся 90 дней, агрегаты — бессрочно.

Как реализовать crypto-native биллинг?

Prepaid баланс в стейблкоинах

Большинство NaaS для Web3 работают в prepaid модели: пользователь пополняет баланс в USDC/USDT, списание происходит с него. Это проще чем подписка через кредитную карту и нет chargeback рисков.

contract NaaSBilling {
    IERC20 public immutable usdc;
    mapping(address => uint256) public balances;
    address public billingOracle; // multisig or oracle service

    event Deposit(address indexed account, uint256 amount);
    event Deduction(address indexed account, uint256 amount, string invoiceId);

    function deposit(uint256 amount) external {
        usdc.transferFrom(msg.sender, address(this), amount);
        balances[msg.sender] += amount;
        emit Deposit(msg.sender, amount);
    }

    // Только billingOracle может списывать
    function deductBalance(
        address account,
        uint256 amount,
        string calldata invoiceId
    ) external onlyBillingOracle {
        require(balances[account] >= amount, "Insufficient balance");
        balances[account] -= amount;
        emit Deduction(account, amount, invoiceId);
    }
}

Важный паттерн: billingOracle — не EOA, а multisig или сервис с HSM. Ключ от оракула компрометируется → все балансы под угрозой.

Автоматическое пополнение

Low balance triggers — пользователь настраивает автопополнение при достижении порога: threshold, refillAmount, sourceWallet, maxMonthlySpend. maxMonthlySpend — обязательная защита от billing runaway. Без неё баглый клиент делает миллион запросов и съедает весь баланс пользователя за час.

Какие алерты и rate limiting нужны?

Rate limiting на уровне API Gateway (не биллинга): 1000 req/sec per API key — стандартный дефолт. Без rate limiting один пользователь с багом может положить ноду для всех.

Billing alerts — нотификации при:

  • Баланс упал ниже X% от обычного месячного расхода (например, 80%)
  • Резкий spike usage (>3x среднего за последний час)
  • Нода недоступна (клиент платит за downtime — это должно компенсироваться SLA кредитами)

SLA credits — автоматическое начисление кредитов при downtime. Считается через uptime probe (внешний сервис мониторинга, не ваш собственный). Self-reported uptime 99.99% не вызывает доверия у корпоративных клиентов.

Какие проблемы биллинга встречаются в production?

За время работы с NaaS биллингом встречали несколько нетривиальных проблем. Рассмотрим три наиболее критичных.

Clock skew между нодами — если billing proxy и нода имеют расхождение часов >1 сек, timestamps в usage events некорректны. NTP обязателен, предпочтительно chrony с Google NTP серверами.

Duplicate events при retry — Kafka at-least-once delivery означает дубликаты при retry. Каждое событие должно иметь idempotency key (request_id + node_id), rating engine де-дуплицирует перед записью.

Timezone bugs в billing cycles — расчётный период "1-е число месяца" в UTC. Пользователь из UTC-8 видит что цикл закрывается в 16:00 его времени. Нужна явная документация и по желанию — кастомные billing cycles.

Сроки разработки полноценной NaaS billing системы: 3–5 месяцев для команды из 2–3 backend инженеров. MVP с prepaid балансом и базовым rate limiting — 6–8 недель.

Что входит в разработку системы биллинга?

  • Документация архитектуры и API
  • Исходный код с комментариями
  • Инструкция по развертыванию (Docker, Kubernetes)
  • Обучение команды заказчика
  • Техническая поддержка 3 месяца
  • Гарантия устранения ошибок

Гарантия точности биллинга: мы гарантируем, что система проходит аудит на предмет утечки средств и корректности расчетов. В течение 3 месяцев после сдачи исправляем любые ошибки бесплатно. Ошибки биллинга могут стоить до 10% выручки провайдера — наша задача свести этот риск к нулю.

Свяжитесь с нами для консультации по архитектуре вашего NaaS биллинга. Закажите разработку системы под ключ и получите оценку проекта.

Направления блокчейн-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142