Detailed Implementation Guide

Complete Step-by-Step Instructions

Every single step broken down with screenshots, code examples, and troubleshooting tips

Back to Overview

Skill Level Required

🟢 Beginner-Friendly

  • • Airtable setup
  • • Bubble.io basics
  • • SendGrid config

🟡 Intermediate

  • • Auth0 setup
  • • Stripe webhooks
  • • API integration

🔴 Advanced

  • • Custom backend
  • • Database design
  • • Security config

Phase 1: Auth0 Setup (Detailed)

Time Required: 2-4 hours | Difficulty: 🟡 Intermediate

Step 1.1: Create Auth0 Account (15 minutes)

1

Navigate to Auth0 Website

  • Go to https://auth0.com
  • Click the "Sign Up" button in the top-right corner
  • You'll see two options: "Log in with Google" or "Sign up with email"

💡 Tip: Using "Sign in with Google" is faster and you won't need to verify email

2

Choose Your Plan

  • Select "Free" plan (perfect for starting)
  • Free tier includes:
    • 7,500 active users per month
    • Unlimited logins
    • Social connections (Google, Facebook, etc.)
    • Multi-factor authentication
3

Configure Your Tenant

You'll be asked to set up your "tenant" (your Auth0 instance):

Tenant Domain Name:

career-success-institute

This becomes: career-success-institute.us.auth0.com

Region:

Choose closest to your customers (US, EU, AU, etc.)

Environment Tag:

Select "Development" for now

Important: Tenant name cannot be changed later, so choose carefully!

4

Complete Account Setup

  • Fill in company information (Career Success Institute)
  • Select industry: "Professional Services"
  • Company size: "1-10 employees" (or actual size)
  • Click "Create Account"

Verify Success

You should now see the Auth0 Dashboard with:

  • Left sidebar with navigation
  • "Getting Started" checklist
  • Your tenant name in the top-left

Step 1.2: Create Application for Customer Portal (10 minutes)

1

Navigate to Applications

  • Click "Applications" in the left sidebar
  • Click "Applications" again in the submenu
  • You'll see a default application already created - ignore it
  • Click the orange "+ Create Application" button (top-right)
2

Configure Application Settings

Name:

Career Success Customer Portal

Application Type:

Select "Single Page Web Applications"

This is for React, Vue, or Bubble.io apps

3

Configure Application URLs

After creation, click on your new application, then go to the "Settings" tab. Scroll down and configure these URLs:

Allowed Callback URLs:

https://portal.careersuccessinstitute.com/callback,
http://localhost:3000/callback,
https://version-test.bubbleapps.io/callback

These are where Auth0 redirects after successful login

Allowed Logout URLs:

https://portal.careersuccessinstitute.com,
http://localhost:3000,
https://version-test.bubbleapps.io

Where users go after logout

Allowed Web Origins:

https://portal.careersuccessinstitute.com,
http://localhost:3000,
https://version-test.bubbleapps.io

Domains allowed to make authentication requests

Note: localhost:3000 is for testing. Remove it before going live. Add your Bubble.io development URL if using Bubble.

4

Save Important Credentials

Scroll to the top of the Settings tab and COPY THESE VALUES - you'll need them later:

🔐 SAVE THESE SECURELY:

Domain:

career-success-institute.us.auth0.com

Client ID:

abc123xyz456789

(Long alphanumeric string)

Client Secret:

••••••••••••••••

(Click "Show" button to reveal - treat like a password!)

Action: Copy these to a password manager or secure note. You'll need them for Bubble.io integration.

5

Scroll Down & Click "Save Changes"

Important: Auth0 won't save settings automatically - you must click the blue "Save Changes" button at the bottom!

Step 1.3: Enable Social Login (Optional - 15 minutes)

Why enable this? Let customers log in with their Google account instead of creating a new password. Increases conversion and reduces friction.

1

