Skip to main content

Open Source Credit Management

PyPI version Python License: MIT Downloads FastAPI FastAPI

Production-ready credit management system for AI/LLM applications. Automatic credit deduction, Razorpay payment integration, subscription plans, promo codes, and multi-provider webhooks.

✨ Why Credit Management?

Building a credit system for your AI application shouldn't mean reinventing billing, payments, and usage tracking. This library gives you:

  • 🪙 Credit Reservations & Deductions — Reserve credits before API calls, deduct actual usage after. Prevents overcharging on failures.
  • 💳 Payment Integration — Razorpay payment links with atomic credit updates.
  • 📊 Subscription Plans — Daily, monthly, yearly plans with auto-renew and credit allocation.
  • 🎫 Promo Codes — Targeted promos with usage limits, expiry dates, and claim tracking.
  • 🔒 Request-Scoped Context — Automatic credit tracking via Python contextvars. Add LLM usage in your handlers, middleware handles the rest.
  • 🗄️ Database Agnostic — MongoDB or in-memory backend. Extensible to any database via BaseDBManager interface.
  • 📋 Dual-Write Ledger — Database + append-only file for audit trails and debugging.
  • 🔔 Notifications — Low credits, expiring credits, transaction errors — pluggable notification queue.

💡 Framework-agnostic, database-agnostic. Works with FastAPI, Flask, Django, or any async framework. Swap MongoDB for PostgreSQL, SQLite, or implement BaseDBManager for your database.

🚀 Quick Start

Installation

pip install credit-management

Basic Setup (3 Lines)

from fastapi import FastAPI
from credit_management.api.frontend_router import router as frontend_router
from credit_management.api.middleware import CreditDeductionMiddleware, _credit_service

app = FastAPI()
app.include_router(frontend_router)

# Automatic credit reservation → deduction on every request
app.add_middleware(
    CreditDeductionMiddleware,
    credit_service=_credit_service,
    path_prefix="/api",
    user_id_header="X-User-Id",
    default_estimated_tokens=100,
    skip_paths=("/api/health",),
)

Track LLM Usage in Your Handlers

from credit_management.context.creditContext import addLlmUsage

# After your LLM call
addLlmUsage(
    model="gpt-4o",
    provider="openai",
    cost=0.05,
    metadata={"prompt_tokens": 100, "completion_tokens": 50},
)
from credit_management.context.creditContext import addLlmUsage

# After your LLM call
addLlmUsage(
    model="gpt-4o",
    provider="openai",
    cost=0.05,
    metadata={"prompt_tokens": 100, "completion_tokens": 50},
)

The middleware automatically reserves credits before the request and deducts actual usage after. If the request fails, credits are unreserved — no overcharging.

Accept Payments via Razorpay

from credit_management.api.router import _payment_service, setup_razorpay_provider

# Initialize (auto-loaded from env vars)
setup_razorpay_provider(
    key_id="rzp_live_xxx",
    key_secret="xxx",
    webhook_secret="whsec_xxx",
    app_base_url="https://yourapp.com",
)

# Create payment link
response = await _payment_service.create_payment_link(
    user_id="user-123",
    amount_inr=500.0,
    provider_name="razorpay",
)

🏗️ Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Your FastAPI App                         │
│  ┌──────────────────┐     ┌──────────────────────────────┐ │
│  │ CreditDeduction  │────▶│  ContextVar (LLM Usage)      │ │
│  │ Middleware       │     │  addLlmUsage(model, cost)    │ │
│  └────────┬─────────┘     └──────────────┬───────────────┘ │
│           │                              │                  │
│           ▼                              ▼                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              CreditService (Core)                   │   │
│  │  reserve → execute → deduct / unreserve             │   │
│  └─────────────────────────┬───────────────────────────┘   │
└────────────────────────────┼───────────────────────────────┘
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
        ┌──────────┐  ┌──────────┐  ┌──────────────┐
        │ MongoDB  │  │ Ledger   │  │ Payment      │
        │ (or Mem) │  │ (DB+File)│  │ Providers    │
        └──────────┘  └──────────┘  └──────────────┘
                                    │ Razorpay │ Stripe │
                                    └──────────┴────────┘

Core Components

