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
- Tiered subscription system
- Donation/tip system with alerts
- Creator payouts infrastructure
- Revenue analytics
- 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 infoPOST /api/subscription-tiers- Create tierPUT /api/subscription-tiers/:id- Update tierDELETE /api/subscription-tiers/:id- Delete tierGET /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 donationGET /api/channels/:id/donations- List donationsGET /api/donations/recent- Recent donations for alertsPUT /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 earningsGET /api/revenue/details- Transaction listGET /api/revenue/graphs- Chart dataPOST /api/payouts/request- Request payoutGET /api/payouts- Payout historyGET /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 handlerGET /api/connect/account- Get connected account statusPUT /api/connect/settings- Payout frequencyPOST /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 infoGET /api/tax-forms/:year- Get 1099 formPOST /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.