Reffi App - Payment Flow Specification

Source

Extracted from conversation with Ron Berry III on December 11, 2025

💰 Payment Model Overview

Platform Type: Two-sided marketplace

  • Payers: Teams/Leagues
  • Payees: Referees
  • Platform Fee: 10% (timing TBD: day one or 6 months later)

🔄 Complete Payment Flow

1. Referee Rate Setting

  • Flexible Pricing: Referees set their own rates per game (similar to Upwork)
  • Variable Rates: Different rates for different:
    • Sports types
    • Leagues
    • Individual games
    • Special circumstances (holidays, premium events)
  • Profile Rate: Display rate in profile as starting point
  • Application Rate: Can adjust rate when applying to specific games

Rate Example

Referee’s profile shows $35/game, but can charge:

  • $35 for local youth soccer
  • $50 for competitive basketball
  • $75 for holiday tournament

2. League Posts Game Listing

  • Single Game: One-time game posting
  • Season Listing: Multiple games (needs to be flushed out)
  • Per-Game Pricing: Each game is individually priced
  • Referee Hiring: Direct hire per game

3. Referee Application

  • Custom Rate: Referee can propose different rate when applying
  • League Review: League reviews application and proposed rate
  • Acceptance Trigger: Payment event

4. Payment Capture (Escrow)

Trigger: League accepts referee application

Critical Flow

Payment is captured UPFRONT when league accepts the application

Payment Amount: Full game rate (e.g., $35) Stripe Action: Payment held in escrow Duration: Until job completion confirmed

Multi-Game Scenario

If referee signs on for 3 games at $35 each:

  • 3 separate charges of $35
  • Each held in escrow independently
  • Released individually after each game completion

5. Escrow Period

Start: League accepts application During: Funds held by platform End: Job completion confirmed

6. Job Completion Confirmation

Confirmation Flow (December 11 Discussion)

Two approval methods discussed:

  1. Trigger: Game date/time passes
  2. Delay: Wait X hours after game end (e.g., 4-24 hours)
  3. Email Sent: Automated email to league contact
  4. Action: League clicks “Approve Payment” button in email
  5. Webhook: Click sends webhook event to Edge Functions
  6. Release: Funds automatically released to referee

Option B: In-App Approval

  1. League Dashboard: View completed games requiring approval
  2. Manual Review: League confirms referee showed up
  3. In-App Button: Click “Approve Payment”
  4. Release: Funds released to referee

Hybrid Approach

Implement both methods:

  • Email for convenience (most users)
  • In-app for leagues who prefer manual control

7. Payment Release

Trigger: League confirmation (email or in-app) Action: Stripe releases funds from escrow Destination: Referee’s connected Stripe account Platform Fee: Deducted during release (when active)

Payment Breakdown (with 10% fee)

  • Game Rate: $35.00
  • Platform Fee (10%): $3.50
  • Referee Receives: $31.50
  • Platform Revenue: $3.50

🔧 Technical Implementation Requirements

Stripe Configuration Needed

  1. Dynamic Product Creation

    • Create Stripe product per game listing
    • Variable pricing based on referee’s accepted rate
    • Metadata: game_id, referee_id, league_id, sport_type
  2. Escrow Management

    • Use Stripe Connect for referee payouts
    • Hold payments before release
    • Implement automatic release trigger
  3. Webhook Events

    • Payment captured
    • Payment released
    • Payment failed
    • Dispute created
  4. Edge Function: approve-payment-via-email

    • Receive webhook from email click
    • Validate league authorization
    • Release escrow funds
    • Send confirmation emails
  5. Edge Function: approve-payment-in-app

    • Validate league permissions
    • Release escrow funds
    • Log approval action

Database Schema Updates Needed

-- Payment tracking
CREATE TABLE payments (
  id UUID PRIMARY KEY,
  game_id UUID REFERENCES games,
  referee_id UUID REFERENCES referees,
  league_id UUID REFERENCES leagues,
  amount DECIMAL,
  platform_fee DECIMAL,
  referee_payout DECIMAL,
  status TEXT, -- 'pending', 'in_escrow', 'released', 'disputed'
  stripe_payment_intent_id TEXT,
  captured_at TIMESTAMPTZ,
  released_at TIMESTAMPTZ,
  approval_method TEXT, -- 'email', 'in_app'
  approved_by UUID
);

🚀 Deployment Phases

Phase 1: Free Beta (Launch - 6 months)

  • Platform Fee: 0%
  • Testing: Real transactions with $0 platform cut
  • Goal: Validate payment flow, gather feedback

Phase 2: Monetization (6+ months)

  • Platform Fee: 10% activated
  • Implementation: Update payment release logic
  • Communication: Notify users 30 days in advance

📊 Payment Flow Diagram

[Referee Sets Rate] → [League Posts Game] → [Referee Applies with Rate]
       ↓
[League Accepts] → [Payment Captured to Escrow] → [Game Occurs]
       ↓
[Auto Email Sent] → [League Clicks Approve] → [Webhook Triggered]
       ↓
[Funds Released] → [Platform Fee Deducted] → [Referee Receives Payment]

⚠️ Edge Cases to Handle

  1. No Approval Given

    • Auto-release after 7 days?
    • Dispute escalation process?
  2. Referee No-Show

    • League disputes payment
    • Refund to league
    • Referee penalty system?
  3. Multiple Games Same Day

    • Individual approval per game
    • Bulk approval option?
  4. Partial Completion

    • Referee leaves early
    • Partial payment release?
  5. League Cancellation

    • Refund timing
    • Cancellation fee for referee?

🔐 Security Considerations

  • Webhook Signature Verification: Validate all Stripe webhooks
  • Authorization Checks: Only league that hired can approve
  • Audit Logging: Log all payment state changes
  • Fraud Detection: Monitor unusual approval patterns

Next Steps

  1. Design Stripe Connect escrow architecture
  2. Build dynamic product/price creation
  3. Implement approval webhook handlers
  4. Create email templates for approval flow
  5. Test end-to-end with production Stripe account