Component Purpose Key Feature
CreditService Core credit operations Cache-first reads, delta-based cache updates, transaction logging
PaymentService Payment processing Atomic updates, reference_id tracking, idempotent webhooks
SubscriptionService Plan management Daily/monthly/yearly plans, auto-renew, credit allocation
PromoService Promo code system Eligibility checks, usage limits, expiry tracking
CreditDeductionMiddleware Automatic credit deduction Reserve → execute → deduct/unreserve flow
LedgerLogger Audit logging Dual-write: database + append-only JSONL file
NotificationService User notifications Low credits, expiry warnings, transaction errors

📖 API Endpoints

User Endpoints (/credits/*)

Endpoint Method Description
/credits/balance/{user_id} GET Get available credit balance
/credits/payments/create POST Create Razorpay payment link
/credits/payments/history GET Payment history with pagination
/credits/payments/{payment_id} GET Get specific payment record
/credits/promo/eligibility?promo_code=X GET Check promo eligibility
/credits/promo/claim POST Claim promo code

Admin Endpoints (/admin/credits/*)

Endpoint Method Description
/admin/credits/add POST Add credits to a user
/admin/credits/deduct POST Deduct credits from a user
/admin/credits/plans POST Create subscription plan
/admin/credits/promos POST/GET Manage promo codes

Webhook Endpoint

Endpoint Method Description
/webhooks/{provider_name} POST Unified webhook handler (Razorpay, Stripe, etc.)

🔐 Security Features

  • Atomic Credit Updates — MongoDB conditional updates prevent double-crediting on concurrent webhooks
  • HMAC-SHA256 Webhook Verification — Timing-safe signature verification for all payment webhooks
  • State Machine Enforcement — Payment status only moves forward (prevents status rollback attacks)
  • Immutable Field Validation — Validates user_id, amount consistency across webhook events
  • Request-Scoped Isolation — Python contextvars ensure credit tracking is per-request, thread-safe

🗄️ Database Backends

MongoDB (Production)

export CREDIT_MONGO_URI="mongodb://localhost:27017"
export CREDIT_MONGO_DB="credit_management"

In-Memory (Testing)

from credit_management.db.memory import InMemoryDBManager
db = InMemoryDBManager()

Custom Backend

Implement BaseDBManager interface for any database (SQL, NoSQL, in-memory). Use schema_generator.py for automatic SQL DDL or MongoDB validators.

python -m schema_generator --backend sql --dialect postgres
python -m schema_generator --backend nosql

⚙️ Configuration

Environment Variable Default Description
CREDIT_MONGO_URI — MongoDB connection string
CREDIT_MONGO_DB credit_management Database name
RAZORPAY_KEY_ID — Razorpay API key ID
RAZORPAY_KEY_SECRET — Razorpay API key secret
RAZORPAY_WEBHOOK_SECRET — Webhook signing secret
APP_BASE_URL http://localhost:8000 Your application base URL

🔧 Manual HTTP API Usage

Prefer curl or HTTP clients? The library exposes REST endpoints you can call directly:

Credits

# Add credits (admin)
curl -X POST http://localhost:8000/admin/credits/add \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user-1", "amount": 100, "description": "Welcome bonus"}'

# Get balance
curl http://localhost:8000/credits/balance/user-1

# Check promo eligibility
curl "http://localhost:8000/credits/promo/eligibility?promo_code=LAUNCH100"

# Claim promo
curl -X POST http://localhost:8000/credits/promo/claim \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user-1", "promo_code": "LAUNCH100"}'

# Manual credit deduction (e.g., for non-API costs)
curl -X POST http://localhost:8000/admin/credits/deduct \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user-1", "amount": 10, "description": "Storage overage"}'

# Create subscription plan (admin)
curl -X POST http://localhost:8000/admin/credits/plans \
  -H "Content-Type: application/json" \
  -d '{"name": "Pro", "credit_limit": 10000, "price": 29.99, "billing_period": "MONTHLY"}'

Payments

# Create payment link
curl -X POST http://localhost:8000/credits/payments/create \
  -H "Content-Type: application/json" \
  -H "X-User-Id: user-1" \
  -d '{"amount_inr": 500, "provider": "razorpay"}'

# Payment history
curl "http://localhost:9000/credits/payments/history?limit=10" \
  -H "X-User-Id: user-1"

# Handle Razorpay webhook
curl -X POST http://localhost:8000/webhooks/razorpay \
  -H "Content-Type: application/json" \
  -H "X-Razorpay-Signature: <signature>" \
  -d '{"event": "payment_link.paid", "payload": {...}}'

🔄 Manual Credit Deduction Use Cases

The middleware handles automatic credit deduction for API calls, but you may need manual deduction for:

Non-API Costs

from credit_management.api.router import _credit_service

# Storage overage
await _credit_service.deduct_credits_after_service(
    user_id="user-1",
    amount=10,
    description="Storage overage for 5GB extra usage",
)

# Manual adjustment
await _credit_service.deduct_credits(
    user_id="user-1",
    amount=50,
    description="Manual credit adjustment for billing cycle",
)

Refunds

# Refund credits to user
await _credit_service.add_credits(
    user_id="user-1",
    amount=100,
    description="Refund for failed API call #12345",
)

Scheduled Credit Allocation

from credit_management.services.expiration_service import ExpirationService

expiration = ExpirationService(db=_db, ledger=_ledger, credit_service=_credit_service)

# Check and expire credits
expired = await expiration.check_credit_expiration(user_id="user-1")
print(f"Expired {expired} credits for user-1")

🧪 Testing

Use the in-memory backend for zero-dependency tests:

import asyncio
from credit_management.db.memory import InMemoryDBManager
from credit_management.services.credit_service import CreditService
from credit_management.logging.ledger_logger import LedgerLogger

async def test():
    db = InMemoryDBManager()
    ledger = LedgerLogger(db=db, file_path="/tmp/test_ledger.log")
    service = CreditService(db=db, ledger=ledger)
    
    await service.add_credits(user_id="test", amount=100)
    info = await service.get_user_credits_info("test")
    assert info.available == 100

asyncio.run(test())

📋 Full Example: AI API with Credit Deduction

from fastapi import FastAPI, Depends
from credit_management.api.router import (
    frontend_router, webhook_router, backend_router,
    _credit_service, setup_razorpay_provider,
)
from credit_management.api.middleware import CreditDeductionMiddleware
from credit_management.context.creditContext import addLlmUsage

app = FastAPI()

# Include all routers
app.include_router(frontend_router)
app.include_router(backend_router, prefix="/admin")
app.include_router(webhook_router)

# Automatic credit middleware
app.add_middleware(
    CreditDeductionMiddleware,
    credit_service=_credit_service,
    path_prefix="/api",
    user_id_header="X-User-Id",
    default_estimated_tokens=100,
    skip_paths=("/api/health",),
)

# Initialize payment provider
setup_razorpay_provider()

@app.post("/api/generate")
async def generate(request: Request):
    user_id = request.headers.get("X-User-Id")
    
    # Your LLM call here
    response = await call_llm("gpt-4o", prompt)
    
    # Track usage — middleware deducts automatically
    addLlmUsage(
        model="gpt-4o",
        provider="openai",
        cost=0.05,
        metadata={"tokens": response.usage.total_tokens},
    )
    return response

🚀 Ready for Production

  • ✅ MongoDB or in-memory backend
  • ✅ Razorpay payment integration
  • ✅ Atomic credit updates (race-condition safe)
  • ✅ Security with Webhook signature verification
  • 🧪 Subscription plans with auto-renew
  • ✅ Promo codes with usage limits
  • ✅ Dual-write ledger (DB + file)
  • 🧪 Notification system (low credits, expiry)
  • ✅ Cache with delta-based updates
  • ✅ Request-scoped context isolation
  • ✅ Database-agnostic interface
  • ✅ Schema generator (SQL + NoSQL)

✅ -> Battle Tested & Verified, 🧪- In Testing ,Implemented

📄 License

MIT License — see LICENSE for details.

🤝 Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

Metadata

Release files for credit-management 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for credit-management 0.7.1
File Size Uploaded Provenance
credit_management-0.7.1.tar.gz 49.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for credit-management 0.7.1
File Interpreter ABI Platform
credit_management-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 109.0 kB

Release files / credit_management-0.7.1.tar.gz

Download URL credit_management-0.7.1.tar.gz
Size 49.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9d4d5fe2016eb55bfd5cbae218a9917719e08c5bf1c4292a05189be2461c52eb
BLAKE2b-256 checksum
How to use checksums
ba1e16a2b385a7f1b0aa2ae58277f011f17ee3a731470655c19708f1a48835d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

Release files / credit_management-0.7.1-py3-none-any.whl

Download URL credit_management-0.7.1-py3-none-any.whl
Size 59.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cae7cfec2602a03b973131ccb9bb6b7c5874c9db7a479a09ffb009312a5ddfea
BLAKE2b-256 checksum
How to use checksums
b073b28e0d33f8e75f00b7c02639f33335a36d3a191d23c38ce90002304a4723
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

Security for credit-management 0.7.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for credit_management-0.7.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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