Skip to main content

Premium System Setup Guide

This guide covers the complete setup process for the Aleteia Premium subscription system, including all external services, environment variables, and local development configuration.

Prerequisites

Before starting, ensure you have:

  • Ruby 3.3.9 or later
  • Rails 7.0 or later
  • PostgreSQL 14+
  • Redis 6+
  • Go 1.21+ (for compiling the Firebase link binary)
  • Node.js 22+ (for frontend assets)

Quick Start

# 1. Start infrastructure services
docker compose up -d postgres redis firestore

# 2. Install dependencies
bundle install

# 3. Compile Go binary
cd firebase-link && ./compile-firebase && cd ..

# 4. Configure environment
cp example.env .env
# Edit .env with your credentials

# 5. Start the application
foreman start -f Procfile.dev

Environment Variables

Complete Reference

VariableRequiredDescriptionExample
STRIPE_SECRET_KEYYesStripe API secret keysk_test_... or sk_live_...
STRIPE_WEBHOOK_SECRET_V2YesWebhook signing secretwhsec_...
GOOGLE_APPLICATION_CREDENTIALSYes*Firebase/GCP credentialsSee below
GOOGLE_PROJECT_IDAltFirebase project IDaleteia-subscriptions
GOOGLE_CLIENT_EMAILAltService account emailsvc@project.iam.gserviceaccount.com
GOOGLE_PRIVATE_KEYAltService account private key-----BEGIN PRIVATE KEY-----\n...
FIRESTORE_PROJECTNoFirestore project (defaults to Firebase project)aleteia-subscriptions
FIRESTORE_EMULATOR_HOSTNoLocal emulator hostlocalhost:8000
SENDGRID_API_KEYYesSendGrid API keySG.xxx...
FIREBASE_CONTINUE_URLNoPassword reset redirect URLhttps://aleteia.org/login

*Either GOOGLE_APPLICATION_CREDENTIALS OR the three GOOGLE_* variables must be set.

Example .env File

# Stripe Configuration
STRIPE_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET_V2=whsec_xxxxxxxxxxxxxxxxxxxxx

# Firebase/Google Cloud (Method 1: Inline JSON)
GOOGLE_APPLICATION_CREDENTIALS='{"type":"service_account","project_id":"aleteia-subscriptions","private_key_id":"abc123","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEvgIBAD...\n-----END PRIVATE KEY-----\n","client_email":"premium@aleteia-subscriptions.iam.gserviceaccount.com","client_id":"123456789","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token"}'

# OR Firebase/Google Cloud (Method 2: File path)
# GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json

# OR Firebase/Google Cloud (Method 3: Separate variables)
# GOOGLE_PROJECT_ID=aleteia-subscriptions
# GOOGLE_CLIENT_EMAIL=premium@aleteia-subscriptions.iam.gserviceaccount.com
# GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvgIBAD...\n-----END PRIVATE KEY-----\n"

# SendGrid
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxx

# Firebase Password Reset
FIREBASE_CONTINUE_URL=https://aleteia.org/login

# Development only
FIRESTORE_EMULATOR_HOST=localhost:8000

External Service Setup

1. Stripe Configuration

Create Webhook Endpoint

  1. Go to Stripe Dashboard > Developers > Webhooks
  2. Click Add endpoint
  3. Enter your webhook URL: https://your-domain.com/stripe-webhook
  4. Select events to listen for:
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
  5. Click Add endpoint
  6. Copy the Signing secret and set as STRIPE_WEBHOOK_SECRET_V2

Configure Products

  1. Go to Products in Stripe Dashboard
  2. Create a new product for each plan tier
  3. Add required metadata:
{
"platform": "premium",
"tier": "essential",
"name": "Premium Essential",
"locale": "it"
}
  1. Create a price for the product (monthly/yearly)

2. Firebase Project Setup

Create Firebase Project

  1. Go to Firebase Console
  2. Click Add project
  3. Enter project name: aleteia-subscriptions
  4. Disable Google Analytics (optional)
  5. Click Create project

Enable Authentication

  1. In Firebase Console, go to Authentication
  2. Click Get started
  3. Enable Email/Password provider
  4. Configure Authorized domains:
    • Add your production domain
    • Add localhost for development

Create Service Account

  1. Go to Project Settings > Service accounts
  2. Click Generate new private key
  3. Save the JSON file securely
  4. Use contents for GOOGLE_APPLICATION_CREDENTIALS

Configure Password Reset Template

  1. Go to Authentication > Templates
  2. Select Password reset
  3. Customize the email template
  4. Set Action URL (handled automatically by Firebase)

3. Firestore Setup

Enable Firestore

  1. In Firebase Console, go to Firestore Database
  2. Click Create database
  3. Select Start in production mode
  4. Choose a location (e.g., europe-west1)

Security Rules

Deploy these security rules:

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Users collection - only service account can write
match /users/{userId} {
// Allow read for authenticated users matching the document
allow read: if request.auth != null && request.auth.uid == userId;

// Only allow writes from server (service account)
allow write: if false;
}
}
}

Create Index

For querying users by email, create an index:

  1. Go to Firestore > Indexes
  2. Click Add index
  3. Collection: users
  4. Field: email (Ascending)

