feat(story-5.3): add Stripe webhook subscription lifecycle handlers

- Add migration 125: subscription_current_period_end column
- Add PLAN_LIMITS config (free/pro_monthly/pro_yearly token + pages limits)
- Add subscription webhook handlers: created/updated/deleted, invoice payment
- Handle checkout.session.completed for subscription mode separately from PAYG
- Idempotency: subscription_id + status + plan_id + period_end guard
- pages_limit upgraded on activation, gracefully downgraded on cancel
- Token reset on subscription_create and subscription_cycle billing events
- Period_end forward-only guard against out-of-order webhook delivery

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vonic 2026-04-15 00:43:07 +07:00
parent 07a4bc3fc3
commit 20c4f128bb
7 changed files with 381 additions and 27 deletions

View file

@ -310,6 +310,13 @@ class Config:
os.getenv("STRIPE_RECONCILIATION_BATCH_SIZE", "100")
)
# Subscription plan limits
PLAN_LIMITS: dict[str, dict[str, int]] = {
"free": {"monthly_token_limit": 50_000, "pages_limit": 500},
"pro_monthly": {"monthly_token_limit": 1_000_000, "pages_limit": 5000},
"pro_yearly": {"monthly_token_limit": 1_000_000, "pages_limit": 5000},
}
# Auth
AUTH_TYPE = os.getenv("AUTH_TYPE")
REGISTRATION_ENABLED = os.getenv("REGISTRATION_ENABLED", "TRUE").upper() == "TRUE"