aethex.live/docs/PHASE_4_MONETIZATION.md

858 lines
20 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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**:
```typescript
// 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**:
```prisma
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**:
```typescript
// 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**:
```typescript
// 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**:
```prisma
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**:
```typescript
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**:
```prisma
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**:
```prisma
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**:
```prisma
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](PHASE_5_COMMUNITY.md) for Phase 5 details.