PAR-202
Stripe billing — plans, checkout, webhooks, PAYG AI
The external/payment half of monetisation (PAR-193), split out because it needs design sign-off + Stripe credentials and is outward-facing (real payment surface). Built on the metering foundation already shipped (usage_event + tenant.seat_limit).
Scope (design-first, needs decisions on tiers + what's metered/charged):
- Plan model on
tenant(plan id, seat allowance, AI token allowance); seed a free tier. - Stripe: customer + subscription per workspace, Checkout for plan purchase, billing portal, webhook handling (subscription state → plan/seat_limit), test vs live mode via config/secrets.
- PAYG AI: meter
usage_event(ai_tokens) and report/charge overage (Stripe usage records or invoice items). - Cloud-only; self-hosted bypasses billing.
Note: keep secrets out of the repo; verify webhook signatures; this is workspace-level billing.
Resources
- commit8880281 Implement billing scaffolding (Stripe wired but inert) (PAR-202)ParadauxIO/tesks
Comments
tesks · Jun 16, 2026, 10:00 AM
Implemented + inert (tesks 8880281) — drop-in for later, no live Stripe yet, per the brief.
Settled & built: plan model (free/pro/enterprise seeded, with seat + AI-token allowances + a stripe_price_id slot), tenant.plan_id + Stripe customer/subscription/status columns; BillingService (effective seat limit = tenant override else plan; token allowance/period-usage/overage; applySubscription/applyByCustomer); seat enforcement now plan-aware; BillingProvider interface with DisabledBillingProvider active by default; StripeBillingProvider (raw Stripe REST, no SDK) + StripeWebhookController (full signature verify + event→state mapping) gated on tesks.billing.enabled=true. 7 tests; suite 131 green.
To go live (2-min wiring, ~2 months): 1) set tesks.billing.enabled=true + stripe-secret-key + stripe-webhook-secret; 2) set plan.stripe_price_id for paid plans; 3) point a Stripe webhook at /billing/webhook; 4) add the checkout/portal entry points to the UI (PAR-203). Checklist also in StripeBillingProvider's javadoc.
Marking Pending Release (the scaffolding ships; activation is config, not code).
tesks · Jun 16, 2026, 8:11 PM
Verification: scaffolding only — keeping open (consistent with the ticket's "design-first, needs Stripe credentials"). Present: plan table + free/pro/enterprise seed and tenant.plan_id/stripe_customer_id/... (V25); BillingService (plans, seat limit, token allowance/overage); a StripeWebhookController + StripeBillingProvider. Not done: no Stripe SDK (com.stripe:stripe-java) — raw HTTP stubs only; no billing API surface or plan-selection/checkout UI in tesks-ui; webhook only flips subscription state; no upsell journey. Real Stripe integration + UI still required.
tesks · Jun 16, 2026, 8:14 PM
Closing as won't-do-now / revisit later (not Done). Stripe billing isn't on the roadmap for the next ~6 months, and by the time it is, the app's architecture is likely to be materially different — so this should get a fresh design pass rather than being implemented against today's assumptions. The metering foundation (usage_event, seat_limit, plan schema) stays in place. Billing won't be forgotten when the time comes; re-open/re-scope then.
Activity
- tesks changed status to Status → Canceled
- tesks commented
- tesks commented
- ParadauxIO linked a commit — Commit 8880281 — Implement billing scaffolding (Stripe wired but inert) (PAR-202)
- tesks changed status to Status → Pending Release
- tesks commented
- tesks changed status to Status → In Progress
- tesks created the issue