Skip to content

Stripe-native usage metering with real-time cost projections, exactly-once processing, and invoice parity guarantees. Open-source billing transparency for SaaS.

License

Notifications You must be signed in to change notification settings

nellcorp/stripemeter

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

49 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

StripeMeter

The open-source usage metering platform that eliminates billing surprises

CI GitHub release License: MIT PRs Welcome Community Contributors

Stability: Alpha (v0.1.0) β€” See Release Notes and Operator Playbook.

Try in 5 minutes

pnpm i -w
docker compose up -d
pnpm -r build
pnpm dev

StripeMeter is an alpha-stage, Stripe-native usage metering system that brings transparency and trust to SaaS billing. Built by developers, for developers who believe customers deserve to see exactly what they're paying for.

Why StripeMeter?

  • Eliminate Bill Shock: Real-time usage tracking with live cost projections
  • Exactly-Once Guarantee: Never double-bill customers with idempotent processing
  • Invoice Parity: What customers see = what Stripe bills (guaranteed within 0.5%)
  • Lightning Fast: Sub-minute freshness with horizontal scaling
  • Battle-Tested: Built for production with comprehensive error handling
  • Beautiful UIs: Admin dashboard + embeddable customer widgets
  • Developer First: Full-featured SDKs for Node.js and Python

What Makes StripeMeter Special

Unlike other billing solutions, StripeMeter is designed around three core principles:

  1. Transparency First: Customers should never be surprised by their bill
  2. Developer Experience: Building usage-based pricing should be delightful
  3. Community Driven: Built by the community, for the community

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Clients   │────▢│ Ingest   │────▢│   Events     β”‚
β”‚  (SDK/HTTP) β”‚     β”‚   API    β”‚     β”‚  (Postgres)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚                 β”‚
                           β–Ό                 β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  Queue   │────▢│ Aggregator   β”‚
                    β”‚ (Redis)  β”‚     β”‚   Worker     β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                            β”‚
                                            β–Ό
                                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                     β”‚   Counters   β”‚
                                     β”‚(Redis + PG)  β”‚
                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                            β”‚
                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                           β–Ό                β–Ό                β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  Stripe  β”‚     β”‚  Alerts  β”‚    β”‚ Customer β”‚
                    β”‚  Writer  β”‚     β”‚  & Caps  β”‚    β”‚  Widget  β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

stripemeter/
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ core/           # Shared types, schemas, utilities
β”‚   β”œβ”€β”€ database/       # Database layer (Drizzle ORM + Redis)
β”‚   β”œβ”€β”€ pricing-lib/    # Pricing calculation engine
β”‚   β”œβ”€β”€ sdk-node/       # Node.js SDK
β”‚   └── sdk-python/     # Python SDK
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/           # REST API (Fastify)
β”‚   β”œβ”€β”€ workers/       # Background workers (BullMQ)
β”‚   β”œβ”€β”€ admin-ui/      # Admin dashboard (React)
β”‚   └── customer-widget/ # Embeddable widget (React)
└── infra/             # Infrastructure configs

Quick Start

Get StripeMeter running in under 5 minutes

One-Command Setup

# Clone and setup everything automatically
git clone https://github.com/geminimir/stripemeter.git
cd stripemeter && ./scripts/setup.sh

That's it! The setup script will:

  • Check prerequisites (Node.js 20+, pnpm, Docker)
  • Install dependencies
  • Start infrastructure services
  • Run database migrations
  • Create example configuration

Manual Setup (if you prefer)

Click to expand manual installation steps
  1. Prerequisites: Node.js 20+, pnpm 8+, Docker
  2. Install: pnpm install
  3. Configure: Copy .env.example to .env and add your Stripe keys
  4. Infrastructure: docker compose up -d
  5. Database: pnpm db:migrate
  6. Start: pnpm dev

You're Ready!

  • API: http://localhost:3000 (with Swagger docs at /docs)
  • Admin Dashboard: http://localhost:3001
  • Customer Widget Demo: http://localhost:3002

Try the Interactive Demo

Experience StripeMeter in action with our realistic SaaS demo:

cd demo/cloudapi-saas
./demo-start.sh

