Complete reference for all environment variables required by the Shazan platform.
Environment variables are stored in the .env file in the project root. Never commit this file to version control. Copy .env.example and fill in your actual values.
DATABASE_URL="postgresql://username:password@localhost:5434/shazan?schema=public"Format: postgresql://[user]:[password]@[host]:[port]/[database]?schema=[schema]
Components:
user: PostgreSQL usernamepassword: PostgreSQL passwordhost: Database server hostname (localhost for local development)port: PostgreSQL port (default 5432, example uses 5434)database: Database name (e.g., "shazan")schema: Database schema (default: "public")
Example:
DATABASE_URL="postgresql://bornali:quadir@localhost:5434/shazan?schema=public"NODE_ENV="production"Values:
development- Local development with debug loggingproduction- Production deployment with optimizationstest- Test environment
PORT=3000The port the API server will listen on.
JWT_SECRET="BY-BENCH-MARKTER-PLACE-NEST-BACKEND"Secret key for JWT token signing and verification. Use a strong, random string in production.
Requirements:
- Minimum 32 characters for production
- Use cryptographically secure random string
- Never share or commit to version control
Generate a secure key:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"MAIL_USER="shazan.softvence@gmail.com"Gmail account for sending emails (password reset, notifications, etc.).
MAIL_PASS="qs-f zonx xhry tpj-"Gmail App Password (NOT your regular Gmail password).
How to generate:
- Enable 2-Factor Authentication on Gmail
- Go to https://myaccount.google.com/apppasswords
- Select "Mail" and "Windows Computer"
- Copy the generated 16-character password
- Format with spaces:
xxxx xxxx xxxx xxxx
Important: This is NOT your Gmail password. Use the generated App Password only.
STRIPE_SECRET_KEY="sk_test_51234567890abcdefghijklmnop"Secret API key for server-side Stripe operations. Starts with sk_test_ (testing) or sk_live_ (production).
Where to find:
- Log in to Stripe Dashboard
- Navigate to Developers → API Keys
- Copy the "Secret Key"
Keys:
- Test Mode: Use
sk_test_*for development (no real charges) - Live Mode: Use
sk_live_*for production (processes real payments)
STRIPE_WEBHOOK_SECRET="whsec_1234567890abcdefghijklmnop"Webhook signing secret for verifying Stripe webhook events. Starts with whsec_.
Where to find:
- Developers → Webhooks
- Click your endpoint
- Copy "Signing secret"
Setup Webhook Endpoint:
- Go to Developers → Webhooks → Add endpoint
- Endpoint URL:
https://yourdomain.com/webhooks/stripe - Select events:
payment_intent.succeeded,payment_intent.failed - Copy signing secret to
STRIPE_WEBHOOK_SECRET
CLOUDINARY_NAME="your_cloud_name"Your Cloudinary account identifier.
CLOUDINARY_API_KEY="123456789012345"API key for authenticating Cloudinary requests.
CLOUDINARY_API_SECRET="abcdefghijklmnop1234567890"Secret key for signing Cloudinary requests. Keep this secure (server-side only).
Where to find:
- Log in to Cloudinary Dashboard
- Go to Settings → API Keys
- Copy:
Cloud Name,API Key,API Secret
Important: Never expose API_SECRET in client-side code. Use server-side only.
PLATFORM_FEE_PERCENT=10Platform commission as a percentage (0-100). Applied to all transactions.
Example:
- Transaction: $100
- Platform fee (10%): $10
- Seller receives: $90
FRONTEND_URL="https://shazan.example.com"Frontend application URL. Used for:
- Email verification links
- Password reset links
- CORS configuration
- Redirects
Format: Complete URL with protocol
Examples:
# Development
FRONTEND_URL="http://localhost:3000"
# Production
FRONTEND_URL="https://shazan.example.com"# Database
DATABASE_URL="postgresql://bornali:quadir@localhost:5434/shazan?schema=public"
# Server
PORT=3000
NODE_ENV="production"
# Authentication
JWT_SECRET="BY-BENCH-MARKTER-PLACE-NEST-BACKEND"
# Email (Gmail SMTP)
MAIL_USER="shazan.softvence@gmail.com"
MAIL_PASS="qs-f zonx xhry tpj-"
# Stripe
STRIPE_SECRET_KEY="sk_test_51234567890abcdefghijklmnop"
STRIPE_WEBHOOK_SECRET="whsec_1234567890abcdefghijklmnop"
# Cloudinary
CLOUDINARY_NAME="your_cloud_name"
CLOUDINARY_API_KEY="123456789012345"
CLOUDINARY_API_SECRET="abcdefghijklmnop1234567890"
# Platform
PLATFORM_FEE_PERCENT=10
FRONTEND_URL="https://shazan.example.com"NODE_ENV="development"
DATABASE_URL="postgresql://user:pass@localhost:5434/shazan_dev?schema=public"
PORT=3000
STRIPE_SECRET_KEY="sk_test_..." # Test key (no real charges)
FRONTEND_URL="http://localhost:3000"Characteristics:
- Test keys for external services (Stripe, Cloudinary)
- Local database
- Debug logging enabled
- Relaxed security settings
NODE_ENV="production"
DATABASE_URL="postgresql://user:pass@prod-server:5432/shazan?schema=public"
PORT=3000
STRIPE_SECRET_KEY="sk_live_..." # Live key (real charges)
FRONTEND_URL="https://shazan.example.com"Characteristics:
- Live API keys
- Remote database with backups
- Optimized performance
- Enhanced security
- Monitoring enabled
-
Never commit .env to version control
- Add
.envto.gitignore - Use
.env.examplewith placeholder values
- Add
-
Use strong secrets
- JWT_SECRET: minimum 32 characters, random
- Generate with:
openssl rand -hex 32
-
Rotate secrets regularly
- Especially API keys and secrets
- Update in .env and service provider
-
Restrict permissions
- .env file should be readable by application only
- Chmod 600 on Unix systems
-
Use environment-specific keys
- Separate test and production API keys
- Never use production keys in development
-
Monitor secret access
- Audit logs for API key usage
- Alert on suspicious activity
- Revoke compromised keys immediately
- Ensure
.envexists in project root - Check DATABASE_URL variable is present
- Verify PostgreSQL connection string format
- Verify
STRIPE_SECRET_KEYstarts withsk_test_orsk_live_ - Check key hasn't been rotated/regenerated
- Confirm environment matches (test vs live)
- Verify
CLOUDINARY_NAME,CLOUDINARY_API_KEY,CLOUDINARY_API_SECRET - Check keys haven't expired or been revoked
- Ensure no extra whitespace in values
- Verify Gmail app-specific password is used (not regular password)
- Enable 2-Factor Authentication on Gmail account
- Check Gmail account hasn't been locked
- Verify MAIL_USER matches account email
- Ensure JWT_SECRET hasn't changed between requests
- Check token hasn't expired
- Verify secret matches between signing and verification
| Variable | Type | Required | Example |
|---|---|---|---|
| DATABASE_URL | String | Yes | postgresql://user:pass@localhost:5434/shazan |
| NODE_ENV | String | Yes | production |
| PORT | Number | No (Default: 3000) | 3000 |
| JWT_SECRET | String | Yes | BY-BENCH-MARKTER-PLACE-NEST-BACKEND |
| MAIL_USER | String | Yes | shazan.softvence@gmail.com |
| MAIL_PASS | String | Yes | qs-f zonx xhry tpj- |
| STRIPE_SECRET_KEY | String | Yes | sk_test_... |
| STRIPE_WEBHOOK_SECRET | String | Yes | whsec_... |
| CLOUDINARY_NAME | String | Yes | your_cloud_name |
| CLOUDINARY_API_KEY | String | Yes | 123456789012345 |
| CLOUDINARY_API_SECRET | String | Yes | abcdefghijklmnop1234567890 |
| PLATFORM_FEE_PERCENT | Number | Yes | 10 |
| FRONTEND_URL | String | Yes | https://shazan.example.com |
For setup instructions, see SETUP.md