A production-ready billing proxy service that wraps any API endpoint with Stripe metered billing capabilities. Built with Rust (Axum) and Next.js.
- API Key Authentication: Secure API key validation and management
- Request Proxying: Forward authenticated requests to upstream APIs
- Usage Tracking: Real-time usage tracking with Redis
- Stripe Integration: Automatic metered billing through Stripe subscriptions
- Batch Sync: Efficient batch syncing of usage data to Stripe
- Admin Dashboard: Beautiful Next.js UI for managing API keys and viewing usage
- Prometheus Metrics: Built-in metrics for monitoring
- Rate Limiting: Configurable rate limiting per API key
- Production Ready: Error handling, logging, and Docker support
Client Request → Rust Proxy (Axum) → Upstream API
↓
Redis (Usage Tracking)
↓
Stripe (Billing)
↑
Next.js Admin UI
-
Rust Proxy Service (
rust-proxy/)- HTTP proxy server with API key validation
- Request forwarding and response streaming
- Usage tracking in Redis
- Background worker for Stripe sync
- Admin API for key management
-
Next.js Admin UI (
admin-ui/)- Dashboard with usage analytics
- API key management interface
- Usage charts and statistics
- Stripe integration links
-
Redis
- API key storage
- Usage counters
- Rate limiting
- Docker and Docker Compose
- Stripe account (test mode is fine)
- Redis (handled by Docker Compose)
-
Clone the repository
git clone <repo-url> cd stripe-billing-api-wrapper-gateway
-
Create environment file
cp env.example .env
-
Configure environment variables Edit
.envand set:UPSTREAM_BASE_URL: Your API endpoint to wrapSTRIPE_SECRET_KEY: Your Stripe secret key (sktest... or sklive...)STRIPE_PRICE_ID: Your Stripe metered price ID (price_...)
-
Start all services
make up # or: docker-compose up -d -
Access the services
- Admin UI: http://localhost:3002
- Admin API: http://localhost:3001
- Proxy: http://localhost:3000
- Go to Stripe Dashboard
- Navigate to Products → Add Product
- Create a product (e.g., "API Usage")
- Add a price:
- Pricing model: Usage-based
- Charge for metered usage: Sum of usage values
- Unit amount: Set your price per request (e.g., $0.01)
- Copy the Price ID (starts with
price_...)
- Secret Key: Dashboard → Developers → API keys
- Use test mode keys (sktest...) for development
- Open the Admin UI at http://localhost:3002
- Navigate to API Keys → Create New Key
- Fill in:
- Label: Descriptive name
- Customer Email: Email for the Stripe customer
- Save the generated API key securely
Use the API key in the X-API-Key header:
curl -H "X-API-Key: sk_xxxxx" \
http://localhost:3000/proxy/your/endpointThe proxy will:
- Validate the API key
- Forward the request to your upstream API
- Track the usage in Redis
- Sync usage to Stripe (every 10 minutes)
- Open the Admin UI at http://localhost:3002
- Navigate to Usage to see aggregate statistics
- Click on any API key to see detailed monthly usage
| Variable | Description | Default |
|---|---|---|
UPSTREAM_BASE_URL |
Your API endpoint to wrap | Required |
REDIS_URL |
Redis connection URL | redis://127.0.0.1:6379 |
STRIPE_SECRET_KEY |
Stripe secret key | Required |
STRIPE_PRICE_ID |
Stripe metered price ID | Required |
PROXY_PORT |
Port for proxy server | 3000 |
ADMIN_PORT |
Port for admin API | 3001 |
SYNC_INTERVAL_MINUTES |
Minutes between Stripe syncs | 10 |
RATE_LIMIT_PER_MINUTE |
Max requests per minute per key | 60 |
RUST_LOG |
Log level | info |
Create admin-ui/.env.local:
cd admin-ui
cp env.example .env.local
# Edit .env.local with your configurationExample configuration:
NEXT_PUBLIC_API_URL=http://localhost:3001
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...Rust Proxy:
cd rust-proxy
cp .env.example .env
# Edit .env with your configuration
cargo runAdmin UI:
cd admin-ui
npm install
cp .env.local.example .env.local
# Edit .env.local with your configuration
npm run devRedis:
docker run -d -p 6379:6379 redis:7-alpine# Rust tests
cd rust-proxy
cargo test
# UI tests
cd admin-ui
npm testGET /health
List all API keys
GET /api-keys
Create API key
POST /api-keys
Content-Type: application/json
{
"label": "Production Key",
"customer_email": "[email protected]"
}
Deactivate API key
DELETE /api-keys/:key_suffix
Get usage summary (current month)
GET /usage/summary
Get detailed usage for a key
GET /usage/:key_suffix
Prometheus metrics
GET /metrics
ANY /proxy/*
X-API-Key: your_api_key
All requests to /proxy/* are forwarded to the upstream API with the path preserved.
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose downSee k8s/ directory for Kubernetes manifests (if available).
The application is containerized and can be deployed to:
- AWS ECS/Fargate
- Google Cloud Run
- Azure Container Instances
- DigitalOcean App Platform
Available at http://localhost:3001/metrics:
http_requests_total- Total HTTP requestshttp_request_duration_seconds- Request durationproxy_requests_total- Proxy requests by statusapi_key_usage_total- Usage per API keystripe_sync_total- Stripe sync operations
Structured JSON logging to stdout:
# View all logs
docker-compose logs -f
# View proxy logs
docker-compose logs -f rust-proxy
# View UI logs
docker-compose logs -f admin-ui- Check
UPSTREAM_BASE_URLis set correctly - Verify API key is valid:
curl http://localhost:3001/api-keys - Check Redis is running:
redis-cli ping
- Verify
STRIPE_SECRET_KEYandSTRIPE_PRICE_IDare correct - Check logs:
docker-compose logs rust-proxy | grep stripe - Ensure the price is configured as metered usage
- Check
NEXT_PUBLIC_API_URLpoints to admin API - Verify admin API is running:
curl http://localhost:3001/health
- Store API keys securely (use environment variables)
- Use HTTPS in production
- Consider IP whitelisting for admin API
- Rotate API keys regularly
- Monitor usage for anomalies
- Use Stripe webhook signing for production
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License - see LICENSE file for details
For issues and questions:
- GitHub Issues: [Create an issue]
- Documentation: See
/docsfolder - Stripe Docs: https://stripe.com/docs/billing/subscriptions/usage-based
- Webhook support for Stripe events
- Multiple pricing tiers
- Usage alerts and notifications
- GraphQL admin API
- Multi-region support
- Advanced rate limiting strategies