The demo showcases:

  • Real-time usage tracking with live cost updates
  • Multiple pricing tiers (Free, Pro, Enterprise)
  • Interactive API testing with immediate billing feedback
  • Usage simulation tools for different traffic patterns
  • Complete billing transparency that customers love

Perfect for understanding how StripeMeter integrates with your SaaS application!

Core Concepts

Events (Immutable Ledger)

Every usage event is stored with a deterministic idempotency key. Events are never deleted or modified - corrections are made through adjustments.

Counters (Materialized Aggregations)

Pre-computed aggregations (sum/max/last) by tenant, metric, customer, and period. Updated in near-real-time by the aggregator worker.

Watermarks (Late Event Handling)

Each counter maintains a watermark timestamp. Events arriving within the lateness window (default 48h) trigger re-aggregation. Later events become adjustments.

Delta Push (Stripe Synchronization)

The writer tracks pushed_total per subscription item and only sends the delta to Stripe, ensuring idempotent updates even after retries.

Reconciliation (Trust but Verify)

Hourly comparison of local totals vs Stripe reported usage. Differences beyond epsilon (0.5%) trigger investigation and suggested adjustments.

Pricing Simulator

Test and optimize your pricing strategy before going live

The StripeMeter pricing simulator helps you validate billing logic, compare pricing models, and ensure customers are never surprised by their bills.

Quick Example

import { InvoiceSimulator } from '@stripemeter/pricing-lib';

const simulator = new InvoiceSimulator();

// Compare tiered vs volume pricing for 25,000 API calls
const tieredPrice = simulator.simulate({
  customerId: 'test',
  periodStart: '2024-01-01',
  periodEnd: '2024-02-01',
  usageItems: [{
    metric: 'api_calls',
    quantity: 25000,
    priceConfig: {
      model: 'tiered',
      currency: 'USD',
      tiers: [
        { upTo: 10000, unitPrice: 0.01 },
        { upTo: 50000, unitPrice: 0.008 },
        { upTo: null, unitPrice: 0.005 }
      ]
    }
  }]
});

console.log(`Tiered pricing: $${tieredPrice.total}`); // $220

πŸ“– Complete Documentation

Why Use the Simulator?

βœ… Validate pricing accuracy - Test before customers see bills
βœ… Compare pricing models - Tiered vs Volume vs Graduated
βœ… Optimize revenue - Find the best pricing for your segments
βœ… Handle edge cases - Test zero usage, tier boundaries, credits
βœ… Enterprise scenarios - Multi-metric billing with commitments

Usage Examples

Track Usage with SDKs

Node.js SDK
import { createClient } from '@stripemeter/sdk-node';

const client = createClient({
  apiUrl: 'http://localhost:3000',
  tenantId: 'your-tenant-id',
  customerId: 'cus_ABC123'
});

// Track a single event
await client.track({
  metric: 'api_calls',
  customerRef: 'cus_ABC123',
  quantity: 100,
  meta: { endpoint: '/v1/search', region: 'us-east-1' }
});

// Get live usage and cost projection
const usage = await client.getUsage('cus_ABC123');
const projection = await client.getProjection('cus_ABC123');

console.log(`Current usage: ${usage.metrics[0].current}`);
console.log(`Projected cost: $${projection.total}`);
Python SDK
from stripemeter import StripeMeterClient

client = StripeMeterClient(
    api_url="http://localhost:3000",
    tenant_id="your-tenant-id",
    customer_id="cus_ABC123"
)

# Track usage
client.track(
    metric="api_calls",
    customer_ref="cus_ABC123",
    quantity=100,
    meta={"endpoint": "/v1/search", "region": "us-east-1"}
)

# Get projections
projection = client.get_projection("cus_ABC123")
print(f"Projected cost: ${projection.total}")
REST API
# Ingest usage events
curl -X POST http://localhost:3000/v1/events/ingest \
  -H "Content-Type: application/json" \
  -d '{
    "events": [{
      "tenantId": "your-tenant-id",
      "metric": "api_calls",
      "customerRef": "cus_ABC123",
      "quantity": 100,
      "ts": "2025-01-16T14:30:00Z"
    }]
  }'

# Get cost projection
curl -X POST http://localhost:3000/v1/usage/projection \
  -H "Content-Type: application/json" \
  -d '{"tenantId": "your-tenant-id", "customerRef": "cus_ABC123"}'

