Skip to main content

Payments

KwikSaaS uses Stripe for all payment processing. This guide covers setup, configuration, and testing.
Payments are pre-configured. This guide helps you customize plans and connect your Stripe account.

What’s Included

  • Stripe Checkout — Hosted payment page for secure transactions
  • Customer Portal — Self-service subscription management
  • Webhook sync — Automatic database updates on payment events
  • Plan gating — Feature access based on subscription status
  • Multiple pricing — Subscriptions (monthly/yearly) and lifetime one-time purchases

Payment Flow


Prerequisites

Stripe Account

Create at stripe.com. Use test mode for development.

Supabase Database

Migrations applied with billing tables.

Stripe Setup

1

Get API keys

Go to Stripe Dashboard → Developers → API keys:
Use test mode keys during development. Toggle “Test mode” in the Stripe Dashboard header.
2

Create products

Go to Products in Stripe Dashboard:
  1. Click Add product
  2. Set name (e.g., “KwikSaaS Standard”)
  3. Add description
  4. Set pricing:
    • One-time for lifetime access
    • Recurring for subscriptions
  5. Save and copy the Price ID (starts with price_)
3

Add price IDs to environment

4

Set up webhooks

For local development:
Copy the webhook signing secret (whsec_...) to:
For production:
  1. Go to Developers → Webhooks in Stripe Dashboard
  2. Add endpoint: https://yourdomain.com/api/webhooks/stripe
  3. Select events:
    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_succeeded
    • invoice.payment_failed
    • payment_intent.succeeded
  4. Copy the signing secret to production environment

Plan Configuration

Plans are defined in src/lib/payments/plans.ts:

Plan Properties


API Endpoints

Create Checkout Session

POST /api/checkout_sessions
Response:

Customer Portal

POST /api/customer_portal Opens Stripe’s billing portal for subscription management.

Webhooks

POST /api/webhooks/stripe Handles Stripe events and updates database:

Database Tables

user_subscriptions

Stores active subscription state:

one_time_purchases

Stores lifetime/one-time purchases:

payment_history

Audit log of all payments:

Access Control

Check user access with helpers in src/lib/access.ts:

Feature Keys


Testing

Test Cards

Use these card numbers in Stripe test mode: Use any future expiry date and any 3-digit CVC.

Testing Webhooks Locally

  1. Start your dev server: npm run dev
  2. Start Stripe listener:
  3. Complete a test checkout
  4. Check database for new records

Verify Webhook Events


Promo Codes & Coupons

Create in Stripe

  1. Go to Products → Coupons in Stripe Dashboard
  2. Create coupon with:
    • Percentage or fixed amount off
    • Duration (once, repeating, forever)
    • Redemption limits

Enable in Plans


Troubleshooting

Check:
  • Price ID is correct and matches Stripe
  • Plan exists in plans.ts with matching price ID
  • Stripe is in correct mode (test vs live)
Check: - STRIPE_WEBHOOK_SECRET matches the endpoint - For local: restart stripe listen and update secret - For production: verify webhook URL is correct
Check: 1. Webhook listener is running 2. Check Stripe Dashboard → Developers → Webhooks for failures 3. Verify database migrations have been applied 4. Check server logs for errors
Check:
  • User has a stripe_customer_id in user_subscriptions
  • User is authenticated
  • Portal is enabled in Stripe Dashboard settings

Going to Production

1

Switch to live mode

Replace test API keys with live keys in production environment.
2

Create production products

Create new products in live mode (test products don’t transfer).
3

Add production webhook

Add endpoint in Stripe Dashboard pointing to production URL.
4

Update price IDs

Set production price IDs in environment variables.
5

Test with real card

Do a small real transaction to verify the flow.
Keep test and production environments completely separate. Never mix test and live API keys.

Next Steps

Deployment

Deploy with payments enabled

Access Control

Understand database and RLS policies