Skip to main content

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

  1. Stripe Account: Create a free account at stripe.com
  2. Access to Backend Code: You'll need to update environment variables
  3. 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

  1. Log in to your Stripe Dashboard
  2. In the top-right corner, toggle to Test mode (you'll see a "TEST DATA" banner)
  3. Navigate to DevelopersAPI keys
  4. Copy the following keys:
    • Publishable key: Starts with pk_test_...
    • Secret key: Starts with sk_test_... (click "Reveal test key")

Step 2: Create Test Products & Prices

  1. Navigate to ProductsAdd product
  2. 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)
  3. After creating, copy the Price IDs (starts with price_...)
    • You'll need these for STRIPE_PRICE_TEAM_MONTHLY and STRIPE_PRICE_TEAM_YEARLY

Step 3: Get Test Webhook Secret

  1. 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
  2. Login to Stripe:

    stripe login
  3. Forward webhooks to your local server:

    stripe listen --forward-to localhost:3001/api/v1/billing/webhook
  4. Copy the webhook signing secret (starts with whsec_...)

    • This will be displayed when you run stripe listen

Option B: Manual Webhook Setup (for deployed test environments)

  1. Navigate to DevelopersWebhooks
  2. Click Add endpoint
  3. Endpoint URL: https://your-test-backend.com/api/v1/billing/webhook
  4. Events to send:
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_failed
    • invoice.payment_succeeded
    • checkout.session.completed
  5. Click Add endpoint
  6. 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 NumberScenario
4242 4242 4242 4242Successful payment
4000 0000 0000 0002Card declined
4000 0025 0000 3155Requires 3D Secure
4000 0000 0000 9995Insufficient 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

  1. Log in to Stripe Dashboard
  2. 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)
  3. Wait for Stripe to approve your account (usually instant, can take 1-2 business days)

Step 2: Get Your Live API Keys

  1. In the Stripe Dashboard, toggle to Live mode (no "TEST DATA" banner)
  2. Navigate to DevelopersAPI keys
  3. Copy the following keys:
    • Publishable key: Starts with pk_live_...
    • Secret key: Starts with sk_live_... (click "Reveal live key")

⚠️ SECURITY WARNING: Never commit live keys to version control. Store them securely.

Step 3: Create Live Products & Prices

  1. Navigate to ProductsAdd product
  2. 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)
  3. Copy the Price IDs for both monthly and yearly

