Skip to content

[Post-MVP] Organization billing and subscription management #25

@Andreas-Froyland

Description

@Andreas-Froyland

Goal

Build a billing and subscription system for organizations to upgrade from free tier to paid plans.

Scope

This is a post-MVP feature — not required for initial launch, but essential for monetization.

Billing Model (suggested)

  • Free tier: 1 project, 100 feedback items/month, basic features
  • Pro tier: Unlimited projects, unlimited feedback, GitHub integration, custom branding
  • Enterprise tier: SSO, priority support, SLA, custom deployment options

Features

Billing Page ()

  • Current plan display (Free / Pro / Enterprise)
  • Usage stats vs limits (projects, feedback items, API calls)
  • Upgrade/downgrade buttons
  • Billing history table (invoices, receipts)
  • Payment method management (add/edit/remove card)
  • Cancel subscription option

Subscription Management

  • Stripe integration (recommended) or similar payment processor
  • Webhook handling for subscription events:

  • Proration handling for mid-cycle upgrades/downgrades
  • Grace period for failed payments (3 days, then downgrade to free)

Database Schema Additions

Add to Phase 0 schema when implementing:

-- Subscriptions table
CREATE TABLE subscriptions (
  id UUID PRIMARY KEY,
  organization_id UUID REFERENCES organizations(id),
  stripe_customer_id VARCHAR,
  stripe_subscription_id VARCHAR,
  plan VARCHAR, -- 'free', 'pro', 'enterprise'
  status VARCHAR, -- 'active', 'canceled', 'past_due'
  current_period_start TIMESTAMP,
  current_period_end TIMESTAMP,
  cancel_at_period_end BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Invoices table
CREATE TABLE invoices (
  id UUID PRIMARY KEY,
  organization_id UUID REFERENCES organizations(id),
  stripe_invoice_id VARCHAR,
  amount_paid INTEGER, -- cents
  currency VARCHAR DEFAULT 'usd',
  status VARCHAR, -- 'paid', 'open', 'void', 'uncollectible'
  invoice_pdf VARCHAR, -- Stripe hosted invoice URL
  created_at TIMESTAMP DEFAULT NOW()
);

API Endpoints

GET    /api/orgs/[slug]/billing              -- Get current plan + usage
POST   /api/orgs/[slug]/billing/checkout     -- Create Stripe checkout session (upgrade)
POST   /api/orgs/[slug]/billing/portal       -- Redirect to Stripe customer portal (manage/cancel)
POST   /api/billing/webhook                  -- Stripe webhook handler
GET    /api/orgs/[slug]/billing/invoices     -- List past invoices

Usage Enforcement

Implement soft limits with grace warnings:

  • Track feedback count per billing cycle
  • Show warning at 80% of limit
  • Block new feedback at 100% (with upgrade CTA)
  • Downgrade features when subscription expires

UI/UX

  • Prominent "Upgrade" button in org settings sidebar
  • Usage progress bars on dashboard
  • Email notifications for billing events (payment success/failure, approaching limits)
  • Clear pricing page (e.g., ) with feature comparison table

Security & Compliance

  • PCI compliance: never store raw credit card data (Stripe handles this)
  • Webhook signature verification (Stripe signing secret)
  • Audit log for all billing events
  • GDPR-friendly: allow data export and account deletion

Testing

  • Use Stripe test mode with test cards
  • Test all subscription lifecycle events (upgrade, downgrade, cancel, reactivate)
  • Test webhook retry logic (Stripe retries failed webhooks)
  • Load test with simulated high-usage orgs

Nice-to-Haves (Stretch)

  • Annual billing option (discount for yearly plans)
  • Team seats pricing (per user instead of per org)
  • Usage-based pricing (pay per feedback item)
  • Coupons/promo codes
  • Referral program

Priority: Post-MVP — build after core feedback features are stable and you have real users ready to pay.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions