Skip to content

Stripe Subscription Plugin (v1) #760

@lane711

Description

@lane711

Overview

Add a Stripe plugin that handles subscription lifecycle events via webhooks and exposes subscription status to the rest of the system through the plugin hook system.

Core Features (v1)

1. Stripe Webhook Endpoint

  • POST /api/stripe/webhook — receives Stripe events, verifies signatures using STRIPE_WEBHOOK_SECRET
  • Handles these subscription events:
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • checkout.session.completed
    • invoice.payment_succeeded
    • invoice.payment_failed

2. Subscriptions Database Table

  • id — primary key
  • userId — FK to users table
  • stripeCustomerId
  • stripeSubscriptionId
  • stripePriceId
  • status — (active, canceled, past_due, trialing, unpaid, paused)
  • currentPeriodStart / currentPeriodEnd
  • cancelAtPeriodEnd — boolean
  • createdAt / updatedAt

3. Stripe Customer Linking

  • API endpoint POST /api/stripe/create-checkout-session — creates a Stripe Checkout session for the authenticated user
  • Automatically links Stripe customer ID to SonicJS user on first checkout
  • API endpoint GET /api/stripe/subscription — returns the current user's subscription status

4. Plugin Configuration

  • STRIPE_SECRET_KEY — Stripe API key (env binding)
  • STRIPE_WEBHOOK_SECRET — webhook signature verification secret (env binding)
  • STRIPE_PRICE_ID — default price ID for checkout (env binding or plugin config)

5. Hook Integration

  • Emits stripe:subscription.created, stripe:subscription.updated, stripe:subscription.deleted hooks so other plugins can react to subscription changes
  • Emits stripe:payment.succeeded and stripe:payment.failed hooks

6. Admin UI

  • Admin page listing all subscriptions with status, user, and dates
  • Filter by status (active, canceled, past_due, etc.)
  • Link to Stripe Dashboard for each subscription

7. Auth Middleware Helper

  • requireSubscription() middleware that plugins/routes can use to gate access to subscribers only
  • Checks subscription status is active or trialing

Out of Scope for v1

  • Multiple plan/tier management
  • Usage-based billing / metering
  • Stripe Customer Portal embedding
  • Coupon / promotion code support
  • Team/org subscriptions
  • Invoicing UI within admin

Technical Notes

  • Uses the plugin builder SDK (createPluginBuilder)
  • Webhook signature verification must use raw request body (not parsed JSON)
  • All Stripe API calls use the stripe npm package
  • Routes requiring auth use existing requireAuth() middleware
  • Database model defined via Drizzle schema + Zod validation

Acceptance Criteria

  • Webhook endpoint correctly verifies Stripe signatures and processes subscription events
  • Subscription records are created/updated in the database on webhook events
  • Authenticated users can create checkout sessions and view their subscription status
  • Hooks fire on subscription lifecycle events
  • Admin page shows subscription list with filtering
  • requireSubscription() middleware correctly gates routes
  • Plugin follows existing SonicJS plugin conventions (manifest, builder, lifecycle hooks)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions