Skip to content

feat: Wire Stripe checkout for Pro/Elite subscriptions#89

Merged
eddiebelaval merged 1 commit intomainfrom
deepstack/stripe-checkout
Apr 2, 2026
Merged

feat: Wire Stripe checkout for Pro/Elite subscriptions#89
eddiebelaval merged 1 commit intomainfrom
deepstack/stripe-checkout

Conversation

@eddiebelaval
Copy link
Copy Markdown
Owner

@eddiebelaval eddiebelaval commented Apr 2, 2026

Summary

  • New /api/checkout route: creates Stripe checkout sessions for Pro ($19) and Elite ($49)
  • New /api/webhooks/stripe route: handles subscription lifecycle (created, updated, deleted, payment failed)
  • Pricing page now calls Next.js API route instead of Python backend
  • Product IDs hardcoded (no price ID hunting needed)

Env vars needed on Vercel

  • STRIPE_SECRET_KEY
  • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
  • SUPABASE_SERVICE_ROLE_KEY
  • STRIPE_WEBHOOK_SECRET (after deploy, from Stripe webhook setup)

Post-merge setup

  1. Set env vars on Vercel
  2. Add webhook endpoint in Stripe: https://deepstack.trade/api/webhooks/stripe
  3. Events: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed

Test plan

  • Verify Vercel preview builds
  • Test checkout flow with Stripe test mode
  • Verify webhook updates Supabase profile

Generated with Claude Code

Summary by CodeRabbit

New Features

  • Stripe subscription integration now available with Pro and Elite pricing tiers
  • New checkout functionality enables users to upgrade to paid subscription plans
  • Automatic subscription management with real-time status updates and payment tracking

New API routes (Next.js, no Python backend dependency):
- /api/checkout: Creates Stripe checkout session for Pro ($19) or Elite ($49)
- /api/webhooks/stripe: Handles subscription lifecycle events

Implementation:
- Looks up prices by product ID at runtime (no price ID config needed)
- Product IDs hardcoded: prod_Ta3YZOPq86bM2J (Pro), prod_Ta3aXZCqBcoFnI (Elite)
- Creates Stripe customer on first checkout, links to Supabase profile
- Webhook updates subscription_tier, subscription_status in profiles table
- Handles: checkout.session.completed, subscription.updated/deleted, invoice.payment_failed
- Uses Supabase service role key for webhook (no user session available)

Also:
- Updated pricing page to call /api/checkout (was calling Python backend)
- Added stripe server SDK to package.json
- Updated .env.example with all required Stripe + Supabase vars

Requires Vercel env vars: STRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
SUPABASE_SERVICE_ROLE_KEY, STRIPE_WEBHOOK_SECRET (after deploy)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
deepstack Canceled Canceled Apr 2, 2026 10:03pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5b23fd4-4cf2-4752-a019-a85a381e7664

📥 Commits

Reviewing files that changed from the base of the PR and between c73552d and 2e53c37.

📒 Files selected for processing (5)
  • web/.env.example
  • web/package.json
  • web/src/app/api/checkout/route.ts
  • web/src/app/api/webhooks/stripe/route.ts
  • web/src/app/pricing/page.tsx

📝 Walkthrough

Walkthrough

This change integrates Stripe payment processing into the application by adding environment configuration for Stripe credentials and product IDs, implementing API endpoints for checkout session creation and webhook event handling, and updating the pricing page to use the new internal checkout endpoint.

Changes

Cohort / File(s) Summary
Configuration & Dependencies
web/.env.example, web/package.json
Added Stripe environment variables (STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, product ID mappings) and SUPABASE_SERVICE_ROLE_KEY for webhook-driven updates. Added stripe package dependency (v^17.7.0).
Stripe API Integration
web/src/app/api/checkout/route.ts, web/src/app/api/webhooks/stripe/route.ts
Implemented POST endpoint for creating Stripe checkout sessions with user/tier validation, Supabase customer ID management, and recurring price resolution. Added webhook handler to process Stripe events (checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed) and sync subscription state to Supabase profiles.
Frontend Integration
web/src/app/pricing/page.tsx
Updated checkout request to target internal relative API route (/api/checkout) instead of external backend URL.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Pricing as Pricing Page
    participant CheckoutAPI as /api/checkout
    participant Supabase
    participant Stripe
    
    User->>Pricing: Click upgrade to tier
    Pricing->>CheckoutAPI: POST /api/checkout {tier, user_id, user_email}
    CheckoutAPI->>CheckoutAPI: Validate tier & credentials
    CheckoutAPI->>Supabase: Query profiles for stripe_customer_id
    alt No existing customer
        CheckoutAPI->>Stripe: Create customer
        Stripe-->>CheckoutAPI: customer_id
        CheckoutAPI->>Supabase: Update profiles with customer_id
    end
    CheckoutAPI->>Stripe: List recurring prices for product
    CheckoutAPI->>Stripe: Create checkout session
    Stripe-->>CheckoutAPI: session {url, id}
    CheckoutAPI-->>Pricing: Return session URL
    Pricing-->>User: Redirect to Stripe checkout
Loading
sequenceDiagram
    participant Stripe as Stripe (Events)
    participant WebhookAPI as /webhooks/stripe
    participant WebhookAPI as Webhook Handler
    participant Supabase as Supabase
    
    Stripe->>WebhookAPI: POST with event + stripe-signature
    WebhookAPI->>WebhookAPI: Verify signature
    alt Signature invalid
        WebhookAPI-->>Stripe: 400 Bad Request
    end
    
    alt checkout.session.completed
        WebhookAPI->>Supabase: Update subscription_tier, status=active
    else customer.subscription.updated
        WebhookAPI->>Supabase: Map product to tier, update status & dates
    else customer.subscription.deleted
        WebhookAPI->>Supabase: Set tier=free, status=canceled, ends_at
    else invoice.payment_failed
        WebhookAPI->>Supabase: Set status=past_due, log warning
    end
    
    WebhookAPI-->>Stripe: 200 {received: true}
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Poem

🐰 Stripes of gold now flow through our code,
Payments dance on the billing road.
Webhooks whisper secrets true,
Subscriptions bloom in every hue. ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch deepstack/stripe-checkout

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@eddiebelaval eddiebelaval merged commit 90f8341 into main Apr 2, 2026
6 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant