Skip to main content

🔍 BillingWatch — Self-Hosted Stripe Billing Anomaly Detector

Python 3.9+ FastAPI License: MIT Tests: Passing Self-Hosted Stripe Docker Deploy on Railway Deploy to Render

Catch billing bugs, dunning failures, and fraud before they hit your churn metrics — entirely on your own machine.

BillingWatch listens to your Stripe webhook stream and runs 7 real-time anomaly detectors against every event. Duplicate charges, revenue drops, fraud spikes, silent subscription lapses — detected and alerted in seconds. No cloud subscription. No SaaS fees. No data leaving your server.


🤔 Who Is This For?

  • SaaS founders who want billing QA without paying for another tool
  • Indie developers using Stripe who've been burned by silent billing failures
  • Privacy-conscious teams who don't want their revenue data on someone else's server
  • DevOps engineers who need webhook observability without a full APM stack

✨ What It Detects

Detector What It Catches Severity
charge_failure_spike Failure rate > 15% over 1 hour — gateway issue or card BIN attack 🔴 High
duplicate_charge Same customer charged twice within 5 min — idempotency bug 🚨 Critical
fraud_spike Dispute/chargeback rate exceeds threshold — active fraud campaign 🚨 Critical
negative_invoice Invoice total < 0 — broken promo stacking or discount bug 🟡 Medium
revenue_drop MRR > 15% below 7-day rolling average — silent churn or billing break 🔴 High
silent_lapse Active subscription with no successful payment in period 🟡 Medium
webhook_lag Events arriving > 10 min late — Stripe delivery degradation 🟢 Low

When a detector fires, BillingWatch sends alerts via email and/or outbound webhook.


🆚 Why Not Just Use [Datadog / Baremetrics / Stripe Radar]?

BillingWatch Datadog Baremetrics Stripe Radar
Cost Free (self-hosted) 5+/mo 29+/mo Built-in (limited)
Your data leaves your server? ❌ Never ✅ Yes ✅ Yes ✅ Yes
Custom anomaly logic ✅ Full control Partial
Stripe-specific detectors ✅ 7 built-in ❌ General ❌ Metrics only ❌ Fraud only
Self-hostable ✅ Yes
Alert destinations Email + webhook Many Email Dashboard only

BillingWatch is for makers who want billing QA (not analytics) with zero SaaS lock-in.


🚀 Quick Start

⚡ One-Click Deploy on Railway

Deploy on Railway

No local setup required. Railway will prompt for your STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET on deploy.

☁️ One-Click Deploy on Render

Deploy to Render

Free tier available. Render will read render.yaml automatically and prompt for env vars on first deploy.

Requirements

  • Python 3.9+
  • A Stripe account (test mode is fine)
  • Stripe CLI (optional — for local webhook forwarding)

Install

git clone https://github.com/rmbell09-lang/BillingWatch.git
cd BillingWatch
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Configure

cp .env.example .env

Minimum config for local dev:

STRIPE_SECRET_KEY=sk_test_PLACEHOLDER
STRIPE_WEBHOOK_SECRET=dev
APP_ENV=development
LOG_LEVEL=DEBUG
PORT=8000

Note: STRIPE_WEBHOOK_SECRET=dev bypasses signature verification. Never use in production.

Run

source .venv/bin/activate
STRIPE_WEBHOOK_SECRET=dev uvicorn src.api.main:app --reload --port 8000

Verify

curl http://localhost:8000/health
# {"status": "ok"}

curl http://localhost:8000/webhooks/detectors
# Lists all 7 registered detectors

Send a Test Event

curl -s -X POST localhost:8000/webhooks/stripe \
  -H 'Content-Type: application/json' \
  -H 'Stripe-Signature: dev' \
  -d '{
    "id": "evt_test_001",
    "type": "charge.failed",
    "created": 1709599200,
    "data": {"object": {"id": "ch_001", "customer": "cus_001", "amount": 2999}}
  }'

Or with Stripe CLI for real test events:

stripe listen --forward-to localhost:8000/webhooks/stripe
stripe trigger charge.failed

📡 API Reference

Endpoint Method Description
/health GET Health check
/docs GET Interactive Swagger UI
/webhooks/stripe POST Stripe event ingestion
/webhooks/alerts GET Recent anomaly alerts
/webhooks/detectors GET Registered detectors list
/metrics GET total_events, events_by_type, uptime_seconds, detector_count
/metrics?window_hours=N GET Rolling window metrics (0.1–168h)
/metrics/detectors GET Per-detector alert counts + severity
/metrics/recent-events GET Most recent webhook events

🏗️ Architecture

Stripe Webhooks
      │
      ▼
 FastAPI (port 8000)
      │
      ├─── Signature Validation (Stripe-Signature header)
      │
      ├─── Event Store (SQLite / PostgreSQL)
      │
      └─── Detector Pipeline (parallel evaluation)
                │
                ├─── charge_failure_spike
                ├─── duplicate_charge
                ├─── fraud_spike
                ├─── negative_invoice
                ├─── revenue_drop
                ├─── silent_lapse
                └─── webhook_lag
                          │
                          ▼
                   Alert Dispatch
                   ├─── Email (SMTP)
                   └─── Outbound Webhook

