Skip to main content

Environment Variables Reference

This page provides a complete reference for all environment variables used across the BookWish platform.

Backend Environment Variables

The backend uses a .env file in the backend/ directory. Copy .env.example to .env and configure.

Core Infrastructure

Database

# PostgreSQL connection string (Supabase or local)
DATABASE_URL=postgresql://postgres:[PASSWORD]@db.[PROJECT_REF].supabase.co:5432/postgres

Format: postgresql://[user]:[password]@[host]:[port]/[database]

Required: Yes Example (local): postgresql://postgres:password@localhost:5432/bookwish Example (Supabase): postgresql://postgres.abc123:password@aws-0-us-east-1.pooler.supabase.com:5432/postgres

Redis

# Redis connection URL (local or Railway)
REDIS_URL=redis://localhost:6379

Required: Yes Default: redis://localhost:6379 Used for: Rate limiting, caching, Bull job queues

Server Configuration

# Server port
PORT=3000

# Node environment
NODE_ENV=development # development | production | test

PORT Default: 3000 NODE_ENV Default: development

Authentication & Security

JWT Secrets

# JWT signing secret (minimum 32 characters)
JWT_SECRET=your_secure_random_string_at_least_32_chars

# JWT refresh token secret (minimum 32 characters)
JWT_REFRESH_SECRET=another_secure_random_string_at_least_32_chars

Required: Yes Generate with: openssl rand -hex 32 Validation: Must be at least 32 characters each

Encryption

# Encryption key for OAuth tokens (base64 encoded, 32 bytes)
ENCRYPTION_KEY=your_base64_encryption_key

Required: For stores using Square OAuth Generate with: openssl rand -base64 32 Used for: Encrypting Square OAuth tokens in database

Book Data APIs

ISBNdb

# ISBNdb API key for book metadata
ISBNDB_API_KEY=your_isbndb_api_key

Required: Yes Get from: https://isbndb.com/apidocs/v2 Used for: Looking up book data by ISBN

Google Books API

# Google Books API key
GOOGLE_BOOKS_API_KEY=your_google_books_api_key

Required: Yes Get from: Google Cloud Console Used for: Fallback book data, cover images

Payment & Commerce

Stripe

# Stripe API keys
STRIPE_SECRET_KEY=sk_live_xxx
STRIPE_PUBLISHABLE_KEY=pk_live_xxx # Not used in backend
STRIPE_WEBHOOK_SECRET=whsec_xxx

Required: For payment processing Get from: Stripe Dashboard > API Keys

Stripe Product Price IDs:

# Premium Subscriptions (Web checkout - mobile uses RevenueCat)
STRIPE_PRICE_PREMIUM_MONTHLY=price_... # $4.99/month
STRIPE_PRICE_PREMIUM_YEARLY=price_... # $29.99/year
STRIPE_PRICE_PREMIUM_LIFETIME=price_... # $79.99 one-time

# Bookstore Subscriptions (B2B - web only)
STRIPE_PRODUCT_BOOKSTORE=price_... # $49.99/month
STRIPE_PRODUCT_CUSTOM_DOMAIN=price_... # $9.99/month add-on

Required: For subscriptions Get from: Stripe Dashboard > Products (create products first)

Square

# Square OAuth integration
SQUARE_APP_ID=sq0idp-xxx
SQUARE_APP_SECRET=sq0csp-xxx
SQUARE_ENVIRONMENT=production # sandbox | production
SQUARE_WEBHOOK_SIGNATURE_KEY=your_webhook_signature_key

Required: For stores using Square POS integration Get from: Square Developer Dashboard

RevenueCat

# RevenueCat for mobile subscriptions
REVENUECAT_API_KEY=your_revenuecat_api_key
REVENUECAT_WEBHOOK_SECRET=your_webhook_secret

Required: For mobile in-app purchases Get from: RevenueCat Dashboard

Fulfillment & Shipping

EasyPost

# EasyPost for shipping labels
EASYPOST_API_KEY=your_easypost_api_key

Required: For shipping functionality Get from: EasyPost Dashboard

BooksRun

# BooksRun for trade-in quotes
BOOKSRUN_API_KEY=your_booksrun_api_key

Required: For trade-in feature Get from: BooksRun API

Ingram Content Group

# Ingram wholesaler integration (future)
INGRAM_API_URL=https://api.ingramcontent.com
INGRAM_USERNAME=your_ingram_username
INGRAM_PASSWORD=your_ingram_password
INGRAM_SAN=your_standard_address_number

Required: No (not yet implemented) Used for: Direct book ordering from wholesaler

Warehouse Configuration

# BookWish warehouse address (for direct fulfillment)
WAREHOUSE_NAME=BookWish Fulfillment
WAREHOUSE_STREET1=123 Distribution Way
WAREHOUSE_CITY=Columbus
WAREHOUSE_STATE=OH
WAREHOUSE_ZIP=43215
WAREHOUSE_COUNTRY=US