Step 4: Set Up Live Webhooks

  1. Navigate to DevelopersWebhooks
  2. Click Add endpoint
  3. Endpoint URL: https://api.stemblock.ai/api/v1/billing/webhook
    • ⚠️ Must be HTTPS in production
  4. Events to send (same as test mode):
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_failed
    • invoice.payment_succeeded
    • checkout.session.completed
  5. Click Add endpoint
  6. 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

  1. Navigate to SettingsPayment methods
  2. Enable:
    • Cards (Visa, Mastercard, Amex)
    • Apple Pay / Google Pay (recommended for mobile)
    • Link (Stripe's one-click checkout)

Step 7: Configure Email Receipts

  1. Navigate to SettingsEmails
  2. 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:

  1. customer.subscription.created

    • Triggered when a new subscription is created
    • Updates user's subscription status to ACTIVE
  2. customer.subscription.updated

    • Triggered when subscription changes (upgrade, downgrade, renewal)
    • Updates subscription tier, billing cycle, etc.
  3. customer.subscription.deleted

    • Triggered when subscription is canceled
    • Updates user's status to CANCELLED, may downgrade to COMMUNITY tier
  4. invoice.payment_failed

    • Triggered when payment fails
    • Updates status to PAST_DUE, sends alert to user
  5. invoice.payment_succeeded

    • Triggered when payment succeeds
    • Updates subscription period, confirms payment
  6. 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:

TierPrice ID VariablePriceFeatures
COMMUNITYN/A (free)$0/month10 AI runs, 100MB
TEAMSTRIPE_PRICE_TEAM_MONTHLY$29/month100 AI runs, 10GB
TEAMSTRIPE_PRICE_TEAM_YEARLY$276/year100 AI runs, 10GB
ENTERPRISEContact salesCustomUnlimited everything

Creating Products in Stripe

Team Plan (Monthly)

  1. Product name: Team Plan
  2. Pricing model: Standard pricing
  3. Price: $29.00 USD
  4. Billing period: Monthly
  5. Currency: USD
  6. Tax behavior: Taxable
  7. Price description: Monthly subscription

Team Plan (Yearly)

  1. Use the same product: Team Plan
  2. 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

  1. Start your frontend and backend
  2. Navigate to the pricing page
  3. Click "Upgrade to Team"
  4. Select monthly or yearly
  5. Use test card 4242 4242 4242 4242
  6. Complete checkout
  7. 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

  1. Navigate to DevelopersWebhooks
  2. Click on your webhook endpoint
  3. View Recent events tab
  4. Check for delivery status (should be 200 OK)

Troubleshooting

Webhooks Not Received

Problem: Backend not receiving webhook events

Solutions:

  1. Check webhook URL is publicly accessible (use ngrok for local testing)
  2. Verify webhook secret is correct in .env
  3. Check Stripe Dashboard → Webhooks → Recent events for errors
  4. Ensure backend endpoint is /api/v1/billing/webhook
  5. Verify your server is running and not behind a firewall

Signature Verification Failed

Problem: Error "Webhook signature verification failed"

Solutions:

  1. Ensure you're using the correct webhook secret for your environment (test vs live)
  2. Make sure you're passing the raw request body, not parsed JSON
  3. Check that stripe-signature header is present
  4. Verify Stripe API version matches (currently 2024-11-20.acacia)

Checkout Session Creation Failed

Problem: Error when creating checkout session

Solutions:

  1. Verify STRIPE_SECRET_KEY is set correctly
  2. Check that price IDs exist in Stripe Dashboard
  3. Ensure you're using the correct mode (test vs live)
  4. Verify FRONTEND_URL is set correctly for redirects
  5. Check backend logs for detailed error messages

Customer Not Found

Problem: Stripe customer doesn't exist for user

Solutions:

  1. Run the customer creation flow in stripe.service.ts
  2. Check database for stripeCustomerId field
  3. Manually create customer in Stripe Dashboard if needed
  4. Re-link customer ID to user record

Price ID Not Found

Problem: Error "No such price: 'price_...'"

Solutions:

  1. Verify price exists in Stripe Dashboard → Products
  2. Check you're using the correct environment (test vs live)
  3. Ensure STRIPE_PRICE_TEAM_MONTHLY and STRIPE_PRICE_TEAM_YEARLY are set
  4. Recreate price if it was deleted

Subscription Status Not Updating

Problem: User subscription not updating after payment

Solutions:

  1. Check webhook events are being delivered
  2. Verify webhook handler in billing.controller.ts is processing events
  3. Check database for subscription record
  4. Look for errors in backend logs
  5. Manually trigger webhook event to test

Security Best Practices

  1. Never commit API keys to version control

    • Add .env to .gitignore
    • Use environment variables on hosting platform
  2. Use webhook signature verification

    • Always verify signatures before processing webhooks
    • This prevents malicious requests
  3. Separate test and production keys

    • Never use test keys in production
    • Use different webhook endpoints for test/live
  4. Rotate API keys periodically

    • Navigate to Developers → API keys → "Roll key"
    • Update environment variables after rotation
  5. Monitor for suspicious activity

    • Enable Stripe Radar for fraud detection
    • Review failed payments regularly
  6. Use HTTPS in production

    • Stripe requires HTTPS for live webhooks
    • Obtain SSL certificate (Let's Encrypt is free)

Additional Resources


Support

For questions or issues:


Last Updated: 2025-01-15 Stripe API Version: 2024-11-20.acacia Backend Version: 1.0.0