Stripe Integration Quick Start Guide
This guide helps you get the Stripe payment integration running locally in under 10 minutes.
Prerequisites
- Node.js 18+ installed
- pnpm package manager
- PostgreSQL database running
- Stripe account (free test mode)
Step 1: Install Dependencies (Already Done ✅)
The Stripe package has already been installed in the backend:
pnpm add stripe --filter backend
Step 2: Database Migration
Run the Prisma migration to add Stripe tables:
cd packages/database
pnpm prisma migrate deploy
# Or for development:
pnpm prisma migrate dev
Verify tables were created:
-- Check if new tables exist
SELECT table_name FROM information_schema.tables
WHERE table_name IN ('credit_pack_subscriptions', 'stripe_events');
Step 3: Get Stripe API Keys
1. Sign up for Stripe (if you haven't)
Visit: https://dashboard.stripe.com/register
2. Get Your Test Mode Keys
- Go to: https://dashboard.stripe.com/test/apikeys
- Copy your keys:
- Publishable key:
pk_test_... - Secret key: Click "Reveal test key" →
sk_test_...
- Publishable key:
3. Set Up Webhook Locally
For local development, you have two options:
Option A: Stripe CLI (Recommended for Local Testing)
- Install Stripe CLI:
# macOS
brew install stripe/stripe-cli/stripe
# Windows (Scoop)
scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git
scoop install stripe
# Linux
# Download from: https://github.com/stripe/stripe-cli/releases
- Login to Stripe:
stripe login
- Forward webhooks to your local server:
stripe listen --forward-to localhost:3800/stripe/webhook
- Copy the webhook signing secret that appears (starts with
whsec_...)
Option B: Use Cloudflare Tunnel (For Public URL)
If your backend is already exposed via Cloudflare Tunnel:
- Go to: https://dashboard.stripe.com/test/webhooks
- Click Add endpoint
- Enter URL:
https://api-dev.civstart.ventures/stripe/webhook - Select events (see STRIPE_PRODUCT_SETUP.md)
- Copy the signing secret
Step 4: Configure Environment Variables
Add these to your .env file in the project root:
# Stripe Configuration (Test Mode)
STRIPE_SECRET_KEY=sk_test_YOUR_SECRET_KEY_HERE
STRIPE_PUBLISHABLE_KEY=pk_test_YOUR_PUBLISHABLE_KEY_HERE
STRIPE_WEBHOOK_SECRET=whsec_YOUR_WEBHOOK_SECRET_HERE
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_YOUR_PUBLISHABLE_KEY_HERE
Note: Replace the placeholder values with your actual keys from Step 3.
Step 5: Set Up Test Products in Stripe
Follow the detailed guide in STRIPE_PRODUCT_SETUP.md, or use this quick setup:
Quick Test Product Setup
-
Click Add product
-
Create GovFit Platform Access:
- Name:
GovFit Platform Access - Price: $12,000 USD, Recurring yearly, billed monthly
- Lookup key:
govfit_platform_access - Metadata:
credits=1,frequency=monthly,productType=govfit
- Name:
-
Create 4-Credit Pack (for testing):
- Name:
4-Credit Pack - Add two prices:
- One-time: $2,000, lookup:
creditpack_4_onetime - Monthly: $1,800, lookup:
creditpack_4_monthly
- One-time: $2,000, lookup:
- Metadata:
credits=4,productType=creditpack,rolloverLimit=10
- Name:
Step 6: Start the Backend
# From project root
pnpm dev
# Or just the backend
cd apps/backend
pnpm dev
The backend should start on http://localhost:3800
Step 7: Test the Integration
1. Health Check
Test that the Stripe module is loaded:
curl http://localhost:3800/stripe/health
Expected response:
{
"status": "ok",
"timestamp": "2024-12-02T..."
}
2. Create a Test Checkout Session
You'll need a valid Clerk JWT token. Get it from your frontend or use Clerk's test tokens.
curl -X POST http://localhost:3800/stripe/create-checkout-session \
-H "Authorization: Bearer YOUR_CLERK_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"priceId": "price_YOUR_PRICE_ID",
"successUrl": "http://localhost:3801/success",
"cancelUrl": "http://localhost:3801/cancel"
}'
Expected response:
{
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_...",
"sessionId": "cs_test_..."
}
3. Complete a Test Purchase
- Open the
checkoutUrlin your browser - Use Stripe test card:
4242 4242 4242 4242 - Fill in any future expiry, any CVC, any ZIP
- Complete the purchase
4. Verify Webhook Received
Check your backend logs for:
[StripeWebhookController] Received Stripe event: checkout.session.completed
[StripeService] Successfully processed checkout for startup ...
Check database:
-- Verify event was logged
SELECT * FROM stripe_events ORDER BY created_at DESC LIMIT 1;
-- Check if credits were added
SELECT credits_remaining, monthly_allocation
FROM startup_contacts
WHERE contact_email = 'your-test-email@example.com';
Step 8: Test Subscription Management
Get Active Subscriptions
curl http://localhost:3800/stripe/subscriptions \
-H "Authorization: Bearer YOUR_CLERK_JWT_TOKEN"
Get Billing History
curl http://localhost:3800/stripe/billing-history \
-H "Authorization: Bearer YOUR_CLERK_JWT_TOKEN"
Cancel a Subscription
curl -X POST http://localhost:3800/stripe/cancel-subscription \
-H "Authorization: Bearer YOUR_CLERK_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"subscriptionId": "sub_xxx"
}'
Common Issues & Solutions
Issue: "STRIPE_SECRET_KEY is not configured"
Solution: Verify your .env file has the correct Stripe keys and restart the backend.
Issue: "Webhook signature verification failed"
Solutions:
- Verify
STRIPE_WEBHOOK_SECRETis correct - If using Stripe CLI, make sure it's running:
stripe listen --forward-to localhost:3800/stripe/webhook - If using dashboard webhook, verify endpoint URL is publicly accessible
Issue: "Startup not found for this user"
Solution: Ensure your test user email exists in the startup_contacts table:
INSERT INTO startup_contacts (id, airtable_record_id, startup_name, contact_email)
VALUES ('test-startup-id', 'rec_test', 'Test Startup', 'your-email@example.com');
Issue: Credits not added after purchase
Solutions:
- Check webhook was received (look for
checkout.session.completedin logs) - Verify metadata is correct on the Stripe price
- Check
stripe_eventstable for processing errors:SELECT * FROM stripe_events WHERE processing_error IS NOT NULL;
Issue: "PrismaService not found"
Solution: The Stripe module depends on core services. Verify app.module.ts imports StripeModule AFTER ConfigModule.
Testing Scenarios
Scenario 1: GovFit Subscription
- Create checkout session for
govfit_platform_access - Complete purchase with test card
- Verify:
govfitSubscriptionIdis setgovfitSubscriptionStatus= 'active'monthlyAllocation= 1creditsRemainingincreased by 1
Scenario 2: One-Time Credit Pack
- Create checkout for
creditpack_4_onetime - Complete purchase
- Verify:
creditsRemainingincreased by 4- No subscription created
- Transaction logged with type 'stripe_purchase'
Scenario 3: Monthly Credit Pack
- Create checkout for
creditpack_4_monthly - Complete purchase
- Verify:
- Entry in
credit_pack_subscriptionstable creditsRemainingincreased by 4monthlyAllocationincreased by 4rolloverLimit= 10
- Entry in
Scenario 4: Credit Rollover (Requires Time Simulation)
- Subscribe to monthly credit pack
- Use only 2 credits (leave 2 unused)
- Trigger renewal (simulate
invoice.paidevent) - Verify:
- New total = 4 (monthly) + 2 (rollover) = 6 credits
- Rollover respects limit (max 10 for 4-credit pack)
Scenario 5: Subscription Cancellation
- Cancel subscription via API or Stripe dashboard
- Verify:
govfitSubscriptionStatus= 'canceled'subscriptionGracePeriodEndset to +1 day- Can still access during grace period
Development Workflow
1. Make Changes to Stripe Logic
Edit files in apps/backend/src/stripe/
2. Restart Backend
The backend will auto-reload with pnpm dev
3. Test Changes
Use curl commands or Postman to test endpoints
4. Check Logs
Monitor terminal for logs from StripeService and StripeWebhookController
5. Verify Database Changes
-- Check recent transactions
SELECT * FROM credit_transactions
ORDER BY created_at DESC LIMIT 10;
-- Check webhook events
SELECT type, processed, processing_error
FROM stripe_events
ORDER BY created_at DESC LIMIT 10;
-- Check subscriptions
SELECT sc.startup_name, sc.govfit_subscription_status, cps.credits, cps.status
FROM startup_contacts sc
LEFT JOIN credit_pack_subscriptions cps ON sc.id = cps.startup_id;
Next Steps
- Frontend Integration - Implement billing UI (see Phase 2 in STRIPE_IMPLEMENTATION_SUMMARY.md)
- Email Notifications - Set up email templates for:
- Purchase confirmations
- Subscription renewals
- Payment failures
- Expiry warnings
- Admin Dashboard - Add admin tools for:
- Viewing all subscriptions
- Manually triggering renewals
- Refunding purchases
- Testing - Write unit and integration tests
- Production Deployment - Switch to live mode (see STRIPE_PRODUCT_SETUP.md)
Useful Commands
Stripe CLI Commands
# Listen for webhooks
stripe listen --forward-to localhost:3800/stripe/webhook
# Trigger specific webhook event
stripe trigger checkout.session.completed
# View recent events
stripe events list --limit 10
# Get subscription details
stripe subscriptions retrieve sub_xxx
Database Queries
# Connect to database
psql $DATABASE_URL
# Check Stripe customers
SELECT id, startup_name, stripe_customer_id, govfit_subscription_status
FROM startup_contacts
WHERE stripe_customer_id IS NOT NULL;
# Check recent credit changes
SELECT sc.startup_name, ct.action_type, ct.amount, ct.created_at
FROM credit_transactions ct
JOIN startup_contacts sc ON ct.startup_id = sc.id
ORDER BY ct.created_at DESC
LIMIT 20;
Support
- Stripe Issues: Check Stripe Documentation
- Backend Issues: Review
STRIPE_IMPLEMENTATION_SUMMARY.md - Setup Issues: Follow
STRIPE_PRODUCT_SETUP.md
Happy Testing! 🚀