Skip to content

Merchant Integration - Plan of Action (POA) โ€‹

Document Version: 1.0
Date: 2026-01-11
Status: Planning Phase
Owner: Development Team


Executive Summary โ€‹

This document outlines the plan of action for integrating merchant signup, onboarding, and access to the Lantern merchant dashboard. The current application has merchant UI components (#/merchant, #/merchant/new) but lacks:

  1. Discovery mechanism - No way for merchants to learn about or access merchant features
  2. Authentication/authorization - No merchant-specific roles or access control
  3. Signup flow - No dedicated merchant registration process
  4. Integration point - Unclear whether merchant portal should be:
    • Same domain with role-based routing
    • Separate subdomain (merchant.ourlantern.app)
    • Settings panel within main app

Decision: Architecture Approach โ€‹

Phase 1 (Pilot - Current): Role-based routing on same domain

  • Why: Fastest to implement, leverages existing Firebase Auth
  • How: Add merchant role to user profiles, conditional routing based on role
  • Timeline: 1-2 weeks
  • Perfect for: San Diego pilot with 5-10 merchants

Phase 2 (Post-Pilot - 6+ months): Separate merchant subdomain

  • Why: Clear separation, professional branding, independent deployment
  • How: Deploy separate merchant portal at merchant.ourlantern.app
  • Timeline: 2-4 weeks
  • Trigger: When merchant count > 25 OR when building dedicated merchant mobile apps

Why Not Start with Separate Subdomain? โ€‹

  1. Over-engineering for pilot: 5-10 merchants don't need enterprise infrastructure
  2. Auth complexity: Need to sync auth across domains or implement SSO
  3. Development overhead: Two deployment pipelines, two build processes
  4. Slower iteration: Changes require coordinating across two codebases

Phase 1: Pilot Implementation Plan โ€‹

1. Data Model Changes โ€‹

User Profile Enhancement โ€‹

javascript
// Add to existing user profile schema in Firestore
{
  uid: "user123",
  email: "merchant@example.com",
  lanternName: "Sunny Cafe Owner",
  role: "merchant", // NEW: "user" | "merchant" | "admin"
  merchantProfile: { // NEW: Optional merchant-specific data
    businessName: "Sunny Cafe",
    venueId: "venue_xyz", // Link to venue in venues collection
    businessType: "cafe", // cafe, bar, restaurant, retail, etc.
    approved: true, // Manual approval flag
    onboardedAt: "2026-01-11T06:00:00Z"
  }
  // ... existing profile fields
}

Merchant Applications Collection โ€‹

javascript
// New collection: merchant_applications
{
  id: "app_123",
  applicantEmail: "merchant@example.com",
  applicantName: "John Doe",
  businessName: "Sunny Cafe",
  venueAddress: "123 Main St, San Diego, CA",
  businessType: "cafe",
  phoneNumber: "+1234567890",
  message: "I'd love to bring more customers in...",
  status: "pending", // pending | approved | rejected
  appliedAt: "2026-01-11T06:00:00Z",
  reviewedAt: null,
  reviewedBy: null,
  notes: "" // Admin notes
}

2. User-Facing Changes (Discovery & CTA) โ€‹

Location: src/screens/dashboard/Dashboard.jsx bottom section
Design: Subtle, non-intrusive banner

jsx
{/* Merchant CTA - Bottom of dashboard */}
<div className="bg-gradient-to-r from-amber-500/10 to-orange-500/10 border border-amber-500/20 rounded-2xl p-6 mt-8">
  <div className="flex items-center justify-between gap-4 flex-wrap">
    <div>
      <h3 className="text-lg font-semibold text-white mb-1">
        Own a bar, cafe, or restaurant?
      </h3>
      <p className="text-zinc-300 text-sm">
        Bring more customers through your doors with Lantern merchant offers.
      </p>
    </div>
    <button
      onClick={() => window.location.hash = '#/merchant/signup'}
      className="bg-amber-500 text-black px-6 py-3 rounded-xl font-semibold hover:bg-amber-400 transition whitespace-nowrap"
    >
      Sign Up as Merchant
    </button>
  </div>
</div>

Rationale:

  • Non-intrusive placement (bottom, after main content)
  • Clear value proposition
  • Direct CTA
  • Matches existing Lantern design language

Location: src/screens/profile/ProfileSettings.jsx
Design: Collapsible "Merchant Access" section at bottom

jsx
{/* In ProfileSettings component, after main sections */}
<div className="bg-white/5 border border-white/10 rounded-2xl p-6">
  <h3 className="text-lg font-semibold text-white mb-2">
    Business Owner?
  </h3>
  <p className="text-zinc-400 text-sm mb-4">
    If you own or manage a venue, you can apply for merchant access to create offers and track engagement.
  </p>
  <button
    onClick={() => window.location.hash = '#/merchant/signup'}
    className="text-amber-400 hover:text-amber-300 text-sm font-medium"
  >
    Learn more about merchant features โ†’
  </button>
</div>

3. Merchant Signup Flow โ€‹

New Route: #/merchant/signup โ€‹

Location: src/screens/merchant/MerchantSignup.jsx (NEW FILE)

Flow:

  1. Introduction screen - Explain merchant benefits, pricing, pilot offer
  2. Application form - Collect business info (name, address, type, contact)
  3. Submission confirmation - "We'll review and email you within 48 hours"
  4. Manual review - Admin reviews application, creates merchant account
  5. Welcome email - Send login credentials + merchant dashboard link

Why manual approval for pilot?

  • Quality control (only serious merchants)
  • Relationship building (personal touch)
  • Fraud prevention (verify business legitimacy)
  • Low volume (5-10 merchants = manageable)

Form Fields โ€‹

javascript
{
  applicantName: string, // Contact person
  applicantEmail: string, // Primary contact (becomes login)
  businessName: string,
  venueAddress: string, // Full address
  businessType: select, // cafe | bar | restaurant | retail | other
  phoneNumber: string,
  website: string (optional),
  existingVenue: boolean, // "Is your venue already on Lantern?"
  venueId: string (optional), // If yes, link to existing venue
  message: textarea, // "Tell us why you want to join" (optional)
  agreeToTerms: boolean
}

4. Access Control & Routing โ€‹

App.jsx Changes โ€‹

jsx
// Add merchant role check
const isMerchant = currentUser && userProfile?.role === 'merchant'

// Conditional routing
{route === '#/merchant' && (
  isMerchant ? (
    <MerchantDashboard />
  ) : (
    <div className="min-h-screen bg-black flex items-center justify-center px-4">
      <div className="max-w-md text-center">
        <h2 className="text-2xl font-bold text-white mb-4">Merchant Access Required</h2>
        <p className="text-neutral-400 mb-6">
          You need merchant access to view this page.
        </p>
        <button
          onClick={() => window.location.hash = '#/merchant/signup'}
          className="bg-amber-400 text-black px-6 py-3 rounded-lg font-medium"
        >
          Apply for Merchant Access
        </button>
      </div>
    </div>
  )
)}

{route === '#/merchant/new' && (
  isMerchant ? (
    <OfferForm />
  ) : (
    // Same access denied UI
  )
)}

{route === '#/merchant/signup' && <MerchantSignup />}

5. Admin Review Process โ€‹

Admin Dashboard (Future) โ€‹

Route: #/admin/merchant-applications
For now: Manual Firestore Console review

Manual Approval Workflow (Pilot):

  1. Merchant submits application โ†’ Document created in merchant_applications
  2. Admin receives notification (email via Cloud Function)
  3. Admin reviews in Firestore Console:
    • Check business legitimacy (Google Maps, website)
    • Verify contact info
    • Approve or reject
  4. If approved:
    • Update user profile: add role: "merchant", merchantProfile: {...}
    • Send welcome email with dashboard link
  5. If rejected:
    • Update application status, add rejection reason in notes
    • Send polite rejection email with feedback

Automation (Post-Pilot):

  • Cloud Function to send notification emails
  • Admin UI to approve/reject with one click
  • Automated welcome email with personalized onboarding checklist

6. Firestore Security Rules โ€‹

javascript
// firestore.rules additions

// Merchant applications - anyone can create, only admins can read all
match /merchant_applications/{applicationId} {
  allow create: if request.auth != null;
  allow read: if request.auth.token.role == 'admin'
                || resource.data.applicantEmail == request.auth.token.email;
  allow update, delete: if request.auth.token.role == 'admin';
}

// User profiles - enhance to check merchant role
match /users/{userId} {
  allow read: if request.auth != null;
  allow write: if request.auth.uid == userId
                  && (!request.resource.data.diff(resource.data).affectedKeys().hasAny(['role', 'merchantProfile']))
                  || request.auth.token.role == 'admin'; // Only admins can change role
}

Phase 2: Separate Merchant Portal (Post-Pilot) โ€‹

When to Implement โ€‹

  • Trigger 1: Merchant count > 25
  • Trigger 2: Building dedicated merchant mobile apps
  • Trigger 3: Need for merchant-specific analytics/features diverges significantly from user app

Architecture โ€‹

ourlantern.app           โ†’ User app (current)
merchant.ourlantern.app  โ†’ Merchant portal (new)
api.ourlantern.app       โ†’ Shared API/backend (Firebase Functions)

Benefits โ€‹

  1. Professional branding - merchant.ourlantern.app feels more serious
  2. Independent deployment - Update merchant features without affecting user app
  3. Performance - Smaller bundle size for each app
  4. SEO - Separate marketing/SEO for merchant audience

Implementation Steps โ€‹

  1. Create new Vite project in /merchant-portal directory
  2. Set up Cloudflare Pages project for merchant.ourlantern.app
  3. Implement SSO with Firebase Auth (same auth domain)
  4. Migrate merchant screens to new portal
  5. Build merchant-specific features (advanced analytics, multi-venue management)
  6. Redirect #/merchant routes to merchant portal

Timeline & Milestones โ€‹

Week 1: Foundation โ€‹

  • [x] Create POA document (this document)
  • [ ] Update TODO.md with merchant integration tasks
  • [ ] Design merchant signup UI mockups
  • [ ] Update Firestore schema and security rules

Week 2: Implementation โ€‹

  • [ ] Build MerchantSignup.jsx component
  • [ ] Add merchant CTA to Dashboard footer
  • [ ] Add merchant role to user profile service
  • [ ] Implement access control in App.jsx
  • [ ] Test signup โ†’ approval โ†’ access flow

Week 3: Admin & Testing โ€‹

  • [ ] Create manual approval workflow documentation
  • [ ] Set up notification emails (Cloud Function)
  • [ ] Test end-to-end with 2-3 real merchant applications
  • [ ] Create merchant onboarding guide documentation

Week 4: Launch Readiness โ€‹

  • [ ] Create merchant welcome email template
  • [ ] Document merchant support process
  • [ ] Add merchant FAQ section
  • [ ] Soft launch to partner network (5 merchants)

Risks & Mitigations โ€‹

Risk 1: Low Merchant Signup Rate โ€‹

Mitigation:

  • Personal outreach via partner's network
  • Clear value prop in CTA (free pilot, no upfront cost)
  • Testimonials from early merchants

Risk 2: Manual Approval Bottleneck โ€‹

Mitigation:

  • SLA: Review applications within 48 hours
  • Automated email notifications
  • Simple approve/reject process (no complex workflows)

Risk 3: User Confusion (Merchant CTA Spam) โ€‹

Mitigation:

  • Single, subtle CTA in footer (not intrusive)
  • Only show to non-merchants
  • A/B test placement and copy

Risk 4: Role-Based Auth Complexity โ€‹

Mitigation:

  • Use Firebase Custom Claims (built-in role support)
  • Simple role check: userProfile.role === 'merchant'
  • Document clearly in code comments

Success Metrics (Pilot Phase) โ€‹

Merchant Acquisition โ€‹

  • Target: 5-10 approved merchants in 90 days
  • Measure: Applications submitted, approval rate, time-to-approval

Merchant Engagement โ€‹

  • Target: 70%+ of merchants create at least 1 offer
  • Measure: Offers created, active merchants (logged in last 30 days)

User Awareness โ€‹

  • Target: 5%+ click-through on merchant CTA
  • Measure: CTA impressions, clicks, conversion to application

Operational Health โ€‹

  • Target: < 48hr approval SLA, < 5% rejection rate
  • Measure: Avg time-to-approval, rejection reasons

Open Questions & Decisions Needed โ€‹

  1. Pricing during pilot?

    • Recommendation: Free pilot (no payment integration yet)
    • Document pricing in welcome email ("free for 90 days, then $150/month")
  2. Merchant verification?

    • Recommendation: Manual for pilot (Google Maps check, website verification)
    • Automate post-pilot with business license API
  3. Multi-venue support?

    • Recommendation: Single venue for pilot
    • Add multi-venue in Phase 2 when needed
  4. Merchant analytics?

    • Recommendation: Basic metrics already in MerchantDashboard
    • Enhance post-pilot based on feedback


Changelog โ€‹

  • 2026-01-11: Initial POA creation

Built with VitePress