Skip to content

VidyaNet Marketplace Subscription Model

Design Document Created: January 2025 Status: Implementation Ready Inspired by: Medium.com Partner Program

Executive Summary

This document outlines the transition from a per-content purchase model to a subscription-based marketplace model for VidyaNet. The new model provides predictable revenue, reduces friction for schools and teachers, and fairly compensates creators based on actual content usage.


Current State

The marketplace currently operates on an individual purchase model: - Schools/teachers buy content individually from creators - High friction for each purchase (approval cycles) - Unpredictable revenue for creators - Administrative overhead per transaction


New Subscription Model

Subscription Tiers

For Schools (Add-on to VidyaNet Platform)

Tier Price Capacity Features
School Basic ₹15,000/year Up to 500 students Full marketplace access for all teachers
School Standard ₹25,000/year Up to 1000 students Full access + basic analytics
School Premium ₹40,000/year Unlimited Full access + advanced analytics + 2x creator payout weight

For Individual Educators

Tier Price Features
Monthly ₹199/month Full marketplace access
Yearly ₹1,499/year Full access (save 37%)
Premium ₹2,999/year Full access + creator tools + analytics + 2x payout weight

Revenue Distribution

Split Model

Total Marketplace Subscription Revenue
    ┌───────────────────────┐
    │   REVENUE SPLIT       │
    ├───────────────────────┤
    │  VidyaNet: 40%        │  → Platform operations, support, marketing
    │  Creator Pool: 60%    │  → Distributed to creators by usage
    └───────────────────────┘

Creator Payout Calculation

Creator Monthly Payout = (Creator's Engagement Points / Total Platform Points) × Creator Pool

Engagement Points Calculation:
- Lesson View (30+ seconds)     = 1 point
- Lesson Completion             = 3 points
- Quiz/Assignment Use           = 5 points
- Positive Rating (4-5 stars)   = 2 points
- Content Download              = 2 points
- Premium User Multiplier       = 2x all points

Example Calculation

Monthly Scenario:
─────────────────
Total Marketplace Revenue:     ₹5,00,000
Creator Pool (60%):            ₹3,00,000

Creator A's Engagement Points: 15,000
Total Platform Points:         1,50,000

Creator A's Payout = (15,000 / 1,50,000) × ₹3,00,000
                   = 10% × ₹3,00,000
                   = ₹30,000/month

Content Access Tiers

Free (No subscription needed)

  • Preview first lesson of any course
  • View content descriptions & ratings
  • Access curated courses (admin-published curriculum)

Subscriber-Only

  • Full marketplace content library
  • Download worksheets & resources
  • AI-powered content recommendations
  • Creator Q&A / discussions

Premium Subscriber

  • Everything above
  • Early access to new content
  • Usage analytics & insights
  • Priority support
  • Can become a creator (no extra fee)

Creator Program

Eligibility Requirements

Requirement Details
Verification KYC with Aadhaar/PAN
Quality Gate First 3 pieces reviewed by VidyaNet team
Minimum Content At least 1 published lesson
Bank Account Indian bank account for payouts
Minimum Payout ₹500 threshold

Creator Tiers

Tier Requirements Benefits
🌱 New Creator Just joined Standard 60% revenue share
🌿 Rising Creator 1,000+ engagement points Better search placement
🌳 Established 10,000+ points, 4.0+ avg rating Featured sections, 62% share
Star Creator 50,000+ points, verified badge Premium placement, 65% share
👑 Elite Creator Top 1% Homepage features, 70% share

Database Schema

New Tables

marketplace_subscriptions

Tracks school and individual subscriptions.

CREATE TABLE marketplace_subscriptions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    subscriber_type VARCHAR(20) NOT NULL,  -- 'school' or 'individual'
    school_id UUID REFERENCES schools(id),
    user_id UUID REFERENCES users(id),
    plan_type VARCHAR(20) NOT NULL,        -- 'basic', 'standard', 'premium'
    billing_cycle VARCHAR(20) NOT NULL,    -- 'monthly', 'yearly'
    price_paid DECIMAL(10,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'INR',
    student_limit INTEGER,                  -- for school plans
    started_at TIMESTAMP NOT NULL,
    expires_at TIMESTAMP NOT NULL,
    is_active BOOLEAN DEFAULT true,
    auto_renew BOOLEAN DEFAULT true,
    payment_provider VARCHAR(20),           -- 'razorpay', 'stripe'
    payment_reference VARCHAR(100),
    cancelled_at TIMESTAMP,
    cancellation_reason TEXT,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    CONSTRAINT valid_subscriber CHECK (
        (subscriber_type = 'school' AND school_id IS NOT NULL) OR
        (subscriber_type = 'individual' AND user_id IS NOT NULL)
    )
);

content_engagement

Tracks all content interactions for payout calculation.

CREATE TABLE content_engagement (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    content_id UUID NOT NULL REFERENCES marketplace_contents(id),
    user_id UUID NOT NULL REFERENCES users(id),
    engagement_type VARCHAR(20) NOT NULL,   -- 'view', 'completion', 'download', 'quiz_use', 'rating'
    duration_seconds INTEGER,               -- for views
    rating_value INTEGER,                   -- for ratings (1-5)
    is_premium_user BOOLEAN DEFAULT false,
    points_earned DECIMAL(10,2) NOT NULL,
    recorded_at TIMESTAMP DEFAULT NOW(),

    -- Prevent duplicate engagements
    UNIQUE(content_id, user_id, engagement_type, DATE(recorded_at))
);

creator_payouts

Monthly payout records for creators.

CREATE TABLE creator_payouts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    creator_id UUID NOT NULL REFERENCES creators(id),
    period_start DATE NOT NULL,
    period_end DATE NOT NULL,
    total_engagement_points DECIMAL(12,2) NOT NULL,
    platform_total_points DECIMAL(12,2) NOT NULL,
    revenue_pool DECIMAL(12,2) NOT NULL,
    revenue_share_percentage INTEGER NOT NULL,
    gross_payout DECIMAL(10,2) NOT NULL,
    deductions DECIMAL(10,2) DEFAULT 0,     -- TDS, fees
    net_payout DECIMAL(10,2) NOT NULL,
    payout_status VARCHAR(20) DEFAULT 'calculated',  -- 'calculated', 'approved', 'processing', 'paid', 'failed'
    approved_by UUID REFERENCES users(id),
    approved_at TIMESTAMP,
    paid_at TIMESTAMP,
    payment_provider VARCHAR(20),
    transaction_reference VARCHAR(100),
    failure_reason TEXT,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    UNIQUE(creator_id, period_start)
);

