<< All versions

Skill v1.0.0

currentAutomated scan100/100
maxcode0917/full-stack-ai-agent-template/billing-stripe
──Details
PublishedOctober 25, 2026 at 02:14 AM
Content Hashsha256:44d674b30a0f0368...
Git SHAb2e3adbfee23
──Files
Files (1 file, 2.9 KB)
SKILL.md2.9 KBactive
SKILL.md · 46 lines · 2.9 KB

version: "1.0.0" name: billing-stripe description: Work with Stripe billing — subscriptions, plans/prices, the Customer Portal, credits, usage metering, invoices, and webhook events. Use when changing plans, handling a new Stripe webhook, debugging a payment/subscription flow, or touching credit balances and usage.


Billing & Credits (Stripe)

Billing is a thick service at backend/app/services/billing/. Routes never touch Stripe directly — everything goes through BillingService (the facade in facade.py, re-exported from __init__.py).

Layout

FileResponsibility
facade.pyBillingService — the only thing routes/workers import
checkout_service.pyCheckout sessions (seat-configurable)
subscription_service.pySubscription CRUD, change plan, cancel/reactivate
credit_service.pyCredit ledger + usage aggregation
stripe_client.pyThin Stripe API wrapper
webhook_handler.py + handlers/Event processing (customer / invoice / payment / subscription)
pricing.pyStatic plan/price data
exceptions.pyBilling domain errors (extend core/exceptions)

Data model: plan / price mirror Stripe products; subscription is one-per-org; stripe_event is an idempotency log; credit_transaction is an immutable ledger; usage_event records per-message token spend, rolled up into the mv_usage_daily materialized view.

Common tasks

Handle a new webhook event: add a handler module/function under services/billing/handlers/, dispatch it from webhook_handler.py, and record it in stripe_event for idempotency (skip if already processed). Verify the signature — never trust unsigned payloads.

Add/adjust a plan: update pricing.py and the corresponding Stripe product/price; the sync-stripe-plans command ({{ cookiecutter.project_slug }} cmd sync-stripe-plans) mirrors Stripe → local plan/price tables.

Charge/grant credits: go through credit_service so every change writes a credit_transaction row (grants, purchases, debits) and the running balance stays consistent. Never mutate balances directly.

Meter usage: write a usage_event (input/output/cached tokens, model, provider, credits charged) — the daily rollup and dashboard charts read from mv_usage_daily (refreshed by a background task).

Local testing

Use the Stripe CLI to forward webhooks: stripe listen --forward-to localhost:8000/api/v1/billing/webhook. Use Stripe test keys/mode. The webhook endpoint is unauthenticated but signature-verified.

Rules

  • Routes call BillingService; never import stripe_client or a sub-service directly from a route.
  • Every webhook is idempotent via stripe_event — re-delivery must be a no-op.
  • Credit changes always go through the ledger; the balance is derived, not authoritative state you overwrite.
  • Keep Stripe secrets in settings / .env, never inline.
All versions