Stack: Python 3.9+ · FastAPI · SQLite (dev) / PostgreSQL (prod) · Redis · APScheduler · Stripe SDK


🧪 Running Tests

source .venv/bin/activate
pytest tests/ -v

# Detector unit tests only
pytest tests/test_detectors/ -v

# With coverage
pytest tests/ --cov=src --cov-report=term-missing

🔧 Adding a Custom Detector

Extend BaseDetector from src/detectors/base.py:

from .base import Alert, BaseDetector

class MyDetector(BaseDetector):
    name = "my_detector"

    def process_event(self, event: dict):
        if event.get("type") == "some.stripe.event":
            return [Alert(
                detector=self.name,
                severity="medium",
                title="Something happened",
                message="Details here"
            )]
        return []

Register it in src/api/main.py startup. Done.


🔒 Production Deployment

See docs/production-setup.md for:

  • Stripe live key setup via macOS Keychain
  • Cloudflare Tunnel for webhook exposure (no open ports)
  • PostgreSQL + Redis configuration
  • Pre-launch security checklist

Never put live Stripe keys in .env files. Use Keychain or a secrets manager.


📁 Project Structure

BillingWatch/
├── src/
│   ├── api/               # FastAPI app + routes
│   ├── detectors/         # 7 anomaly detectors + BaseDetector
│   ├── storage/           # SQLite/Postgres event persistence
│   ├── workers/           # Async processing + APScheduler
│   ├── alerting/          # Email + webhook alert delivery
│   ├── models/            # SQLAlchemy models + Pydantic schemas
│   └── stripe_client.py   # Stripe SDK wrapper
├── tests/                 # Unit + E2E tests
├── docs/                  # Setup guides + spec
├── Dockerfile
├── docker-compose.yml
└── README.md

🗺️ Roadmap

v1.1 (In Progress)

  • 📧 Email Digest — daily/weekly anomaly summary (endpoint live, SMTP config needed)
  • ☁️ Render.com 1-Click Deployrender.yaml + deploy button ✅
  • 🔍 Webhook Event Explorer UI — searchable, filterable event log

v1.2 (Planned)

  • 📊 Grafana Dashboard — pre-built anomaly trend dashboard
  • 🔔 Slack/Discord Alerts — native integrations
  • 🧪 Test Mode Replay — replay historical events without live webhooks


🔗 Related Projects & Alternatives

BillingWatch fills the gap between expensive SaaS platforms and doing nothing:

Tool Type Cost Why BillingWatch Instead
Datadog Full observability $5+/mo General-purpose APM, no Stripe-specific detectors
Baremetrics SaaS analytics $29+/mo Analytics dashboards, not real-time anomaly alerts
Stripe Radar Fraud detection Built-in Card fraud only — no dunning failures, duplicate charges, or webhook lag
Sentry Error monitoring $26+/mo Code errors, not billing events
ChartMogul Revenue analytics $100+/mo Historical charts, not real-time detection
Lago Open-source billing Self-hosted Full billing system — BillingWatch monitors Stripe, not replaces it

BillingWatch is free, self-hosted, and purpose-built for Stripe billing QA. One webhook endpoint. Seven detectors. Zero SaaS fees.

Also useful for: stripe monitoring · stripe webhook monitoring · billing anomaly detection · SaaS billing monitoring · self-hosted stripe monitor · payment failure alerts · subscription billing QA · chargeback detection · dunning failure detection · webhook observability · fastapi stripe webhooks


🛠️ More Dev Tools

Built by the same maker — if you're interested in algorithmic trading:

TradeSight — AI Paper Trading Strategy Lab → — Python trading bot with overnight strategy tournaments, RSI confluence, and Alpaca integration.

License

MIT — see LICENSE


Built by an indie maker who got burned by a silent dunning failure. Stripe is great — but it doesn't tell you when things go wrong until it's too late.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

billingwatch-1.0.0.tar.gz (16.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

billingwatch-1.0.0-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file billingwatch-1.0.0.tar.gz.

File metadata

  • Download URL: billingwatch-1.0.0.tar.gz
  • Upload date:
  • Size: 16.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for billingwatch-1.0.0.tar.gz
Algorithm Hash digest
SHA256 667870064a7ab3c48789af4902b580a70c30b5ccc566ef59e593d354ed71bc00
MD5 ef8caa3dd134d99e96bdf5792e5edc23
BLAKE2b-256 5c8e7075feededb9f593d59e4ca958936ce512b9dba92c17abeae0d87e6b626b

See more details on using hashes here.

File details

Details for the file billingwatch-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: billingwatch-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for billingwatch-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 43cb34575b5673d481df3e8a41c9f861fcbb26a6d7e681f21af2fa747da416cc
MD5 4f1e0aa0707189d4e3be0a23d7be18cb
BLAKE2b-256 72e1ad321662a95d44bae406f68ee607382da7a572569857af551a234303a1aa

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page