Payments (Stripe)
Stripe powers two distinct things in Cohort. Both are deployment-level configuration — set once with environment variables, verified webhooks, and honest fallbacks when unconfigured.
Workspace billing
The Billing tab in Settings shows your plan, subscription state, and invoices. It is driven by Stripe subscription and invoice data, kept in sync by a signed webhook.
| Piece | Detail |
| --- | --- |
| Feature gate | STRIPE_SECRET_KEY — without it, billing is simply not configured |
| Webhook | POST /api/webhooks/stripe, verified with STRIPE_WEBHOOK_SECRET against the raw request body |
| Behaviour when unconfigured | The webhook answers 503 (never a fake 200), and the tab reflects the absence honestly |
Point a Stripe webhook endpoint at /api/webhooks/stripe for subscription and invoice lifecycle events. Delivery is idempotent — Stripe retries are safe.
Payment links on invoices (Books)
Books — the finance surface — can attach a payment link to an invoice you send. The provider seam has two modes:
- Sandbox (no
STRIPE_SECRET_KEY): a clearly labelled sandbox URL. No money moves, and success is never faked. - Stripe (
STRIPE_SECRET_KEYset): a real Stripe Payment Link, created with a Price and Link derived from the invoice under idempotency keys — retries reuse the same objects rather than duplicating them. If creation fails, the invoice shows the error; it is never papered over with a sandbox URL.
Incoming payment events for invoices (including part-payments) post back through a second, separately signed webhook:
| Piece | Detail |
| --- | --- |
| Webhook | POST /api/webhooks/stripe/books |
| Signature | STRIPE_BOOKS_WEBHOOK_SECRET |
| Behaviour when unset | The route answers 501 — link creation still works, reconciliation events do not flow |
Separately from all of this, the plugin registry also carries a generated Stripe integration (list customers, charges, and invoices) that works like any other plugin — install it, seal an API key, grant agents. See Connect an integration. Use a restricted Stripe key for it.