billing-stripe
GitHubStripe 计费服务技能,涵盖订阅、支付、积分及 Webhook 处理。指导开发者通过 BillingService 进行账单操作、Webhook 事件处理与签名验证、积分记账及用量计量,确保数据一致性与幂等性。
Trigger Scenarios
Install
npx skills add vstorm-co/full-stack-ai-agent-template --skill billing-stripe -g -y
SKILL.md
Frontmatter
{
"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
| File | Responsibility |
|---|---|
facade.py |
BillingService — the only thing routes/workers import |
checkout_service.py |
Checkout sessions (seat-configurable) |
subscription_service.py |
Subscription CRUD, change plan, cancel/reactivate |
credit_service.py |
Credit ledger + usage aggregation |
stripe_client.py |
Thin Stripe API wrapper |
webhook_handler.py + handlers/ |
Event processing (customer / invoice / payment / subscription) |
pricing.py |
Static plan/price data |
exceptions.py |
Billing 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 importstripe_clientor 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.
Version History
- 0.2.16 Current 2026-07-25 10:05