Embed the Customer Widget

<!-- Add to your customer dashboard -->
<div id="usage-widget"></div>
<script src="https://cdn.stripemeter.io/widget/v1/stripemeter-widget.umd.js"></script>
<script>
  StripeMeterWidget.initStripeMeterWidget('usage-widget', {
    apiUrl: 'https://api.stripemeter.io',
    tenantId: 'your-tenant-id',
    customerId: 'cus_ABC123',
    theme: 'light' // or 'dark'
  });
</script>

Contributing

StripeMeter is built by the community, for the community.

Ways to Contribute

  • Found a bug? Open an issue
  • Have an idea? Start a discussion
  • Improve docs - Even fixing typos helps!
  • Add tests - Help us improve reliability
  • Design improvements - Make StripeMeter more beautiful
  • New features - Check our roadmap

Quick Contribution Guide

  1. Fork the repo and create your branch: git checkout -b my-amazing-feature
  2. Make your changes and add tests if needed
  3. Run the tests: pnpm test
  4. Commit with a clear message: git commit -m "Add amazing feature"
  5. Push and create a PR - we'll review it quickly!

Testing & Quality

We maintain high code quality standards:

# Run all tests
pnpm test

# Type checking
pnpm typecheck

# Linting
pnpm lint

# End-to-end tests
pnpm test:e2e

Deployment

One-Click Deploy

Deploy to Railway Deploy with Vercel

Docker Production

# Production deployment
docker compose -f docker-compose.prod.yml up -d

# With monitoring stack
docker compose -f docker-compose.prod.yml --profile monitoring up -d

Kubernetes

# Apply all manifests
kubectl apply -k infra/k8s/

# Or use Helm
helm install stripemeter ./charts/stripemeter

Performance & Monitoring

Production SLOs:

  • Ingest latency p99 ≀ 200ms
  • Projection staleness ≀ 60s
  • Reconciliation accuracy β‰₯ 99.5%
  • Uptime β‰₯ 99.9%

Built-in Observability:

  • Prometheus metrics
  • Structured logging
  • Distributed tracing
  • Health check endpoints

Security & Compliance

  • Zero PCI scope - No card data stored
  • Multi-tenant isolation - Complete data separation
  • SOC 2 ready - Comprehensive audit trails
  • RBAC support - Role-based access control
  • Security scanning - Automated vulnerability detection

Roadmap

Foundations (in progress)

  • Deterministic idempotency across core/SDKs/writer
  • BullMQ dedup via jobId for aggregation
  • Fix watermark logic for late events β†’ adjustments
  • Implement usage endpoints (current + projection)
  • API authentication + tenant scoping
  • Price mappings CRUD (DB-backed)
  • Alerts CRUD + history endpoints
  • Health checks + Prometheus metrics
  • Drizzle migrations and bootstrap
  • Security and resilience hardening

Next: Billing Simulator

  • Simulator core: Scenario DSL + runner
  • Stripe billing driver (test clocks, meters v2, credits)
  • Simulator DB schema & migrations
  • CSV/S3 parity adapter + MinIO
  • Assertions library for simulator
  • sim-api: CRUD scenarios, run orchestration
  • sim-reporter: HTML/JSON reports
  • MinIO infra profile for CSV parity tests
  • Simulator CLI (run/validate/report)
  • Simulator Prometheus metrics
  • Credit Grants lifecycle
  • Mixed cadence invoice scenario
  • Dunning lab
  • CI for simulator (fast PR + nightly full)
  • Docs: Simulator getting started + scenarios

View full roadmap β†’

License

StripeMeter is MIT licensed. Use it, modify it, distribute it - we believe in open source!

Acknowledgments

Built with ❀️ by the open-source community. Special thanks to:


If StripeMeter helps your business, please give us a star!

Star on GitHub β€’ Documentation β€’ Community

Made with ❀️ by developers who believe in billing transparency

About

Stripe-native usage metering with real-time cost projections, exactly-once processing, and invoice parity guarantees. Open-source billing transparency for SaaS.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 85.7%
  • Python 6.6%
  • Shell 1.8%
  • JavaScript 1.7%
  • HTML 1.5%
  • PLpgSQL 1.5%
  • Other 1.2%