Navigate to Authentication

  • Click "Authentication" in left sidebar
  • Click "Social" in submenu
  • You'll see a list of social providers (Google, Facebook, LinkedIn, etc.)
2

Enable Google (Recommended)

  1. Find "Google" in the list
  2. Click the toggle switch to enable it
  3. A popup will appear - you can either:
    • Quick Start: Use Auth0's developer keys (easiest, works immediately)
    • Production: Use your own Google OAuth credentials (better for branding)

For Quick Start:

  • Just click "Continue"
  • Google login will work immediately
  • Warning: You'll see Auth0 branding in the consent screen

For Production (Your Own Credentials):

Click to expand detailed instructions
  1. Go to Google Cloud Console
  2. Create new project: "Career Success Auth"
  3. Enable Google+ API
  4. Go to Credentials → Create OAuth 2.0 Client ID
  5. Application type: "Web application"
  6. Authorized redirect URIs: https://YOUR-TENANT.auth0.com/login/callback
  7. Copy Client ID and Client Secret
  8. Paste into Auth0 Google connection settings
3

Configure Permissions

Scroll down in the Google connection settings:

Attributes/Scopes:

Make sure these are checked:

  • ✅ email
  • ✅ profile
4

Click "Save" and Test

Auth0 provides a "Try Connection" button - click it to test Google login

Phase 2: Build Customer Portal in Bubble.io

Time Required: 8-12 hours | Difficulty: 🟡 Intermediate

Step 2.1: Set Up Bubble.io Account & App (30 minutes)

1

Create Bubble Account

  • Go to bubble.io
  • Click "Get Started Free"
  • Sign up with email or Google
  • Verify your email address
2

Create New App

