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>
This commit is contained in:
112
docs/payout-system-analysis.md
Normal file
112
docs/payout-system-analysis.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# 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
|
||||
|
||||
## Compliance and Legal Considerations
|
||||
|
||||
### 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.
|
||||
Reference in New Issue
Block a user