Overview
FlexPrice is a comprehensive usage-based billing and subscription management platform built in Go. The system handles the complete billing lifecycle from event ingestion through invoice generation and payment processing, designed for B2B SaaS companies requiring flexible pricing models.High-Level Architecture
FlexPrice implements a three-tier layered architecture with clear separation of concerns, bootstrapped using Uber FX dependency injection framework:Architecture Layers
Technology Stack
Core Technologies
FlexPrice uses a modern Go stack with specialized components: Key Dependencies:- Gin - HTTP routing and middleware
- Ent - Type-safe ORM for PostgreSQL
- Uber FX - Dependency injection framework
- ClickHouse - Columnar database for analytics
- Kafka (Sarama) - Event streaming platform
- Temporal - Workflow orchestration engine
- Stripe - Payment processing integration
Dual-Database Strategy
FlexPrice employs a specialized database strategy for different workloads:PostgreSQL (Transactional Data)
- Purpose: ACID transactions, relational data
- Data: Subscriptions, invoices, customers, plans, prices, wallets
- Access Pattern: Read-write, complex joins, referential integrity
- ORM: Ent for type-safe queries
ClickHouse (Analytical Data)
- Purpose: High-volume inserts, aggregation queries
- Data: Events (raw), processed_events, feature_usage
- Access Pattern: Append-only writes, time-series queries
- Tables: Optimized for usage metering and analytics
Event Processing Pipeline
The core of FlexPrice’s usage-based billing is an asynchronous event processing pipeline powered by Kafka:Pipeline Stages
1. Event Ingestion
Events are ingested via REST API and published to Kafka:2. Event Consumption & Storage
Consumers process events from Kafka and store in ClickHouse:3. Event Post-Processing
Events are enriched with subscription context and pricing data:4. Feature Usage Tracking
Usage metrics are aggregated by meter and feature for billing:Kafka Topics Configuration
Deployment Modes
FlexPrice supports multiple deployment configurations to separate concerns and scale independently:Available Modes
| Mode | Components | Purpose |
|---|---|---|
local | API + Consumer + Worker | Development environment |
api | API Server only | Handle HTTP requests |
consumer | Event processing only | Process Kafka messages |
temporal_worker | Background workers only | Execute workflows |
Service Layer Architecture
The service layer implements business logic through 30+ domain services organized by domain:Core Services
- Billing Service: Handles invoice generation, usage calculations, and billing cycles
- Event Service: Processes incoming usage events and manages event lifecycle
- Subscription Service: Manages customer subscriptions, upgrades, and downgrades
- Customer Service: Customer management and tenant operations
- Payment Service: Payment processing and gateway integrations
- Plan Service: Pricing plan management and feature configuration
- Wallet Service: Prepaid credits and wallet balance management
Service Factory Pattern
All services are instantiated through factory functions that receive a centralizedServiceParams struct containing shared dependencies:
API Layer & Routing
The API layer uses Gin framework with a comprehensive middleware stack for security, logging, and request processing:Middleware Stack
- Recovery Middleware: Panic recovery and graceful error handling
- CORS Middleware: Cross-origin resource sharing configuration
- Rate Limiting: Request throttling per API key/tenant
- Authentication: JWT and API key validation
- Tenant Isolation: Multi-tenant context enforcement
- Request Logging: Structured logging for all requests
- Metrics Collection: Prometheus metrics for observability
Authentication & Authorization
FlexPrice supports multiple authentication methods:- API Keys: Tenant-scoped keys for programmatic access
- JWT Tokens: User session tokens with role-based permissions
- Webhook Signatures: HMAC verification for incoming webhooks
API Endpoints Structure
Multi-Tenancy Architecture
FlexPrice implements row-level multi-tenancy with environment isolation enforced at multiple architectural layers:Tenant Isolation Strategy
- Database Level: All tables include
tenant_idandenvironmentcolumns - Middleware Level: Request context includes tenant/environment validation
- Service Level: All business logic operations are tenant-scoped
- Repository Level: Automatic filtering on all database queries
Middleware Enforcement
Authentication Methods
API keys are configured with tenant and user association:- Tenant API Keys: Scoped to specific tenant and environment
- User Tokens: Associated with user permissions within tenant
- System Keys: Cross-tenant access for administrative operations
Repository Layer
The repository layer provides data access abstraction with automatic tenant/environment filtering:Repository Interface
Automatic Tenant Filtering
All repositories automatically append tenant and environment filters to queries:Message Processing with PubSub Router
FlexPrice uses Watermill for message routing with built-in retry mechanisms and rate limiting:Kafka Integration
Message Processing Features
- Dead Letter Queues: Failed messages are routed to error topics
- Retry Logic: Exponential backoff for transient failures
- Rate Limiting: Configurable processing rates per topic
- Metrics: Built-in monitoring for message processing
Temporal Workflow Orchestration
Background jobs and scheduled tasks use Temporal for reliable execution and workflow management:Workflow Types
- Billing Workflows: Monthly/annual invoice generation
- Usage Aggregation: Periodic usage calculations
- Payment Processing: Async payment collection workflows
- Data Exports: Large dataset exports to S3
- Webhook Delivery: Reliable event notifications
Workflow Registration
Worker Lifecycle
Workers are deployed separately and can be scaled independently:External Integrations
Payment Gateway Abstraction
FlexPrice uses a factory pattern for payment integrations supporting multiple providers:Webhook Delivery
Webhooks are delivered through Svix for reliable event notification with automatic retries and delivery guarantees:Infrastructure Services
Monitoring & Observability
Sentry for error tracking and performance monitoring:Document Storage
Invoice PDFs are stored in S3 with presigned URL generation for secure access:Caching Layer
In-memory caching for performance optimization using Redis and local caches:Configuration Management
Configuration is loaded from YAML files with environment variable overrides for deployment flexibility:Configuration Structure
Application Lifecycle
The application lifecycle is managed by Uber FX with hooks for startup and shutdown:Notes
Key Architectural Decisions:- Dual-Database Strategy: PostgreSQL for transactional consistency, ClickHouse for high-volume analytics
- Event-Driven Architecture: Kafka enables asynchronous processing, scalability, and fault tolerance
- Microservices-Ready: Deployment modes allow splitting components into separate services
- Strong Multi-Tenancy: Enforced at middleware, service, and repository layers
- Workflow Orchestration: Temporal provides reliable background job execution
- Open Integration: Factory pattern allows multiple payment gateway implementations