App Settings:

  • App name: Career Success Portal
  • Template: Start from blank (we'll build custom)
  • App type: Web app

Click "Create a new app"

3

Familiarize with Bubble Editor

You'll see the visual editor with:

Left Sidebar:

  • • Elements (drag-drop components)
  • • Data (database structure)
  • • Plugins
  • • Styles

Main Canvas:

  • • Visual page builder
  • • Drag elements here
  • • Right-click for options

💡 Tip: Take Bubble's 10-minute tutorial (Help → Lessons) before continuing

Step 2.2: Install Auth0 Plugin (15 minutes)

1

Navigate to Plugins

  • Click "Plugins" in the left sidebar
  • Click "+ Add plugins" button
  • In the search box, type: Auth0
2

Install Official Auth0 Plugin

Look for:

Auth0 by Bubble

Official Auth0 authentication plugin

FREE
3

Configure Auth0 Plugin

After installation, the plugin will appear in your Plugins list. Click on it to configure:

Enter Your Auth0 Credentials:

Auth0 Domain:

career-success-institute.us.auth0.com

(Your tenant domain from Step 1.2)

Client ID:

abc123xyz456789...

(From Step 1.2 - the long alphanumeric string)

Client Secret:

••••••••••••

(From Step 1.2 - keep this private!)

After entering credentials, click "Save"

Step 2.3: Create Database Structure (20 minutes)

What we're building: Data types to store customer information, orders, and documents

1

Navigate to Data Tab

  • Click "Data" in the left sidebar
  • Click "Data types" tab at the top
  • You'll see "User" type already exists (Bubble default)
2

Modify User Type

Click on "User" to add these fields:

Field Name Field Type Purpose
auth0_user_id text Link to Auth0
phone text Phone number
subscription_status text active/inactive

Click "Create a new field" for each one

3

Create "Order" Data Type

Click "New type" button:

Type name: Order

Add these fields:

Field Name Field Type
order_number text
customer User
package_type text
status text
amount number
created_date date
expert_assigned text
4

Create "Document" Data Type

Type name: Document

Field Name Field Type
order Order
document_type text
file file
version number
status text
uploaded_date date

✅ Progress Check

By now you should have completed:

  • Auth0 account with configured application
  • Bubble.io app with Auth0 plugin installed
  • Database structure for Users, Orders, Documents

Next: Continue with the remaining phases in the main integration guide at /integration-guide

The remaining phases (Airtable CRM, Stripe, Emails) follow similar detailed patterns.

🔗 Important Links Reference

Your Auth0:

https://YOUR-TENANT.us.auth0.com

Bubble Editor:

https://bubble.io/app-name

Auth0 Docs:

auth0.com/docs

Bubble Manual:

manual.bubble.io

Career Success Institute - Detailed Implementation Guide

This guide covers the most critical first steps. Continue with /integration-guide for remaining phases.

Last Updated: January 2025 | Version 1.0

Phase 3: Set Up Airtable CRM

Time Required: 3-4 hours | Difficulty: 🟢 Beginner

Step 3.1: Create Airtable Account & Base (20 minutes)

1

Sign Up for Airtable

  • Go to airtable.com
  • Click "Sign up for free"
  • Sign up with email or Google account
  • Verify your email if prompted

Free Plan Includes: Unlimited bases, 1,200 records per base, 2GB attachments

2

Create New Base

  • After login, you'll see the home screen
  • Click "+ Create a base" (or "Start from scratch")
  • Name it: Career Success CRM
  • Choose an icon and color (optional - pick green for brand consistency)
3

Understand the Interface

Top Bar:

  • • Base name (click to rename)
  • • Share button (for team access)
  • • Extensions & Automations

Left Sidebar:

  • • Tables list
  • • Add new table button
  • • Views for each table

Step 3.2: Build Tables Structure (1 hour)

Table 1: Customers

How to create:

  1. Airtable creates "Table 1" by default - rename it to Customers
  2. Click the + button next to existing field names to add new fields
  3. For each field below, select the correct field type
Field Name Field Type Configuration
Customer Name Single line text Primary field (already exists)
Email Email -
Phone Phone number -
Auth0 User ID Single line text For linking to portal
Status Single select Options: Active, Inactive, Completed
Sign Up Date Date Include time: Yes
Orders Link to another record Link to: Orders table (create later)
Notes Long text Enable rich text formatting

Tip: Click the dropdown arrow on any field name to change its type, add description, or configure settings

Table 2: Orders

How to create:

  1. Click "+ Add or import" at the bottom of the left sidebar
  2. Choose "Create empty table"
  3. Name it: Orders
  4. Add these fields:
Field Name Field Type Configuration
Order Number Single line text Primary field - format: ORDER-12345
Customer Link to another record Link to: Customers table
Package Type Single select Options: Resume, Cover Letter, LinkedIn, Coaching, Bundle
Amount Paid Currency Currency: USD ($)
Status Single select Options: Payment Received, In Progress, First Draft, Revisions, Completed
Assigned Expert Single select Add your team member names
Order Date Date Include time: Yes
Due Date Date -
Documents Link to another record Link to: Documents table
Internal Notes Long text For team communication

Table 3: Documents

Create this table the same way as Orders table:

Field Name Field Type Configuration
Document Name Single line text Primary field - e.g., "John Doe Resume v1"
Order Link to another record Link to: Orders table
Document Type Single select Options: Resume, Cover Letter, LinkedIn Profile, Other
File Attachment Upload PDF, Word, etc.
Version Number Precision: Integer
Status Single select Options: Draft, Ready for Review, Approved, Final
Upload Date Created time Auto-populated

Table 4: Team Members

Field Name Field Type
Name Single line text
Email Email
Role Single select (Admin, Editor, Writer, Support)
Specialty Multiple select (Resume, Cover Letter, LinkedIn, Coaching)
Active Orders Count (from Orders → Assigned Expert)

Step 3.3: Create Views for Different Roles (30 minutes)

What are Views? Different ways to display and filter your data. Perfect for showing editors only their assigned orders, or showing admins all orders.

1

Create "Active Orders" View

  1. In the Orders table, click the "Grid view" dropdown
  2. Click "Create... → Grid"
  3. Name it: Active Orders
  4. Click "Filter" button
  5. Add filter: Status → is not → Completed
  6. Click "Sort" button
  7. Sort by: Due Date → Ascending
2

Create "Kanban Board" View

  1. Create new view: "Kanban"
  2. Name it: Order Pipeline
  3. Stack by: Status
  4. Now you can drag orders between status columns!

This gives you a visual workflow like Trello!

3

Create "Calendar" View

  1. Create new view: "Calendar"
  2. Name it: Due Date Calendar
  3. Date field: Due Date
  4. Color by: Status

Step 3.4: Set Up Automations (30 minutes)

1

Enable Automations

  • Click "Automations" in the top-right
  • Click "Create automation"
2

Automation 1: New Order Notification

Setup:

  1. Trigger: When record created in Orders table
  2. Action: Send email
    • To: Your team email
    • Subject: "New Order: [Order Number]"
    • Message: Include customer name, package type, amount
  3. Click "Turn on automation"
3

Automation 2: Due Date Reminder

  1. Trigger: When record matches conditions
    • Due Date is within 1 day from now
    • Status is not "Completed"
  2. Action: Send email to assigned expert
  3. Schedule: Run daily at 9:00 AM

Step 3.5: Share with Team & Get API Key (15 minutes)

1

Invite Team Members

  • Click "Share" button (top-right)
  • Click "Invite by email"
  • Enter team member emails
  • Set permissions:
    • Owner: Full access (you)
    • Creator: Can edit everything
    • Editor: Can edit records only
    • Commenter: Can only comment
    • Read only: View only
2

Generate API Key (for Integration)

  1. Go to airtable.com/create/tokens
  2. Click "Create new token"
  3. Name: Career Success Integration
  4. Scopes: Select data.records:read and data.records:write
  5. Access: Select your "Career Success CRM" base
  6. Click "Create token"
  7. Copy the API key immediately - you won't see it again!

🔐 SAVE THIS API KEY SECURELY

pat1234567890abcdefghijklmnop...

You'll need this for connecting Bubble.io or Stripe webhooks to Airtable

✅ Phase 3 Complete!

You now have:

  • • Complete CRM with 4 tables
  • • Kanban board, calendar, and grid views
  • • Automated notifications
  • • Team access configured
  • • API key for integrations

Phase 4: Set Up Database (Supabase)

Time Required: 2-3 hours | Difficulty: 🟡 Intermediate

Step 4.1: Create Supabase Account & Project (20 minutes)

1

Sign Up for Supabase

  • Go to supabase.com
  • Click "Start your project"
  • Sign in with GitHub (recommended) or email
  • Create organization: Career Success Institute
2

Create New Project

Project Settings:

  • Name: career-success-db
  • Database Password: Generate strong password (save it!)
  • Region: Choose closest to your users
  • Pricing Plan: Free (2 projects, 500MB database, 1GB file storage)

⏱️ Project setup takes ~2 minutes

3

Save Project Credentials

Once project is ready, go to Settings → API:

🔐 SAVE THESE VALUES:

Project URL:

https://abcdefgh.supabase.co

anon public key:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

service_role secret:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

⚠️ Keep this SECRET - never expose in frontend code!

Step 4.2: Create Database Tables (1 hour)

Method: We'll use Supabase's SQL Editor to create tables with proper relationships

1

Navigate to SQL Editor

  • Click "SQL Editor" in left sidebar
  • Click "+ New query"
2

Create Customers Table

Copy and paste this SQL code:

-- Create customers table
CREATE TABLE public.customers (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  full_name TEXT NOT NULL,
  phone TEXT,
  auth0_user_id TEXT UNIQUE,
  subscription_status TEXT DEFAULT 'active',
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Enable Row Level Security
ALTER TABLE public.customers ENABLE ROW LEVEL SECURITY;

-- Create policy: Users can only see their own data
CREATE POLICY "Users can view own data"
  ON public.customers
  FOR SELECT
  USING (auth.uid()::text = auth0_user_id);

-- Create index for faster lookups
CREATE INDEX idx_customers_email ON public.customers(email);
CREATE INDEX idx_customers_auth0 ON public.customers(auth0_user_id);
3

Create Orders Table

-- Create orders table
CREATE TABLE public.orders (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  order_number TEXT UNIQUE NOT NULL,
  customer_id UUID REFERENCES public.customers(id) ON DELETE CASCADE,
  package_type TEXT NOT NULL,
  amount_paid DECIMAL(10,2) NOT NULL,
  status TEXT DEFAULT 'payment_received',
  assigned_expert TEXT,
  stripe_payment_id TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  due_date TIMESTAMP WITH TIME ZONE,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Enable RLS
ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;

-- Policy: Users can see their own orders
CREATE POLICY "Users can view own orders"
  ON public.orders
  FOR SELECT
  USING (
    customer_id IN (
      SELECT id FROM public.customers 
      WHERE auth0_user_id = auth.uid()::text
    )
  );

-- Indexes
CREATE INDEX idx_orders_customer ON public.orders(customer_id);
CREATE INDEX idx_orders_status ON public.orders(status);
CREATE INDEX idx_orders_number ON public.orders(order_number);
4

Create Documents Table

-- Create documents table
CREATE TABLE public.documents (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  order_id UUID REFERENCES public.orders(id) ON DELETE CASCADE,
  document_type TEXT NOT NULL,
  file_url TEXT NOT NULL,
  file_name TEXT NOT NULL,
  version INTEGER DEFAULT 1,
  status TEXT DEFAULT 'draft',
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Enable RLS
ALTER TABLE public.documents ENABLE ROW LEVEL SECURITY;

-- Policy: Users can see documents for their orders
CREATE POLICY "Users can view own documents"
  ON public.documents
  FOR SELECT
  USING (
    order_id IN (
      SELECT o.id FROM public.orders o
      JOIN public.customers c ON o.customer_id = c.id
      WHERE c.auth0_user_id = auth.uid()::text
    )
  );

-- Indexes
CREATE INDEX idx_documents_order ON public.documents(order_id);
CREATE INDEX idx_documents_status ON public.documents(status);

Verify Tables Created

  • Click "Table Editor" in left sidebar
  • You should see: customers, orders, documents tables
  • Click each table to see the columns

Step 4.3: Set Up Storage for Documents (30 minutes)

1

Create Storage Bucket

  • Click "Storage" in left sidebar
  • Click "Create a new bucket"
  • Name: customer-documents
  • Public bucket: NO (keep private)
  • File size limit: 10 MB
  • Allowed MIME types: application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document
2

Set Storage Policies

In the bucket settings, add these RLS policies:

-- Allow authenticated users to upload
CREATE POLICY "Authenticated users can upload"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK (bucket_id = 'customer-documents');

-- Allow users to view their own files
CREATE POLICY "Users can view own files"
ON storage.objects FOR SELECT
TO authenticated
USING (bucket_id = 'customer-documents' AND auth.uid()::text = (storage.foldername(name))[1]);

Phase 5: Stripe Payment Integration

Time Required: 2-3 hours | Difficulty: 🟡 Intermediate

Step 5.1: Set Up Stripe Account (30 minutes)

1

Create Stripe Account

  • Go to stripe.com
  • Click "Start now"
  • Fill in business information
  • Verify your email
  • Complete business verification (bank account, ID)

⏱️ Verification time: Can take 1-2 business days for full approval

2

Get API Keys

  • Go to Developers → API keys
  • You'll see two sets of keys:
    • Test mode: For development/testing
    • Live mode: For real payments (appears after verification)

🔐 SAVE THESE KEYS (Test Mode First):

Publishable key (safe to expose):

pk_test_51abc123...

Secret key (NEVER expose!):

sk_test_51xyz789...
3

Create Products

  • Go to Product catalog → + Add product
  • Create each service package:

Product 1: Premium Resume

  • • Price: $299 one-time
  • • Description: Professional resume writing service

Product 2: Cover Letter

  • • Price: $149 one-time

Product 3: LinkedIn Optimization

  • • Price: $199 one-time

Step 5.2: Set Up Webhooks (1 hour)

What are webhooks? Stripe sends automatic notifications to your server when payments succeed, enabling you to create customer records automatically.

1

Create Webhook Endpoint

You need a server endpoint to receive webhooks. Options:

Option A: Bubble.io Workflow

  • • Use Bubble's API Workflow
  • • Easiest for no-code
  • • Requires paid Bubble plan

Option B: Serverless Function

  • • Vercel/Netlify function
  • • More technical
  • • Free tier available
2

Configure Webhook in Stripe

  1. Go to Developers → Webhooks
  2. Click "Add endpoint"
  3. Endpoint URL: https://your-api.com/stripe/webhook
  4. Events to send:
    • checkout.session.completed
    • payment_intent.succeeded
    • payment_intent.payment_failed
  5. Click "Add endpoint"
  6. Copy the Webhook Signing Secret (starts with whsec_)
3

Sample Webhook Handler Code

Basic Node.js example:

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const { createClient } = require('@supabase/supabase-js');

const supabase = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_SERVICE_KEY
);

export default async function handler(req, res) {
  const sig = req.headers['stripe-signature'];
  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle successful payment
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;

    // Create customer in database
    const { data, error } = await supabase
      .from('customers')
      .insert([
        {
          email: session.customer_email,
          full_name: session.customer_details.name,
        }
      ])
      .select()
      .single();

    if (!error) {
      // Create order record
      await supabase.from('orders').insert([
        {
          customer_id: data.id,
          order_number: `ORDER-${Date.now()}`,
          package_type: session.metadata.package_type,
          amount_paid: session.amount_total / 100,
          stripe_payment_id: session.payment_intent,
          status: 'payment_received'
        }
      ]);

      // Send confirmation email (Phase 6)
      // await sendConfirmationEmail(session.customer_email);
    }
  }

  res.json({ received: true });
}

Phase 6: Email Automation with SendGrid

Time Required: 2-3 hours | Difficulty: 🟡 Intermediate

Step 6.1: Set Up SendGrid Account (30 minutes)

1

Create SendGrid Account

  • Go to sendgrid.com
  • Click "Start for free"
  • Fill in account details
  • Verify your email
  • Complete account verification questions

Free Plan: 100 emails/day forever (perfect for starting)

2

Verify Domain (Recommended)

  1. Go to Settings → Sender Authentication
  2. Click "Verify a domain"
  3. Enter: careersuccessinstitute.com
  4. SendGrid will provide DNS records to add:

DNS Records to Add:

CNAME Record 1:

em1234.careersuccessinstitute.com → u1234567.wl.sendgrid.net

CNAME Record 2:

s1._domainkey.careersuccessinstitute.com → s1.domainkey.u1234567.wl.sendgrid.net

CNAME Record 3:

s2._domainkey.careersuccessinstitute.com → s2.domainkey.u1234567.wl.sendgrid.net

Add these to your domain registrar (GoDaddy, Namecheap, etc.)

Verification takes 24-48 hours

3

Create API Key

  • Go to Settings → API Keys
  • Click "Create API Key"
  • Name: Career Success Portal
  • Permissions: Full Access (or "Restricted" with Mail Send enabled)
  • Click "Create & View"

🔐 SAVE THIS API KEY NOW:

SG.abc123xyz789...

You won't be able to see it again!

Step 6.2: Create Email Templates (1 hour)

1

Navigate to Dynamic Templates

  • Go to Email API → Dynamic Templates
  • Click "Create a Dynamic Template"
2

Template 1: Payment Confirmation

  1. Template Name: Payment Confirmation
  2. Click "Add Version"
  3. Choose editor: "Code Editor"
  4. Copy your HTML from /email-templates page
  5. Add dynamic variables using {{"{{"}}{{"orderNumber"}}}} syntax

Key Variables to Add:

  • {{"{{"}}{{"customerName"}}}} - Customer's name
  • {{"{{"}}{{"orderNumber"}}}} - Order ID
  • {{"{{"}}{{"packageName"}}}} - What they purchased
  • {{"{{"}}{{"amount"}}}} - Price paid
  • {{"{{"}}{{"orderDate"}}}} - Purchase date
3

Create Remaining Templates

Repeat for:

  • Template 2: Portal Credentials
  • Template 3: First Draft Ready
  • Template 4: Revision Acknowledged
4

Copy Template IDs

For each template, copy the Template ID (looks like: d-abc123xyz789)

You'll need these when sending emails via API

Step 6.3: Send Emails via API (Code Example)

Add this to your Stripe webhook handler (from Phase 5):

const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

async function sendConfirmationEmail(customerData) {
  const msg = {
    to: customerData.email,
    from: '[email protected]', // Your verified sender
    templateId: 'd-abc123xyz789', // Your template ID
    dynamic_template_data: {
      customerName: customerData.name,
      orderNumber: customerData.orderNumber,
      packageName: customerData.package,
      amount: customerData.amount,
      orderDate: new Date().toLocaleDateString()
    }
  };

  try {
    await sgMail.send(msg);
    console.log('Email sent successfully');
  } catch (error) {
    console.error('Email error:', error);
  }
}

// Call in your webhook:
await sendConfirmationEmail({
  email: session.customer_email,
  name: session.customer_details.name,
  orderNumber: 'ORDER-12345',
  package: 'Premium Resume',
  amount: '$299'
});

Test it! Use SendGrid's "Send Test Email" feature in template editor

Phase 7: Testing & Launch

Time Required: 1-2 days | Difficulty: 🟢 Beginner

Step 7.1: End-to-End Testing Checklist

Complete Testing Flow:

Step 7.2: Go Live Checklist

Before Going Live:

Make sure ALL testing is complete and working perfectly!

Common Issues & Solutions

Quick fixes for frequent problems

❌ Stripe Webhook Not Working

Symptoms: Payment succeeds but no database record created

Solutions:

  • Check webhook URL is correct in Stripe
  • Verify webhook signing secret matches
  • Check server logs for errors
  • Test with Stripe CLI: stripe listen --forward-to localhost:3000/webhook

❌ Auth0 Login Fails

Symptoms: Redirect loop or "invalid callback" error

Solutions:

  • Double-check callback URLs in Auth0 settings
  • Ensure URLs match exactly (http vs https)
  • Clear browser cookies and try again
  • Check Auth0 logs in dashboard

❌ Emails Not Sending

Symptoms: No emails received after purchase

Solutions:

  • Check SendGrid API key is correct
  • Verify sender email is verified
  • Check spam folder
  • Review SendGrid activity log
  • Ensure template ID is correct

❌ Database Connection Failed

Symptoms: Can't read/write to Supabase

Solutions:

  • Check Supabase URL and keys are correct
  • Verify RLS policies allow access
  • Use service_role key for admin operations
  • Check network/firewall settings

🎉 Congratulations!

You've completed the detailed implementation guide!

Your complete system is now set up with:
Auth0 authentication • Bubble.io customer portal • Airtable CRM
Supabase database • Stripe payments • SendGrid emails

Career Success Institute - Complete Detailed Implementation Guide

All 7 phases covered with step-by-step instructions

Last Updated: January 2025 | Version 1.0