# Subscription Workflow Plan ## Overview End-to-end subscription management workflow for vendors on the platform. --- ## 1. Vendor Subscribes to a Tier ### 1.1 New Vendor Registration Flow ``` Vendor Registration → Select Tier → Trial Period → Payment Setup → Active Subscription ``` **Steps:** 1. Vendor creates account (existing flow) 2. During onboarding, vendor selects a tier: - Show tier comparison cards (Essential, Professional, Business, Enterprise) - Highlight features and limits for each tier - Default to 14-day trial on selected tier 3. Create `VendorSubscription` record with: - `tier` = selected tier code - `status` = "trial" - `trial_ends_at` = now + 14 days - `period_start` / `period_end` set for trial period 4. Before trial ends, prompt vendor to add payment method 5. On payment method added → Create Stripe subscription → Status becomes "active" ### 1.2 Database Changes Required **Add FK relationship to `subscription_tiers`:** ```python # VendorSubscription - Add proper FK tier_id = Column(Integer, ForeignKey("subscription_tiers.id"), nullable=True) tier_code = Column(String(20), nullable=False) # Keep for backwards compat # Relationship tier_obj = relationship("SubscriptionTier", backref="subscriptions") ``` **Migration:** 1. Add `tier_id` column (nullable initially) 2. Populate `tier_id` from existing `tier` code values 3. Add FK constraint ### 1.3 API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/api/v1/vendor/subscription/tiers` | GET | List available tiers for selection | | `/api/v1/vendor/subscription/select-tier` | POST | Select tier during onboarding | | `/api/v1/vendor/subscription/setup-payment` | POST | Create Stripe checkout for payment | --- ## 2. Admin Views Subscription on Vendor Page ### 2.1 Vendor Detail Page Enhancement **Location:** `/admin/vendors/{vendor_id}` **New Subscription Card:** ``` ┌─────────────────────────────────────────────────────────────┐ │ Subscription [Edit] │ ├─────────────────────────────────────────────────────────────┤ │ Tier: Professional Status: Active │ │ Price: €99/month Since: Jan 15, 2025 │ │ Next Billing: Feb 15, 2025 │ ├─────────────────────────────────────────────────────────────┤ │ Usage This Period │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Orders │ │ Products │ │ Team Members │ │ │ │ 234 / 500 │ │ 156 / ∞ │ │ 2 / 3 │ │ │ │ ████████░░ │ │ ████████████ │ │ ██████░░░░ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ Add-ons: Custom Domain (mydomain.com), 5 Email Addresses │ └─────────────────────────────────────────────────────────────┘ ``` ### 2.2 Files to Modify - `app/templates/admin/vendor-detail.html` - Add subscription card - `static/admin/js/vendor-detail.js` - Load subscription data - `app/api/v1/admin/vendors.py` - Include subscription in vendor response ### 2.3 Admin Quick Actions From the vendor page, admin can: - **Change Tier** - Upgrade/downgrade vendor - **Override Limits** - Set custom limits (enterprise deals) - **Extend Trial** - Give more trial days - **Cancel Subscription** - With reason - **Manage Add-ons** - Add/remove add-ons --- ## 3. Tier Upgrade/Downgrade ### 3.1 Admin-Initiated Change **Location:** Admin vendor page → Subscription card → [Edit] button **Modal: Change Subscription Tier** ``` ┌─────────────────────────────────────────────────────────┐ │ Change Subscription Tier [X] │ ├─────────────────────────────────────────────────────────┤ │ Current: Professional (€99/month) │ │ │ │ New Tier: │ │ ○ Essential (€49/month) - Downgrade │ │ ● Business (€199/month) - Upgrade │ │ ○ Enterprise (Custom) - Contact required │ │ │ │ When to apply: │ │ ○ Immediately (prorate current period) │ │ ● At next billing cycle (Feb 15, 2025) │ │ │ │ [ ] Notify vendor by email │ │ │ │ [Cancel] [Apply Change] │ └─────────────────────────────────────────────────────────┘ ``` ### 3.2 Vendor-Initiated Change **Location:** Vendor dashboard → Billing page → [Change Plan] **Flow:** 1. Vendor clicks "Change Plan" on billing page 2. Shows tier comparison with current tier highlighted 3. Vendor selects new tier 4. For upgrades: - Show prorated amount for immediate change - Or option to change at next billing - Redirect to Stripe checkout if needed 5. For downgrades: - Always schedule for next billing cycle - Show what features they'll lose - Confirmation required ### 3.3 API Endpoints | Endpoint | Method | Actor | Description | |----------|--------|-------|-------------| | `/api/v1/admin/subscriptions/{vendor_id}/change-tier` | POST | Admin | Change vendor's tier | | `/api/v1/vendor/billing/change-tier` | POST | Vendor | Request tier change | | `/api/v1/vendor/billing/preview-change` | POST | Vendor | Preview proration | ### 3.4 Stripe Integration **Upgrade (Immediate):** ```python stripe.Subscription.modify( subscription_id, items=[{"price": new_price_id}], proration_behavior="create_prorations" ) ``` **Downgrade (Scheduled):** ```python stripe.Subscription.modify( subscription_id, items=[{"price": new_price_id}], proration_behavior="none", billing_cycle_anchor="unchanged" ) # Store scheduled change in our DB ``` --- ## 4. Add-ons Upselling ### 4.1 Where Add-ons Are Displayed #### A. Vendor Billing Page ``` /vendor/{code}/billing ┌─────────────────────────────────────────────────────────────┐ │ Available Add-ons │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ 🌐 Custom Domain │ │ 📧 Email Package │ │ │ │ €15/year │ │ From €5/month │ │ │ │ Use your own domain │ │ 5, 10, or 25 emails │ │ │ │ [Add to Plan] │ │ [Add to Plan] │ │ │ └─────────────────────┘ └─────────────────────┘ │ │ │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ 🔒 Premium SSL │ │ 💾 Extra Storage │ │ │ │ €49/year │ │ €5/month per 10GB │ │ │ │ EV certificate │ │ More product images │ │ │ │ [Add to Plan] │ │ [Add to Plan] │ │ │ └─────────────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` #### B. Contextual Upsells **When vendor hits a limit:** ``` ┌─────────────────────────────────────────────────────────┐ │ ⚠️ You've reached your order limit for this month │ │ │ │ Upgrade to Professional to get 500 orders/month │ │ [Upgrade Now] [Dismiss] │ └─────────────────────────────────────────────────────────┘ ``` **In settings when configuring domain:** ``` ┌─────────────────────────────────────────────────────────┐ │ 🌐 Custom Domain │ │ │ │ Your shop is available at: myshop.platform.com │ │ │ │ Want to use your own domain like www.myshop.com? │ │ Add the Custom Domain add-on for just €15/year │ │ │ │ [Add Custom Domain] │ └─────────────────────────────────────────────────────────┘ ``` #### C. Upgrade Prompts in Tier Comparison When showing tier comparison, highlight what add-ons come included: - Professional: Includes 1 custom domain - Business: Includes custom domain + 5 email addresses - Enterprise: All add-ons included ### 4.2 Add-on Purchase Flow ``` Vendor clicks [Add to Plan] ↓ Modal: Configure Add-on - Domain: Enter domain name, check availability - Email: Select package (5/10/25) ↓ Create Stripe checkout session for add-on price ↓ On success: Create VendorAddOn record ↓ Provision add-on (domain registration, email setup) ``` ### 4.3 Add-on Management **Vendor can view/manage in Billing page:** ``` ┌─────────────────────────────────────────────────────────────┐ │ Your Add-ons │ ├─────────────────────────────────────────────────────────────┤ │ Custom Domain myshop.com €15/year [Manage] │ │ Email Package 5 addresses €5/month [Manage] │ │ │ │ Next billing: Feb 15, 2025 │ └─────────────────────────────────────────────────────────────┘ ``` ### 4.4 Database: `vendor_addons` Table ```python class VendorAddOn(Base): id = Column(Integer, primary_key=True) vendor_id = Column(Integer, ForeignKey("vendors.id")) addon_product_id = Column(Integer, ForeignKey("addon_products.id")) # Config (e.g., domain name, email count) config = Column(JSON, nullable=True) # Stripe stripe_subscription_item_id = Column(String(100)) # Status status = Column(String(20)) # active, cancelled, pending_setup provisioned_at = Column(DateTime) # Billing quantity = Column(Integer, default=1) created_at = Column(DateTime) cancelled_at = Column(DateTime, nullable=True) ``` --- ## 5. Implementation Phases ### Phase 1: Database & Core (Day 1-2) - [ ] Add `tier_id` FK to VendorSubscription - [ ] Create migration with data backfill - [ ] Update subscription service to use tier relationship - [ ] Update admin subscription endpoints ### Phase 2: Admin Vendor Page (Day 2-3) - [ ] Add subscription card to vendor detail page - [ ] Show usage meters (orders, products, team) - [ ] Add "Edit Subscription" modal - [ ] Implement tier change API (admin) ### Phase 3: Vendor Billing Page (Day 3-4) - [ ] Create `/vendor/{code}/billing` page - [ ] Show current plan and usage - [ ] Add tier comparison/change UI - [ ] Implement tier change API (vendor) - [ ] Add Stripe checkout integration for upgrades ### Phase 4: Add-ons (Day 4-5) - [ ] Seed add-on products in database - [ ] Add "Available Add-ons" section to billing page - [ ] Implement add-on purchase flow - [ ] Create VendorAddOn management - [ ] Add contextual upsell prompts ### Phase 5: Polish & Testing (Day 5-6) - [ ] Email notifications for tier changes - [ ] Webhook handling for Stripe events - [ ] Usage limit enforcement updates - [ ] End-to-end testing - [ ] Documentation --- ## 6. Files to Create/Modify ### New Files | File | Purpose | |------|---------| | `app/templates/vendor/billing.html` | Vendor billing page | | `static/vendor/js/billing.js` | Billing page JS | | `app/api/v1/vendor/billing.py` | Vendor billing endpoints | | `app/services/addon_service.py` | Add-on management | ### Modified Files | File | Changes | |------|---------| | `models/database/subscription.py` | Add tier_id FK | | `app/templates/admin/vendor-detail.html` | Add subscription card | | `static/admin/js/vendor-detail.js` | Load subscription data | | `app/api/v1/admin/vendors.py` | Include subscription in response | | `app/api/v1/admin/subscriptions.py` | Add tier change endpoint | | `app/services/subscription_service.py` | Tier change logic | | `app/templates/vendor/partials/sidebar.html` | Add Billing link | --- ## 7. API Summary ### Admin APIs ``` GET /admin/vendors/{id} # Includes subscription POST /admin/subscriptions/{vendor_id}/change-tier POST /admin/subscriptions/{vendor_id}/override-limits POST /admin/subscriptions/{vendor_id}/extend-trial POST /admin/subscriptions/{vendor_id}/cancel ``` ### Vendor APIs ``` GET /vendor/billing/subscription # Current subscription GET /vendor/billing/tiers # Available tiers POST /vendor/billing/preview-change # Preview tier change POST /vendor/billing/change-tier # Request tier change POST /vendor/billing/checkout # Stripe checkout session GET /vendor/billing/addons # Available add-ons GET /vendor/billing/my-addons # Vendor's add-ons POST /vendor/billing/addons/purchase # Purchase add-on DELETE /vendor/billing/addons/{id} # Cancel add-on ``` --- ## 8. Questions to Resolve 1. **Trial without payment method?** - Allow full trial without card, or require card upfront? 2. **Downgrade handling:** - What happens if vendor has more products than new tier allows? - Block downgrade, or just prevent new products? 3. **Enterprise tier:** - Self-service or contact sales only? - Custom pricing in UI or hidden? 4. **Add-on provisioning:** - Domain: Use reseller API or manual process? - Email: Integrate with email provider or manual? 5. **Grace period:** - How long after payment failure before suspension? - What gets disabled first?