Skip to content
GitHubTwitterDiscord

Stripe Integration & Testing

This guide covers everything you need to know about integrating Stripe payments into your LaunchKit SaaS, including webhook setup and comprehensive testing procedures.

LaunchKit’s Stripe integration handles:

  • One-time payments for products and licenses
  • Recurring subscriptions with automatic billing
  • Customer portal for subscription management
  • Webhook processing for real-time updates
  • Invoice generation and payment tracking
  1. Go to Stripe Dashboard
  2. Complete your business profile
  3. Enable payment methods (cards, wallets, etc.)
  4. Set up your branding and customer emails
# Test keys (for development)
STRIPE_PUBLIC_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec...
  1. In Stripe Dashboard, go to DevelopersWebhooks

  2. Click “Add endpoint”

  3. Set endpoint URL: https://yourdomain.com/api/webhook/stripe

  4. Select these events to listen for:

    • checkout.session.completed
    • checkout.session.expired
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.paid
    • invoice.payment_failed
  5. Copy the webhook secret: whsec_...

Add your Stripe keys to .env.local:

# Stripe Configuration
STRIPE_PUBLIC_KEY=pk_test_your_publishable_key
STRIPE_SECRET_KEY=sk_test_your_secret_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret

The webhook handler at /app/api/webhook/stripe/route.ts processes Stripe events:

case 'checkout.session.completed': {
  // ✅ First payment successful
  // - Create purchase record
  // - Grant user access
  // - Send confirmation email
  // - Create user account if needed
}

In your Stripe Dashboard:

  1. Go to ProductsAdd Product

  2. Enter product details:

    • Name: “LaunchKit Pro License”
    • Description: “Complete NextJS SaaS boilerplate”
    • Price: $99 (one-time) or $29/month (subscription)
  3. Copy the Price ID (starts with price_)

Use your admin panel at /dashboard/admin/products or directly insert:

INSERT INTO products (
  name,
  description,
  price,
  stripe_price_id,
  type,
  billing_type,
  billing_interval,
  is_active,
  is_featured
) VALUES (
  'LaunchKit Pro License',
  'Complete NextJS SaaS boilerplate with authentication, payments, and deployment',
  99.00,
  'price_1234567890',  -- Your Stripe price ID
  'github',            -- 'github' or 'link'
  'one_time',          -- 'one_time' or 'subscription'
  NULL,                -- NULL for one-time, 'month'/'year' for subscriptions
  true,
  true
);
brew install stripe/stripe-cli/stripe
stripe login

This opens your browser to authenticate with your Stripe account.

stripe listen --forward-to localhost:3000/api/webhook/stripe

Important: Keep this running in a separate terminal while testing!

The CLI will display:

  • Webhook signing secret (starts with whsec_)
  • Real-time event logs
  • HTTP request/response details

Copy the webhook secret from the CLI output to your .env.local:

STRIPE_WEBHOOK_SECRET=whsec_1234567890abcdef
  1. Start your local server: bun dev
  2. Start Stripe CLI forwarding: stripe listen --forward-to localhost:3000/api/webhook/stripe
  3. Navigate to your pricing page: http://localhost:3000/#pricing
  4. Click a “Purchase” button
  5. Use Stripe test cards:
Card Number: 4242424242424242
Expiry: 12/34
CVC: 123
ZIP: 12345

After completing a test payment, check:

Stripe CLI Output:

2025-01-15 10:30:15 --> checkout.session.completed [evt_1234567890]
2025-01-15 10:30:15 <-- [200] POST http://localhost:3000/api/webhook/stripe [evt_1234567890]

Database Changes:

-- Check purchase was created
SELECT * FROM purchases WHERE stripe_session_id = 'cs_test_...';

-- Check user access was granted
SELECT has_access FROM profiles WHERE customer_id = 'cus_...';

Server Logs:

Purchase record created for user abc-123 and product def-456
Purchase confirmation email sent to [email protected]

For subscription products:

  1. Complete a subscription checkout
  2. In Stripe Dashboard, go to Customers → find your test customer
  3. Cancel the subscription to test cancellation flow
  4. Change the subscription to test update flow

Each webhook event should trigger an email. Check your email service logs or use the test email endpoint to verify templates.

Use Stripe CLI to trigger specific events:

# Simulate successful payment
stripe trigger checkout.session.completed

# Simulate failed payment
stripe trigger invoice.payment_failed

# Simulate subscription cancellation
stripe trigger customer.subscription.deleted
  1. Complete a subscription purchase
  2. Navigate to /dashboard/settings/billing
  3. Click “Manage Billing” to open Stripe Customer Portal
  4. Test subscription changes, payment method updates, etc.

For GitHub-type products:

  1. Complete purchase
  2. Navigate to /dashboard/products
  3. Provide GitHub username
  4. Verify repository invitation is sent

In Stripe Dashboard:

  1. Update webhook endpoint to your production URL
  2. Copy the new webhook secret
  3. Update production environment variables

Replace test keys with live keys:

STRIPE_WEBHOOK_SECRET=pk_live_your_live_key
STRIPE_SECRET_KEY=sk_live_your_live_secret
STRIPE_WEBHOOK_SECRET=whsec_your_live_webhook_secret

Use Stripe CLI to test production webhooks:

stripe listen --forward-to https://yourdomain.com/api/webhook/stripe --live

The webhook handler includes several security measures:

try {
  event = stripe.webhooks.constructEvent(body, signature, webhookSecret);
} catch (err) {
  console.error(`Webhook signature verification failed. ${err.message}`);
  return NextResponse.json({ error: err.message }, { status: 400 });
}

Webhooks are idempotent - processing the same event multiple times won’t cause issues.

Webhooks use the Supabase service role key to bypass RLS policies:

const supabase = new SupabaseClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.SUPABASE_SERVICE_ROLE_KEY
);

Webhook Not Receiving Events:

  • Check webhook URL is correct and accessible
  • Verify webhook secret matches
  • Check firewall settings

Database Errors:

  • Ensure service role key has correct permissions
  • Check RLS policies allow webhook operations
  • Verify foreign key relationships

Email Not Sending:

  • Check Resend API key is configured
  • Verify email templates are valid
  • Check rate limits and quotas

Stripe Dashboard:

  • View all webhook attempts and responses
  • See detailed event data
  • Check customer and payment status

Stripe CLI:

# View recent events
stripe events list

# Get specific event details
stripe events retrieve evt_1234567890

# Resend webhook
stripe events resend evt_1234567890

Server Logs: Add detailed logging to your webhook handler for debugging.