creator_tiers

Tracks creator level and benefits.

CREATE TABLE creator_tiers (
    creator_id UUID PRIMARY KEY REFERENCES creators(id),
    tier VARCHAR(20) NOT NULL DEFAULT 'new',  -- 'new', 'rising', 'established', 'star', 'elite'
    total_lifetime_points DECIMAL(14,2) DEFAULT 0,
    total_content_count INTEGER DEFAULT 0,
    average_rating DECIMAL(3,2),
    revenue_share_percentage INTEGER DEFAULT 60,
    verified_at TIMESTAMP,
    tier_updated_at TIMESTAMP DEFAULT NOW(),
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

subscription_usage_logs

Audit trail for subscription usage.

CREATE TABLE subscription_usage_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    subscription_id UUID NOT NULL REFERENCES marketplace_subscriptions(id),
    user_id UUID NOT NULL REFERENCES users(id),
    content_id UUID NOT NULL REFERENCES marketplace_contents(id),
    action VARCHAR(20) NOT NULL,            -- 'access', 'download'
    recorded_at TIMESTAMP DEFAULT NOW()
);

Indexes

-- Subscription lookups
CREATE INDEX idx_subscriptions_school ON marketplace_subscriptions(school_id) WHERE school_id IS NOT NULL;
CREATE INDEX idx_subscriptions_user ON marketplace_subscriptions(user_id) WHERE user_id IS NOT NULL;
CREATE INDEX idx_subscriptions_active ON marketplace_subscriptions(is_active, expires_at);

-- Engagement analytics
CREATE INDEX idx_engagement_content ON content_engagement(content_id, recorded_at);
CREATE INDEX idx_engagement_user ON content_engagement(user_id, recorded_at);
CREATE INDEX idx_engagement_period ON content_engagement(recorded_at);

-- Payout queries
CREATE INDEX idx_payouts_creator ON creator_payouts(creator_id, period_start);
CREATE INDEX idx_payouts_status ON creator_payouts(payout_status);

API Endpoints

Subscription Management

POST   /api/v1/marketplace/subscriptions              # Create subscription
GET    /api/v1/marketplace/subscriptions/me           # Get current subscription
GET    /api/v1/marketplace/subscriptions/{id}         # Get subscription details
PUT    /api/v1/marketplace/subscriptions/{id}/cancel  # Cancel subscription
POST   /api/v1/marketplace/subscriptions/{id}/renew   # Renew subscription
GET    /api/v1/marketplace/subscriptions/plans        # List available plans

