Stripe Setup Guide for StemBlock AI
This guide walks you through setting up Stripe for both test mode (development) and production mode (live).
Table of Contents
- Prerequisites
- Test Mode Setup (Development)
- Production Mode Setup (Live)
- Environment Variables
- Webhook Configuration
- Product & Price Setup
- Testing Your Integration
- Troubleshooting
Prerequisites
- Stripe Account: Create a free account at stripe.com
- Access to Backend Code: You'll need to update environment variables
- CLI Access (optional): Install Stripe CLI for webhook testing
Test Mode Setup (Development)
Stripe provides a test mode where you can simulate payments without real money.
Step 1: Get Your Test API Keys
- Log in to your Stripe Dashboard
- In the top-right corner, toggle to Test mode (you'll see a "TEST DATA" banner)
- Navigate to Developers → API keys
- Copy the following keys:
- Publishable key: Starts with
pk_test_... - Secret key: Starts with
sk_test_...(click "Reveal test key")
- Publishable key: Starts with
Step 2: Create Test Products & Prices
- Navigate to Products → Add product
- Create the Team product:
- Name: "Team Plan"
- Description: "Professional plan for small teams"
- Pricing:
- Monthly: $29/month (recurring)
- Yearly: $276/year (recurring, $23/month effective)
- Tax code: Software as a service (SaaS)
- After creating, copy the Price IDs (starts with
price_...)- You'll need these for
STRIPE_PRICE_TEAM_MONTHLYandSTRIPE_PRICE_TEAM_YEARLY
- You'll need these for
Step 3: Get Test Webhook Secret
Option A: Using Stripe CLI (Recommended for local development)
-
Install Stripe CLI:
# macOS (Homebrew)
brew install stripe/stripe-cli/stripe
# Windows (Scoop)
scoop install stripe
# Linux
wget https://github.com/stripe/stripe-cli/releases/latest/download/stripe_linux_amd64.tar.gz
tar -xvf stripe_linux_amd64.tar.gz
sudo mv stripe /usr/local/bin -
Login to Stripe:
stripe login -
Forward webhooks to your local server:
stripe listen --forward-to localhost:3001/api/v1/billing/webhook -
Copy the webhook signing secret (starts with
whsec_...)- This will be displayed when you run
stripe listen
- This will be displayed when you run
Option B: Manual Webhook Setup (for deployed test environments)
- Navigate to Developers → Webhooks
- Click Add endpoint
- Endpoint URL:
https://your-test-backend.com/api/v1/billing/webhook - Events to send:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_failedinvoice.payment_succeededcheckout.session.completed
- Click Add endpoint
- Copy the Signing secret (starts with
whsec_...)
Step 4: Update Environment Variables (Test Mode)
Add these to your .env.development file:
# Stripe Test Keys
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
# Stripe Price IDs (Test Mode)
STRIPE_PRICE_TEAM_MONTHLY=price_YOUR_MONTHLY_PRICE_ID
STRIPE_PRICE_TEAM_YEARLY=price_YOUR_YEARLY_PRICE_ID
# Frontend URL (for checkout redirects)
FRONTEND_URL=http://localhost:3000
Step 5: Test with Test Cards
Stripe provides test card numbers that simulate different scenarios:
| Card Number | Scenario |
|---|---|
| 4242 4242 4242 4242 | Successful payment |
| 4000 0000 0000 0002 | Card declined |
| 4000 0025 0000 3155 | Requires 3D Secure |
| 4000 0000 0000 9995 | Insufficient funds |
Expiration Date: Any future date (e.g., 12/34) CVC: Any 3 digits (e.g., 123) ZIP: Any 5 digits (e.g., 12345)
Production Mode Setup (Live)
⚠️ WARNING: Production mode processes real payments. Only enable when you're ready to go live.
Step 1: Activate Your Stripe Account
- Log in to Stripe Dashboard
- Complete the Account activation checklist:
- Provide business information
- Add bank account for payouts
- Verify your identity (may require ID upload)
- Provide tax information (W-9 for US businesses)
- Wait for Stripe to approve your account (usually instant, can take 1-2 business days)
Step 2: Get Your Live API Keys
- In the Stripe Dashboard, toggle to Live mode (no "TEST DATA" banner)
- Navigate to Developers → API keys
- Copy the following keys:
- Publishable key: Starts with
pk_live_... - Secret key: Starts with
sk_live_...(click "Reveal live key")
- Publishable key: Starts with
⚠️ SECURITY WARNING: Never commit live keys to version control. Store them securely.
Step 3: Create Live Products & Prices
- Navigate to Products → Add product
- Create the Team product (same as test mode):
- Name: "Team Plan"
- Description: "Professional plan for small teams"
- Pricing:
- Monthly: $29/month (recurring)
- Yearly: $276/year (recurring)
- Copy the Price IDs for both monthly and yearly
Step 4: Set Up Live Webhooks
- Navigate to Developers → Webhooks
- Click Add endpoint
- Endpoint URL:
https://api.stemblock.ai/api/v1/billing/webhook- ⚠️ Must be HTTPS in production
- Events to send (same as test mode):
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_failedinvoice.payment_succeededcheckout.session.completed
- Click Add endpoint
- Copy the Signing secret (starts with
whsec_...)
Step 5: Update Environment Variables (Production)
Add these to your .env.production file (or hosting platform's environment variables):
# Stripe Live Keys
STRIPE_SECRET_KEY=sk_live_YOUR_SECRET_KEY_HERE
STRIPE_PUBLISHABLE_KEY=pk_live_YOUR_PUBLISHABLE_KEY_HERE
STRIPE_WEBHOOK_SECRET=whsec_YOUR_WEBHOOK_SECRET_HERE
# Stripe Price IDs (Live Mode)
STRIPE_PRICE_TEAM_MONTHLY=price_YOUR_MONTHLY_PRICE_ID
STRIPE_PRICE_TEAM_YEARLY=price_YOUR_YEARLY_PRICE_ID
# Frontend URL (production)
FRONTEND_URL=https://stemblock.ai
Step 6: Enable Required Payment Methods
- Navigate to Settings → Payment methods
- Enable:
- Cards (Visa, Mastercard, Amex)
- Apple Pay / Google Pay (recommended for mobile)
- Link (Stripe's one-click checkout)
Step 7: Configure Email Receipts
- Navigate to Settings → Emails
- Customize email receipts:
- Add your logo
- Set "From" email address
- Enable customer receipts
Environment Variables
Complete list of required environment variables:
#######################
# Stripe Configuration
#######################
# API Keys (get from Stripe Dashboard → Developers → API keys)
STRIPE_SECRET_KEY=sk_test_or_live_YOUR_KEY
STRIPE_PUBLISHABLE_KEY=pk_test_or_live_YOUR_KEY
# Webhook Secret (get from Stripe Dashboard → Developers → Webhooks)
STRIPE_WEBHOOK_SECRET=whsec_YOUR_SECRET
# Price IDs (get from Stripe Dashboard → Products)
STRIPE_PRICE_TEAM_MONTHLY=price_YOUR_MONTHLY_ID
STRIPE_PRICE_TEAM_YEARLY=price_YOUR_YEARLY_ID
# Optional: Enterprise (custom pricing, handled via sales)
# STRIPE_PRICE_ENTERPRISE_CUSTOM=price_YOUR_ENTERPRISE_ID
# URLs
FRONTEND_URL=http://localhost:3000 # or https://stemblock.ai in production
Webhook Configuration
Events to Listen For
Your backend (billing.controller.ts) handles these webhook events:
-
customer.subscription.created
- Triggered when a new subscription is created
- Updates user's subscription status to ACTIVE
-
customer.subscription.updated
- Triggered when subscription changes (upgrade, downgrade, renewal)
- Updates subscription tier, billing cycle, etc.
-
customer.subscription.deleted
- Triggered when subscription is canceled
- Updates user's status to CANCELLED, may downgrade to COMMUNITY tier
-
invoice.payment_failed
- Triggered when payment fails
- Updates status to PAST_DUE, sends alert to user
-
invoice.payment_succeeded
- Triggered when payment succeeds
- Updates subscription period, confirms payment
-
checkout.session.completed
- Triggered when user completes checkout
- Links Stripe customer to your user record
Testing Webhooks Locally
Using Stripe CLI:
# Terminal 1: Run your backend
npm run start:dev
# Terminal 2: Forward webhooks to local backend
stripe listen --forward-to localhost:3001/api/v1/billing/webhook
# Terminal 3: Trigger test events
stripe trigger customer.subscription.created
stripe trigger invoice.payment_succeeded
stripe trigger invoice.payment_failed
Webhook Security
The backend automatically verifies webhook signatures using:
// billing.controller.ts
const event = this.stripeService.verifyWebhookSignature(
req.rawBody,
signature
);
This ensures webhooks are genuinely from Stripe, not malicious requests.
Product & Price Setup
Product Structure
StemBlock AI uses 3 tiers:
| Tier | Price ID Variable | Price | Features |
|---|---|---|---|
| COMMUNITY | N/A (free) | $0/month | 10 AI runs, 100MB |
| TEAM | STRIPE_PRICE_TEAM_MONTHLY | $29/month | 100 AI runs, 10GB |
| TEAM | STRIPE_PRICE_TEAM_YEARLY | $276/year | 100 AI runs, 10GB |
| ENTERPRISE | Contact sales | Custom | Unlimited everything |
Creating Products in Stripe
Team Plan (Monthly)
- Product name: Team Plan
- Pricing model: Standard pricing
- Price: $29.00 USD
- Billing period: Monthly
- Currency: USD
- Tax behavior: Taxable
- Price description: Monthly subscription
Team Plan (Yearly)
- Use the same product: Team Plan
- Add a new price:
- Price: $276.00 USD (20% discount from $348)
- Billing period: Yearly
- Currency: USD
- Price description: Annual subscription (save 20%)
Price ID Mapping
After creating products, update your environment variables:
STRIPE_PRICE_TEAM_MONTHLY=price_1234567890abcdef # $29/month
STRIPE_PRICE_TEAM_YEARLY=price_abcdef1234567890 # $276/year
These IDs are hardcoded in stripe.service.ts:
private getPriceId(tier: SubscriptionTier, billingInterval: BillingInterval): string {
const priceMap = {
TEAM: {
MONTHLY: this.configService.get('STRIPE_PRICE_TEAM_MONTHLY'),
YEARLY: this.configService.get('STRIPE_PRICE_TEAM_YEARLY'),
},
};
return priceMap[tier]?.[billingInterval];
}
Testing Your Integration
1. Test Checkout Flow
- Start your frontend and backend
- Navigate to the pricing page
- Click "Upgrade to Team"
- Select monthly or yearly
- Use test card
4242 4242 4242 4242 - Complete checkout
- Verify:
- User is redirected to success page
- Subscription status is updated in database
- Webhook events were received
2. Test Subscription Updates
# Upgrade subscription
stripe subscriptions update sub_1234567890 --default-payment-method pm_card_visa
# Cancel subscription
stripe subscriptions cancel sub_1234567890
3. Test Failed Payments
Use test card 4000 0000 0000 0002 to simulate declined payment.
Verify:
- User receives email notification
- Subscription status changes to PAST_DUE
- User can update payment method
4. Monitor Webhook Delivery
- Navigate to Developers → Webhooks
- Click on your webhook endpoint
- View Recent events tab
- Check for delivery status (should be 200 OK)
Troubleshooting
Webhooks Not Received
Problem: Backend not receiving webhook events
Solutions:
- Check webhook URL is publicly accessible (use ngrok for local testing)
- Verify webhook secret is correct in
.env - Check Stripe Dashboard → Webhooks → Recent events for errors
- Ensure backend endpoint is
/api/v1/billing/webhook - Verify your server is running and not behind a firewall
Signature Verification Failed
Problem: Error "Webhook signature verification failed"
Solutions:
- Ensure you're using the correct webhook secret for your environment (test vs live)
- Make sure you're passing the raw request body, not parsed JSON
- Check that
stripe-signatureheader is present - Verify Stripe API version matches (currently
2024-11-20.acacia)
Checkout Session Creation Failed
Problem: Error when creating checkout session
Solutions:
- Verify
STRIPE_SECRET_KEYis set correctly - Check that price IDs exist in Stripe Dashboard
- Ensure you're using the correct mode (test vs live)
- Verify
FRONTEND_URLis set correctly for redirects - Check backend logs for detailed error messages
Customer Not Found
Problem: Stripe customer doesn't exist for user
Solutions:
- Run the customer creation flow in
stripe.service.ts - Check database for
stripeCustomerIdfield - Manually create customer in Stripe Dashboard if needed
- Re-link customer ID to user record
Price ID Not Found
Problem: Error "No such price: 'price_...'"
Solutions:
- Verify price exists in Stripe Dashboard → Products
- Check you're using the correct environment (test vs live)
- Ensure
STRIPE_PRICE_TEAM_MONTHLYandSTRIPE_PRICE_TEAM_YEARLYare set - Recreate price if it was deleted
Subscription Status Not Updating
Problem: User subscription not updating after payment
Solutions:
- Check webhook events are being delivered
- Verify webhook handler in
billing.controller.tsis processing events - Check database for subscription record
- Look for errors in backend logs
- Manually trigger webhook event to test
Security Best Practices
-
Never commit API keys to version control
- Add
.envto.gitignore - Use environment variables on hosting platform
- Add
-
Use webhook signature verification
- Always verify signatures before processing webhooks
- This prevents malicious requests
-
Separate test and production keys
- Never use test keys in production
- Use different webhook endpoints for test/live
-
Rotate API keys periodically
- Navigate to Developers → API keys → "Roll key"
- Update environment variables after rotation
-
Monitor for suspicious activity
- Enable Stripe Radar for fraud detection
- Review failed payments regularly
-
Use HTTPS in production
- Stripe requires HTTPS for live webhooks
- Obtain SSL certificate (Let's Encrypt is free)
Additional Resources
- Stripe API Documentation
- Stripe Testing Guide
- Stripe Webhooks Guide
- Stripe Checkout Documentation
- Stripe CLI Documentation
Support
For questions or issues:
- Stripe Support: support.stripe.com
- StemBlock AI Team: dev@stemblock.ai
- Backend Issues: Check
stemblockai-backend/src/billing/for implementation details
Last Updated: 2025-01-15 Stripe API Version: 2024-11-20.acacia Backend Version: 1.0.0