Files
aperonight/docs/payout-system-analysis.md
kbe 1889ee7fb2 feat: replace Stripe Global Payouts with manual bank transfer system for France compliance
- Replace Stripe automatic payouts with manual admin-processed bank transfers
- Add banking information fields (IBAN, bank name, account holder) to User model
- Implement manual payout workflow: pending → approved → processing → completed
- Add comprehensive admin interface for payout review and processing
- Update Payout model with manual processing fields and workflow methods
- Add transfer reference tracking and rejection/failure handling
- Consolidate all migration fragments into clean "create" migrations
- Add comprehensive documentation for manual payout workflow
- Fix Event payout_status enum definition and database column issues

This addresses France's lack of Stripe Global Payouts support by implementing
a complete manual bank transfer workflow while maintaining audit trails and
proper admin controls.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 11:55:07 +02:00

4.8 KiB

Payout System Analysis Report

Current Implementation Overview

The current payout system implemented on the feat/stripe-global-payouts branch uses Stripe Connect with Stripe Transfers to automatically process payouts to promoters. This implementation is not compatible with France as it relies on Stripe Global Payouts functionality.

Architecture Analysis

Core Components

  1. Models

    • Payout: Tracks payout requests with statuses (pending, processing, completed, failed)
    • User: Contains stripe_connected_account_id for Stripe Connect integration
    • Event: Has payout eligibility and earnings calculation methods
    • Earning: Tracks individual order earnings (referenced in docs but may not be fully implemented)
  2. Services

    • PayoutService (app/services/payout_service.rb:13-19): Processes payouts via Stripe::Transfer.create
    • StripeConnectService: Manages Stripe Connect account setup
  3. Controllers

    • Promoter::PayoutsController: Handles promoter payout requests and viewing
    • Admin::PayoutsController: Handles admin payout processing

Current Payout Flow

  1. Promoter Request: Promoter requests payout for ended event via Promoter::PayoutsController#create
  2. Admin Processing: Admin processes payout via Admin::PayoutsController#process
  3. Stripe Transfer: PayoutService creates Stripe::Transfer to promoter's connected account
  4. Status Update: Payout status updated to completed/failed based on Stripe response

Key Issues for France

  1. Stripe Global Payouts Dependency: The system uses Stripe::Transfer.create with destination: stripe_connected_account_id which requires Stripe Global Payouts
  2. Stripe Connect Requirement: Users must have verified Stripe Connect accounts (stripe_connected_account_id)
  3. Automatic Processing: System assumes automated Stripe processing capability

Database Schema

Payouts Table

  • amount_cents: Gross payout amount
  • fee_cents: Platform fees
  • status: Enum (pending, processing, completed, failed)
  • stripe_payout_id: Stripe transfer ID
  • total_orders_count: Number of orders included
  • refunded_orders_count: Number of refunded orders
  • user_id: Promoter receiving payout
  • event_id: Event for which payout is requested

Users Table (Relevant Fields)

  • stripe_connected_account_id: Stripe Connect account ID
  • is_professionnal: Required for event management

France-Specific Issues

  1. Stripe Global Payouts: Not available in France as of current analysis
  2. Banking Regulations: May require different approach for cross-border transfers
  3. Tax Reporting: Manual payouts may require additional documentation

Alternative Approaches Needed

  1. Manual Bank Transfers: Admin-initiated SEPA transfers
  2. Payout Request System: Promoters request, admins approve and process manually
  3. Documentation: Enhanced record-keeping for manual transfers

Recommendations

Immediate Actions Required

  1. Disable Automatic Processing: Remove Stripe Transfer functionality
  2. Implement Manual Workflow: Create admin interface for manual payout processing
  3. Add Banking Information: Collect IBAN/SWIFT details from promoters
  4. Update Status Flow: Modify payout statuses for manual processing

Proposed Manual Payout System

  1. Request Phase: Promoters submit payout requests (existing functionality can be kept)
  2. Review Phase: Admins review and approve requests
  3. Processing Phase: Admins mark as "processing" and initiate bank transfer
  4. Completion Phase: Admins confirm transfer completion manually

Migration Strategy

Phase 1: Immediate Fix

  • Disable automatic Stripe processing
  • Add manual processing interface for admins
  • Update payout status workflow

Phase 2: Enhanced Manual System

  • Add banking information collection
  • Implement approval workflow
  • Add transfer documentation features

Phase 3: Potential Automation

  • Investigate France-compatible payment providers
  • Implement API-based bank transfers if available
  • Maintain manual fallback option

Technical Debt

Files Requiring Updates

  • app/services/payout_service.rb: Remove Stripe Transfer logic
  • app/controllers/admin/payouts_controller.rb: Add manual processing actions
  • app/models/user.rb: Add banking information fields
  • Database migrations: Add IBAN/banking fields to users table

Testing Impact

  • Update test/services/payout_service_test.rb
  • Modify controller tests for manual workflow
  • Add integration tests for manual payout flow

Conclusion

The current Stripe Global Payouts implementation is not viable for France operations. A manual payout system must be implemented immediately to handle promoter payments through traditional banking methods while maintaining audit trails and proper documentation.