Required: For direct fulfillment orders Defaults provided in code

Firebase (Push Notifications)

# Firebase Admin SDK credentials
FIREBASE_PROJECT_ID=your_project_id
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYour key here\n-----END PRIVATE KEY-----\n"
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxxx@your-project.iam.gserviceaccount.com

Required: For push notifications Get from: Firebase Console > Project Settings > Service Accounts > Generate New Private Key

Note: The private key should include \n for newlines in the .env file. The code will replace \\n with actual newlines.

Email (AWS SES)

# AWS Simple Email Service
AWS_REGION=us-east-1
AWS_SES_ACCESS_KEY_ID=your_access_key_id
AWS_SES_SECRET_ACCESS_KEY=your_secret_access_key
AWS_SES_EMAIL_SOURCE=noreply@bookwish.io

# BookWish operations email (receives order notifications)
BOOKWISH_OPS_EMAIL=orders@bookwish.io

Required: For sending email notifications Get from: AWS Console > IAM > Create Access Key with SES permissions

Store Websites

# Store website base URL (bookwish.shop deployment)
STORE_WEBSITE_URL=https://bookwish.shop

Required: For Stripe checkout redirects on store websites Default: https://bookwish.shop

Economics Configuration

# Ingram wholesale cost percentage
INGRAM_COST_PERCENTAGE=60 # 60% of retail price

# Stripe payment processing fees
STRIPE_FEE_PERCENTAGE=2.9 # 2.9%
STRIPE_FEE_FIXED_CENTS=30 # $0.30

Required: No (defaults provided) Used for: Revenue calculations and economics modeling

Web Project Environment Variables

The Next.js customer-facing website uses .env.local in the web/ directory.

# Backend API URL
NEXT_PUBLIC_API_URL=https://bookwishmonorepo-production.up.railway.app/v1

# Main app URL
NEXT_PUBLIC_APP_URL=https://www.bookwish.io

# Site URL (this project)
NEXT_PUBLIC_SITE_URL=https://wishlist.bookwish.io

# Stripe (for web checkout)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_xxx
STRIPE_SECRET_KEY=sk_live_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx

Note: Variables prefixed with NEXT_PUBLIC_ are exposed to the browser.

Stores Project Environment Variables

The Next.js bookstore websites use .env.local in the stores/ directory.

# Backend API URL
NEXT_PUBLIC_API_URL=https://bookwishmonorepo-production.up.railway.app

# Main BookWish app URL
NEXT_PUBLIC_MAIN_APP_URL=https://bookwish.io

# Stores base URL (this project)
NEXT_PUBLIC_STORES_URL=https://bookwish.shop

# Stripe Bookstore subscription price ID
NEXT_PUBLIC_STRIPE_BOOKSTORE_PRICE_ID=price_...

Flutter App Configuration

The Flutter app uses Firebase for configuration. Environment-specific values are configured in:

  • app/lib/firebase_options.dart (generated from Firebase console)
  • app/ios/Runner/GoogleService-Info.plist
  • app/android/app/google-services.json

API URL is hardcoded in the app or configured via build flavors (future enhancement).

Security Best Practices

Never Commit Secrets

Add to .gitignore:

.env
.env.local
.env.*.local
GoogleService-Info.plist
google-services.json

Use Strong Secrets

Generate secure random strings:

# For JWT secrets (hex encoding)
openssl rand -hex 32

# For encryption keys (base64 encoding)
openssl rand -base64 32

Environment-Specific Configuration

Use different values for:

  • Development: Local services, test API keys
  • Staging: Sandbox/test mode for payment providers
  • Production: Production API keys, live mode

Validate Required Variables

The backend uses Zod schema validation (see backend/src/config/env.ts) to ensure all required variables are present at startup.

Development vs. Production

Development Defaults

NODE_ENV=development
PORT=3000
REDIS_URL=redis://localhost:6379
DATABASE_URL=postgresql://postgres:password@localhost:5432/bookwish
SQUARE_ENVIRONMENT=sandbox

Production Configuration

NODE_ENV=production
# Use hosted services (Supabase, Railway Redis)
# Use production API keys for Stripe, Square, etc.
# Enable all monitoring and error tracking

Troubleshooting

Missing Required Variables

If you see validation errors on startup:

Environment validation failed:
JWT_SECRET: String must contain at least 32 character(s)

Check that all required variables are set in .env and meet validation requirements.

Firebase Private Key Issues

If push notifications fail with authentication errors:

  • Ensure the private key includes literal \n characters in the .env file
  • Verify the service account has Firebase Cloud Messaging permissions
  • Check that the project ID and client email match your Firebase project

Database Connection Issues

Can't connect to database:

  • Verify DATABASE_URL format
  • Check network access (Supabase IP allowlisting)
  • Test with: psql $DATABASE_URL

Next Steps

After configuring environment variables: