aethex.live/docs/PHASE_4_MONETIZATION.md

20 KiB

Phase 4: Monetization - Complete Implementation Guide

Duration: Weeks 14-19 | Complexity: Very High | Team Size: 3-4 devs

Executive Summary

Phase 4 enables sustainable revenue for creators through subscriptions, donations, gifting, and platform revenue sharing. Creators earn money, viewers support creators, and the platform generates sustainable revenue.


Phase 4 Goals

Primary Goals

  1. Tiered subscription system
  2. Donation/tip system with alerts
  3. Creator payouts infrastructure
  4. Revenue analytics
  5. Gifting between viewers

Success Criteria

  • 💰 $10k+ monthly platform revenue
  • 👑 50+ creators earning >$100/month
  • 🎁 1k+ gifting transactions
  • 💳 <2% failed transactions
  • 📊 99.9% payout uptime

Sprint Breakdown

Sprint 4.1: Subscriptions

Duration: Days 1-5 | Team: 3 devs

User Story 4.1.1: Subscription Tiers

AS A creator
I WANT to set up subscriptions
SO THAT I can generate recurring revenue

Tasks:

  • Design subscription tier system
  • Build subscription management page
  • Set tier names, prices, benefits
  • Create tier preview page
  • Subscription benefits (badges, emotes, etc - Phase 5)

Tier System:

// Default tiers
const DEFAULT_TIERS = [
  {
    id: 'tier-1',
    name: 'Bronze',
    monthlyPrice: 499, // $4.99 in cents
    description: 'Support the creator',
    benefits: ['Ad-free chat', 'Bronze badge', 'Custom emotes'],
    order: 1,
  },
  {
    id: 'tier-2',
    name: 'Silver', 
    monthlyPrice: 999,
    description: 'VIP support',
    benefits: ['Ad-free chat', 'Silver badge', 'Custom emotes', 'Priority support'],
    order: 2,
  },
  {
    id: 'tier-3',
    name: 'Gold',
    monthlyPrice: 2499,
    description: 'Ultimate support',
    benefits: ['All Silver perks', 'Gold badge', 'Personal shoutout monthly'],
    order: 3,
  },
]

// Creators can customize

Schema:

model SubscriptionTier {
  id                String    @id @default(cuid())
  channelId         String
  channel           Channel   @relation(fields: [channelId], references: [id], onDelete: Cascade)
  
  name              String    // "Silver", "Gold", etc
  description       String?
  price             Int       // In cents (499 = $4.99)
  
  benefits          String[]  // List of benefits
  
  // Customization
  emoteId           String?   // Channel-specific emote
  badgeName         String?   // Badge name for subscribers
  
  order             Int       @default(999)
  isActive          Boolean   @default(true)
  
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt
  
  subscriptions     Subscription[]
}

model Subscription {
  id                String    @id @default(cuid())
  userId            String
  user              User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  
  channelId         String
  channel           Channel   @relation(fields: [channelId], references: [id], onDelete: Cascade)
  
  tierId            String
  tier              SubscriptionTier @relation(fields: [tierId], references: [id], onDelete: Cascade)
  
  // Stripe details
  stripeSubId       String    @unique
  stripeCustomerId  String
  
  // Status
  status            SubStatus @default(ACTIVE) // ACTIVE, CANCELLED, EXPIRED
  
  // Dates
  startDate         DateTime  @default(now())
  renewalDate       DateTime?
  cancelledDate     DateTime?
  
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt
}

enum SubStatus {
  ACTIVE
  CANCELLED  
  EXPIRED
  FAILED
}

API Routes:

  • GET /api/channels/:id/subscription-tiers - Get tier info
  • POST /api/subscription-tiers - Create tier
  • PUT /api/subscription-tiers/:id - Update tier
  • DELETE /api/subscription-tiers/:id - Delete tier
  • GET /api/channels/:id/subscribers - Get subscriber list (creator only)

Components:

components/subscriptions/
├── SubscriptionTierManager.tsx (creator)
├── SubscriptionTierCard.tsx (viewer)
├── SubscribeButton.tsx
├── SubscriptionCheckout.tsx
└── SubscriberBadge.tsx

Deliverables:

  • Subscription tier system designed
  • Creator tier management page
  • Tier customization working
  • Database schema in place

User Story 4.1.2: Stripe Integration

AS A platform
I WANT to handle payments securely
SO THAT USERS CAN SUBSCRIBE SAFELY

Tasks:

  • Set up Stripe account
  • Install Stripe SDK
  • Create Stripe products for tiers
  • Webhook handling for subscription events
  • Test payment flow end-to-end
  • PCI compliance

Stripe Setup:

// lib/stripe.ts
import Stripe from 'stripe'

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2023-10-16',
})

// Create product for tier
export const createStripeProduct = async (tier: SubscriptionTier) => {
  const product = await stripe.products.create({
    name: `${channel.name} - ${tier.name}`,
    description: tier.description,
    metadata: {
      channelId: tier.channelId,
      tierId: tier.id,
    },
  })
  
  const price = await stripe.prices.create({
    product: product.id,
    currency: 'usd',
    unit_amount: tier.price,
    recurring: {
      interval: 'month',
      interval_count: 1,
    },
  })
  
  return { product, price }
}

Checkout Flow:

1. User clicks "Subscribe" button
2. Create Stripe Checkout Session
3. Redirect to Stripe-hosted checkout
4. User enters payment info
5. Stripe processes payment
6. Webhook confirms subscription
7. Create Subscription record in DB
8. Redirect to success page

Webhook Handling:

// pages/api/webhooks/stripe.ts
export async function POST(req) {
  const event = stripe.webhooks.constructEvent(...)
  
  switch (event.type) {
    case 'customer.subscription.created':
      // Create Subscription in DB
      break
    case 'customer.subscription.updated':
      // Update subscription status
      break
    case 'customer.subscription.deleted':
      // Mark as cancelled
      break
    case 'invoice.payment_failed':
      // Send email, mark subscription at risk
      break
  }
}

Deliverables:

  • Stripe account set up and keys configured
  • Products and prices created
  • Checkout working end-to-end
  • Webhook processing events
  • Manual testing complete

User Story 4.1.3: Subscription Page

AS A viewer
I WANT to subscribe to my favorite creator
SO THAT I can support them and get perks

Route: /channel/{username}/subscribe

Tasks:

  • Build subscription tier selection page
  • Display tier benefits
  • List subscriber perks
  • Subscribe button with Stripe redirect
  • Success page after subscription
  • Manage subscription page

Page Structure:

/channel/[username]/subscribe
├── Hero: "Support {CreatorName}"
├── Tier Cards (3 columns)
│   ├── Card 1: $4.99/mo
│   │   ├── Tier name
│   │   ├── Benefits list
│   │   └── Subscribe button
│   ├── Card 2: $9.99/mo (highlighted)
│   └── Card 3: $24.99/mo
├── FAQ section
└── Testimonials from existing subscribers

Success page:
├── Checkmark "Subscribed!"
├── Tier details confirmations
├── "Manage subscription" link
└── "Go back to channel" link

Manage Subscription Page:

/dashboard/subscriptions
├── Active subscriptions (Tier, renewal date)
├── Cancel button per subscription
├── Payment history
└── Receipt downloads

Components:

components/subscriptions/
├── SubscriptionTierCards.tsx
├── SubscriptionFAQ.tsx
├── SuccessPage.tsx
└── ManageSubscriptions.tsx

Deliverables:

  • Subscription page attractive
  • Tiering clear
  • Subscribe flow smooth
  • Success feedback clear

Sprint 4.2: Donations & Gifting

Duration: Days 6-10 | Team: 2 devs

User Story 4.2.1: Donation System

AS A viewer
I WANT to donate to my favorite creator
SO THAT I can show appreciation

Tasks:

  • Build donation widget
  • Custom donation amounts
  • Donation alerts (text + sound)
  • Donation activity feed
  • Thank you message system

Schema:

model Donation {
  id                String    @id @default(cuid())
  donorId           String
  donor             User      @relation(fields: [donorId], references: [id], onDelete: SetNull)
  
  channelId         String
  channel           Channel   @relation(fields: [channelId], references: [id], onDelete: Cascade)
  
  streamId          String?   // Optional: linked to specific stream
  stream            Stream?   @relation(fields: [streamId], references: [id], onDelete: SetNull)
  
  amount            Int       // In cents
  currency          String    @default("USD")
  
  message           String?
  isAnonymous       Boolean   @default(false)
  
  stripePaymentId   String    @unique
  
  // Alert
  showAlert         Boolean   @default(true)
  playSound         Boolean   @default(true)
  soundUrl          String?   // Default sound or custom
  
  createdAt         DateTime  @default(now())
}

Donation Widget Layout:

On stream page, bottom right:
┌─────────────────────┐
│  Support {Creator}  │
├─────────────────────┤
│ ♥ Donate $5         │
│ ♥ Donate $10        │
│ ♥ Donate $25        │
│ ♥ Custom amount     │
└─────────────────────┘

Donation Alert (during stream):

Alerts to creator's screen:
┌──────────────────────────┐
│ ✨ JohnDoe donated $10! ✨│
│                          │
│ "Great stream bro!"      │
│                          │
│ [Alert sound + animation]│
└──────────────────────────┘

API Routes:

  • POST /api/donations - Create donation
  • GET /api/channels/:id/donations - List donations
  • GET /api/donations/recent - Recent donations for alerts
  • PUT /api/donations/:id - Update anonymous status

WebSocket Events:

socket.emit('donation:alert', {
  donorName: string,
  amount: number,
  message: string,
  timestamp: Date,
})

Components:

components/donations/
├── DonationWidget.tsx
├── DonationInput.tsx
├── DonationAlert.tsx
└── DonationHistory.tsx

Deliverables:

  • Donation widget working
  • Alerts displaying
  • Donations recorded
  • Sound playback

User Story 4.2.2: Gifting System

AS A viewer
I WANT to gift subscriptions
SO THAT I CAN SUPPORT OTHERS

Tasks:

  • Gift subscription feature
  • Recipient selection
  • Gift alerts
  • Gift history

Schema:

model SubscriptionGift {
  id                String    @id @default(cuid())
  gifterUserId      String
  gifter            User      @relation("gifted_to", fields: [gifterUserId], references: [id])
  
  recipientUserId   String
  recipient         User      @relation("gifted_from", fields: [recipientUserId], references: [id])
  
  channelId         String
  channel           Channel   @relation(fields: [channelId], references: [id])
  
  tierId            String
  tier              SubscriptionTier @relation(fields: [tierId], references: [id])
  
  months            Int       @default(1) // Gift for 1-12 months
  
  message           String?
  
  stripePaymentId   String    @unique
  
  createdAt         DateTime  @default(now())
}

Gift Flow:

1. Viewer clicks "Gift Sub" button
2. Select recipient from chat users
3. Select tier
4. Select 1-12 months
5. Optional message
6. Process payment
7. Recipient automatically subscribed
8. Alert in chat: "JohnDoe gifted 5 subs to viewers!"

Deliverables:

  • Gift subscription flow
  • Recipient notifications
  • Gift alerts in chat
  • Gift tracking

Sprint 4.3: Creator Payouts

Duration: Days 11-15 | Team: 3 devs

User Story 4.3.1: Revenue Dashboard

AS A creator
I WANT to see my earnings
SO THAT I CAN TRACK MY INCOME

Tasks:

  • Build revenue dashboard
  • Display total earnings
  • Breakdown by source (subs, donations, gifts)
  • Earnings graphs
  • Tax forms (1099 for US)

Dashboard Layout:

/dashboard/revenue
├── Revenue Summary
│   ├── Total this month: $1,234.56
│   ├── Pending payout: $567.89
│   └── Last payout: $1,000 (Feb 5)
├── Revenue Breakdown (pie chart)
│   ├── Subscriptions: 60%
│   ├── Donations: 30%
│   └── Gifts: 10%
├── Monthly Graph (last 12 months)
├── Detailed Earnings Table
│   ├── Type, Date, Amount, Status
│   └── Filter, sort, export CSV
└── Payout Settings
    ├── Connected Stripe Account
    ├── Tax Info (1099)
    └── Payout Frequency (monthly, weekly)

Schema:

model CreatorRevenue {
  id                String    @id @default(cuid())
  channelId         String    @unique
  channel           Channel   @relation(fields: [channelId], references: [id])
  
  totalEarnings     Int       // All time in cents
  pendingBalance    Int       // Awaiting payout
  paidBalance       Int       // Already paid out
  
  platformFeeRate   Float     @default(0.30) // 30% platform cut
  lastPayoutDate    DateTime?
  
  stripeAccountId   String?   // Connected Stripe account
  
  updatedAt         DateTime  @updatedAt
}

model PayoutRequest {
  id                String    @id @default(cuid())
  channelId         String
  channel           Channel   @relation(fields: [channelId], references: [id])
  
  amount            Int       // In cents
  status            PayoutStatus @default(PENDING)
  
  stripePayoutId    String?   @unique
  
  requestedAt       DateTime  @default(now())
  paidAt            DateTime?
  
  failureReason     String?
}

enum PayoutStatus {
  PENDING
  PROCESSING
  PAID
  FAILED
}

API Routes:

  • GET /api/revenue/summary - Total earnings
  • GET /api/revenue/details - Transaction list
  • GET /api/revenue/graphs - Chart data
  • POST /api/payouts/request - Request payout
  • GET /api/payouts - Payout history
  • GET /api/creator-account - Stripe account status

Components:

components/revenue/
├── RevenueSummary.tsx
├── RevenueBreakdown.tsx
├── EarningsGraph.tsx
├── TransactionTable.tsx
├── PayoutRequests.tsx
└── StripeConnectButton.tsx

Pricing Model:

Platform Cut: 30%
Creator Revenue: 70%

Example:
$10 subscription
→ $7 to creator
→ $3 to platform (Stripe + operations)

Deliverables:

  • Revenue dashboard showing data
  • Breakdown working correctly
  • Graphs displaying
  • Export to CSV

User Story 4.3.2: Stripe Connect

AS A creator  
I WANT TO CONNECT MY STRIPE ACCOUNT
SO THAT I CAN GET PAID DIRECTLY

Tasks:

  • Implement Stripe Connect
  • OAuth flow for account connection
  • Account verification steps
  • Payout settings
  • Automatic daily/weekly/monthly payouts

Stripe Connect Flow:

1. Creator visits revenue settings
2. Clicks "Connect Your Bank Account"
3. Redirected to Stripe OAuth
4. Creator authorizes and verifies identity
5. Returned to app with connected account
6. Revenue automatically transfers to creator's Stripe account
7. Creator can withdraw to their bank account themselves

Payouts:

Option A: Automatic Payouts
- Set frequency: daily, weekly, or monthly
- Stripe automatically pays creators
- Creators can see status in Stripe Dashboard

Option B: Manual Request
- Creator manually requests payout
- Platform reviews (fraud check)
- Approves and initiates Stripe payout
- Creator sees in bank within 1-2 days

API Routes:

  • POST /api/connect/oauth - OAuth handler
  • GET /api/connect/account - Get connected account status
  • PUT /api/connect/settings - Payout frequency
  • POST /api/connect/disconnect - Disconnect account

Deliverables:

  • Stripe Connect integration
  • OAuth flow working
  • Payouts processing
  • Status tracking

User Story 4.3.3: Tax & Compliance

AS A creator
I WANT TO HANDLE TAXES
SO THAT I CAN STAY COMPLIANT

Tasks:

  • Collect tax information (W9/1099)
  • Generate 1099 forms (US)
  • Tax recap email yearly
  • Export earnings for tax filing

Tax Collection:

US Creators:
- Threshold: $600+ annual earnings
- Collect W9 form
- Generate 1099-NEC
- Send to creator by Jan 31
- Send copy to IRS

International:
- Collect legal entity info
- Generate invoices
- Creators report own taxes

Schema:

model TaxInfo {
  id                String    @id @default(cuid())
  channelId         String    @unique
  channel           Channel   @relation(fields: [channelId], references: [id])
  
  country           String    // "US", "CA", "UK", etc
  
  // US W9 fields
  businessName      String?
  taxId             String?   // SSN or EIN
  ownerName         String?
  
  // International
  businessAddress   String?
  
  updatedAt         DateTime  @updatedAt
}

API Routes:

  • PUT /api/tax-info - Update tax info
  • GET /api/tax-forms/:year - Get 1099 form
  • POST /api/tax-forms/send - Send form to IRS

Deliverables:

  • Tax info collection
  • 1099 generation (US)
  • Compliance verified

Sprint 4.4: Testing & Deployment

Duration: Days 16-20 | Team: 3 devs

Payment Testing

  • Test subscription creation
  • Test subscription cancellation
  • Test failed payments handling
  • Test refunds
  • Test webhook processing
  • Load test with 1000 concurrent checkouts

Compliance

  • SSL/TLS enabled
  • PCI compliance verified
  • Stripe Terms of Service compliant
  • Refund policy in place
  • Privacy policy updated

Documentation

  • Payment flow documented
  • Creator onboarding guide
  • FAQ for payments
  • Troubleshooting guide

Database Schema - Phase 4 Complete

New Models:

- SubscriptionTier
- Subscription
- Donation
- SubscriptionGift
- CreatorRevenue
- PayoutRequest
- TaxInfo

Updated Models:

  • Channel (adds relations to tiers, subscriptions)
  • User (adds relations to subscriptions, donations)
  • Stream (adds donations relation)

API Routes - Phase 4 Complete

Subscriptions: 6 routes
Donations: 4 routes
Gifting: 3 routes
Payouts: 5 routes
Tax: 3 routes

Total: ~20 new routes


Components - Phase 4 New

components/subscriptions/ (5)
components/donations/ (4)
components/gifting/ (3)
components/revenue/ (6)

Third-Party Services

Stripe

  • Account management
  • Billing API
  • Payout API
  • Connect platform
  • ~2.2% + $0.30 per transaction
  • PCI Level 1 compliant

Tax Services (Optional)

  • TaxJar for VAT/GST handling
  • CloudTax API for 1099 generation

Success Metrics

  • 💰 $10k+ monthly platform revenue
  • 👑 50+ creators earning >$100/month
  • 💳 Sub conversion rate: 5% of viewers
  • 📊 <2% payment failure rate
  • ⏱️ <100ms checkout experience
  • 🔄 <1h payout processing time

Payment Pricing

AeThex takes 30% platform cut:

  • Stripe processing: ~2.2% + $0.30
  • Operations (support, moderation): 10%
  • Infrastructure & scaling: 10%
  • Growth & marketing: 5%
  • Profit/reserves: 2.8%

Timeline

Week Sprint Focus
14 4.1 Subscriptions, Stripe integration
15 4.2 Donations, gifting
16 4.3 Creator payouts, Stripe Connect
17-19 4.4 Testing, deployment, optimization

Phase 4 Completion Checklist

  • Subscription system working
  • All Stripe integrations tested
  • Donations functioning
  • Gifting system live
  • Creator payouts processing
  • Revenue dashboard accurate
  • Tax forms generating
  • Payment compliance verified
  • Mobile payments working
  • Deployed to production
  • $10k+ monthly revenue

Phase 4 Estimated Completion: Week 19 (by May 16, 2025)
Next Phase: Phase 5 - Community & Engagement (May 19, 2025)

See PHASE_5_COMMUNITY.md for Phase 5 details.