Subscription Verification (Internal)

GET    /api/v1/marketplace/access/check               # Check if user has access
GET    /api/v1/marketplace/access/school/{school_id}  # Check school subscription

Content Engagement

POST   /api/v1/marketplace/engagement/track           # Track engagement event
GET    /api/v1/marketplace/engagement/my-stats        # User's engagement stats
GET    /api/v1/marketplace/engagement/content/{id}    # Content engagement stats

Creator Payouts

GET    /api/v1/marketplace/payouts/me                 # Creator's payout history
GET    /api/v1/marketplace/payouts/me/current         # Current period earnings
GET    /api/v1/marketplace/payouts/{id}               # Payout details
POST   /api/v1/marketplace/payouts/calculate          # Trigger payout calculation (admin)
PUT    /api/v1/marketplace/payouts/{id}/approve       # Approve payout (admin)
PUT    /api/v1/marketplace/payouts/{id}/process       # Process payment (admin)

Creator Tiers

GET    /api/v1/marketplace/creators/me/tier           # Get my tier info
GET    /api/v1/marketplace/creators/{id}/tier         # Get creator tier (public)

Admin Analytics

GET    /api/v1/admin/marketplace/revenue              # Revenue analytics
GET    /api/v1/admin/marketplace/subscriptions        # Subscription analytics
GET    /api/v1/admin/marketplace/payouts/pending      # Pending payouts
GET    /api/v1/admin/marketplace/creators/rankings    # Creator rankings

Implementation Phases

Phase 1: Database & Core Models (Week 1)

  • [ ] Create Alembic migration for new tables
  • [ ] Create SQLAlchemy models
  • [ ] Create Pydantic schemas
  • [ ] Unit tests for models

Phase 2: Subscription Service (Week 1-2)

  • [ ] Subscription CRUD service
  • [ ] Access control middleware
  • [ ] Plan configuration
  • [ ] Subscription validation logic

Phase 3: Engagement Tracking (Week 2)

  • [ ] Engagement tracking service
  • [ ] Points calculation logic
  • [ ] Track content views, completions, downloads
  • [ ] Premium user detection

Phase 4: Creator Payouts (Week 2-3)

  • [ ] Monthly payout calculation job
  • [ ] Creator tier calculation
  • [ ] Payout approval workflow
  • [ ] Payout processing (bank transfer integration)

Phase 5: API Endpoints (Week 3)

  • [ ] Subscription endpoints
  • [ ] Engagement endpoints
  • [ ] Payout endpoints
  • [ ] Admin endpoints

Phase 6: Frontend - Web (Week 3-4)

  • [ ] Subscription plans page
  • [ ] Checkout flow (Razorpay integration)
  • [ ] Subscription management page
  • [ ] Creator earnings dashboard
  • [ ] Admin payout management

Phase 7: Frontend - Mobile (Week 4)

  • [ ] Subscription status display
  • [ ] Upgrade prompts
  • [ ] Creator earnings view

Phase 8: Testing & Polish (Week 4-5)

  • [ ] Integration tests
  • [ ] Load testing for engagement tracking
  • [ ] Email notifications
  • [ ] Documentation

Migration Strategy

Handling Existing Purchases

  1. Honor existing purchases: Content already purchased remains accessible
  2. Grandfather existing users: Offer discounted first-year subscription
  3. Parallel operation: Run both models for 3 months
  4. Sunset purchases: Stop new individual purchases after transition period

Data Migration

-- Migrate existing purchases to access logs (for reference)
INSERT INTO subscription_usage_logs (subscription_id, user_id, content_id, action, recorded_at)
SELECT NULL, user_id, content_id, 'legacy_purchase', purchased_at
FROM purchases;

Success Metrics

Metric Target
School subscription conversion 30% of active schools in 6 months
Individual subscription conversion 20% of active teachers in 6 months
Creator retention 80% of active creators continue
Average creator payout ₹5,000+/month for active creators
Content engagement increase 3x compared to purchase model
MRR growth 20% month-over-month

Risks & Mitigations

Risk Mitigation
Creators unhappy with usage-based pay Transparent dashboard, minimum guarantee for first 6 months
Schools resist subscription model Flexible pricing, pilot program
Content quality drops Quality gates, ratings system, tier demotion
Payment failures Multiple payment providers, retry logic
Engagement gaming Fraud detection, minimum duration rules

References