Skip to main content

Quick Stripe Integration Setup

Follow these steps to get Stripe subscriptions working in CONA.

1. Add Environment Variables

Add these to apps/webapp/.env.example and apps/webapp/.env.local:
# Stripe Configuration
STRIPE_SECRET_KEY=sk_test_your_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_secret_here
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_key_here
NEXT_PUBLIC_STRIPE_PRICE_ID=price_your_id_here
Get your keys from: Stripe Dashboard

2. Apply Database Migration

cd packages/database
pnpm prisma migrate deploy
This adds Stripe fields to the organization table.

3. Set Up Stripe Product

  1. Go to Stripe Products
  2. Click Add Product
  3. Name: “CONA Subscription”
  4. Add pricing (e.g., $29/month)
  5. Copy the Price ID → Use as NEXT_PUBLIC_STRIPE_PRICE_ID

4. Configure Webhook (Production)

  1. Go to Stripe Webhooks
  2. Click Add endpoint
  3. URL: https://your-domain.com/api/webhooks/stripe
  4. Select events:
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • checkout.session.completed
  5. Copy the Signing secret → Use as STRIPE_WEBHOOK_SECRET

5. Local Development Webhook Testing

# Install Stripe CLI
brew install stripe/stripe-cli/stripe

# Login to Stripe
stripe login

# Forward webhooks to your local server
stripe listen --forward-to localhost:3000/api/webhooks/stripe

# Copy the webhook secret from CLI output
# Add it to your .env.local as STRIPE_WEBHOOK_SECRET

6. Test the Integration

Test Subscription Flow:

  1. Navigate to /subscription in your app
  2. Click “Subscribe Now”
  3. Use test card: 4242 4242 4242 4242
  4. Complete checkout
  5. Verify subscription appears as active

Test Cards:

  • Success: 4242 4242 4242 4242
  • Decline: 4000 0000 0000 0002
  • Requires Auth: 4000 0025 0000 3155

7. Protect Routes (Optional)

Add subscription checks to server actions:
import { requireActiveSubscription } from "@/app/lib/auth/subscription";

export async function premiumFeature() {
  await requireActiveSubscription(); // Throws if not subscribed
  // Your premium feature logic
}

8. Going to Production

  • Switch to live API keys (sk_live_, pk_live_)
  • Update webhook endpoint to production URL
  • Update webhook secret with production value
  • Use production price ID
  • Test with real payment method

Troubleshooting

Webhook not receiving events?
  • Check webhook URL is correct
  • Verify webhook secret matches
  • Check Stripe Dashboard → Webhooks → Recent deliveries
“No active subscription” error?
  • Check database has subscription_status = ‘active’
  • Verify webhook processed successfully
  • Check organization.is_sandbox is false (sandbox orgs bypass checks)
Can’t create checkout session?
  • Verify STRIPE_SECRET_KEY is set
  • Check NEXT_PUBLIC_STRIPE_PRICE_ID exists
  • Verify price ID is valid in Stripe Dashboard