4. SendGrid Setup

Create API Key

  1. Go to SendGrid Dashboard
  2. Navigate to Settings > API Keys
  3. Click Create API Key
  4. Select Full Access or Restricted Access with:
    • Mail Send: Full Access
    • Template Engine: Read Access
  5. Copy the API key and set as SENDGRID_API_KEY

Create Dynamic Templates

Create templates following the naming convention:

Template NamePurpose
PREMIUM-WELCOME-ENEnglish welcome email
PREMIUM-WELCOME-ITItalian welcome email
PREMIUM-WELCOME-FRFrench welcome email
PREMIUM-GOODBYE-ENEnglish goodbye email
PREMIUM-GOODBYE-ITItalian goodbye email
PREMIUM-GOODBYE-FRFrench goodbye email

For template content, see Email Notifications.

Local Development Setup

Docker Services

Start required services:

docker compose up -d postgres redis firestore

The docker-compose.yml includes:

services:
postgres:
image: postgres:14
ports:
- '5432:5432'
environment:
POSTGRES_PASSWORD: postgres

redis:
image: redis:7
ports:
- '6379:6379'

firestore:
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
command: gcloud emulators firestore start --host-port=0.0.0.0:8000
ports:
- '8000:8000'
environment:
FIRESTORE_PROJECT_ID: aleteia-subscriptions

Compile Go Binary

cd firebase-link
./compile-firebase

This creates bin/firebase-link used for password reset link generation.

Stripe CLI

For local webhook testing:

# Install Stripe CLI (macOS)
brew install stripe/stripe-cli/stripe

# Login
stripe login

# Forward webhooks
stripe listen --forward-to localhost:3000/stripe-webhook

The Stripe CLI is included in Procfile.dev:

web: bin/rails server
worker: bundle exec sidekiq
stripe: stripe listen --forward-to localhost:3000/stripe-webhook

Start Development Server

foreman start -f Procfile.dev

This starts:

  • Rails server on port 3000
  • Sidekiq for background jobs
  • Stripe CLI for webhook forwarding

Production Deployment

Heroku Configuration

Set environment variables:

# Stripe
heroku config:set STRIPE_SECRET_KEY=sk_live_xxx
heroku config:set STRIPE_WEBHOOK_SECRET_V2=whsec_xxx

# Firebase (inline JSON for Heroku)
heroku config:set GOOGLE_APPLICATION_CREDENTIALS='{"type":"service_account",...}'

# SendGrid
heroku config:set SENDGRID_API_KEY=SG.xxx

# Firebase password reset
heroku config:set FIREBASE_CONTINUE_URL=https://aleteia.org/login

Verify Webhook Endpoint

After deploying:

  1. Go to Stripe Dashboard > Webhooks
  2. Select your endpoint
  3. Click Send test webhook
  4. Choose customer.subscription.created
  5. Verify successful delivery

Post-Deployment Checklist

  • Environment variables set correctly
  • Stripe webhook endpoint configured
  • Firebase project configured
  • Firestore security rules deployed
  • SendGrid templates created
  • Test subscription flow end-to-end

Troubleshooting

Common Issues

Webhook Signature Verification Failed

Symptom: Stripe::SignatureVerificationError

Solutions:

  1. Verify STRIPE_WEBHOOK_SECRET_V2 matches Stripe Dashboard
  2. Check webhook URL is correct
  3. Ensure raw request body is not modified by middleware

Firebase Authentication Failed

Symptom: Google::Auth::CredentialsError

Solutions:

  1. Check GOOGLE_APPLICATION_CREDENTIALS format
  2. Verify service account has required permissions
  3. For inline JSON, ensure proper escaping of newlines in private key

Firestore Connection Failed

Symptom: GRPC::Unavailable

Solutions:

  1. Check FIRESTORE_EMULATOR_HOST for local development
  2. Verify Firestore is enabled in Firebase Console
  3. Check service account has Firestore access

Symptom: TTY::Command::ExitError

Solutions:

  1. Verify bin/firebase-link exists and is executable
  2. Check Go binary was compiled correctly
  3. Verify credentials can access Firebase Auth

Debug Mode

Enable verbose logging:

# Rails console
Rails.logger.level = :debug

# Or in .env
LOG_LEVEL=debug

Health Checks

Verify services are running:

# Rails console

# Check Stripe
Stripe::Account.retrieve
# => #<Stripe::Account id=acct_xxx>

# Check Firebase
firebase = Firebase::Admin::Auth.new
firebase.get_user_by_email('test@example.com')
# => #<Firebase::Admin::UserRecord> or raises NotFound

# Check Firestore
firestore = Google::Cloud::Firestore.new
firestore.col('users').limit(1).get
# => #<Google::Cloud::Firestore::QuerySnapshot>

# Check SendGrid
client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
response = client.client.templates.get
# => #<SendGrid::Response>

Security Checklist

  • All credentials stored in environment variables
  • .env file in .gitignore
  • Stripe webhook signature verification enabled
  • Firebase security rules restrict access
  • Service account has minimal required permissions
  • Production uses HTTPS
  • Sensitive data not logged