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:
Option A: Email Automation (Recommended)
- Trigger: Game date/time passes
- Delay: Wait X hours after game end (e.g., 4-24 hours)
- Email Sent: Automated email to league contact
- Action: League clicks “Approve Payment” button in email
- Webhook: Click sends webhook event to Edge Functions
- Release: Funds automatically released to referee
Option B: In-App Approval
- League Dashboard: View completed games requiring approval
- Manual Review: League confirms referee showed up
- In-App Button: Click “Approve Payment”
- 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
-
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
-
Escrow Management
- Use Stripe Connect for referee payouts
- Hold payments before release
- Implement automatic release trigger
-
Webhook Events
- Payment captured
- Payment released
- Payment failed
- Dispute created
-
Edge Function:
approve-payment-via-email- Receive webhook from email click
- Validate league authorization
- Release escrow funds
- Send confirmation emails
-
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
-
No Approval Given
- Auto-release after 7 days?
- Dispute escalation process?
-
Referee No-Show
- League disputes payment
- Refund to league
- Referee penalty system?
-
Multiple Games Same Day
- Individual approval per game
- Bulk approval option?
-
Partial Completion
- Referee leaves early
- Partial payment release?
-
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
- Design Stripe Connect escrow architecture
- Build dynamic product/price creation
- Implement approval webhook handlers
- Create email templates for approval flow
- Test end-to-end with production Stripe account