feat: implement payout system database schema and models

This commit is contained in:
kbe
2025-09-16 23:52:26 +02:00
parent e5ed1a34dd
commit 0399761fb3
23 changed files with 421 additions and 5 deletions

24
docs/promoter-payouts.md Normal file
View File

@@ -0,0 +1,24 @@
# Promoter Payouts Architecture
## Overview
To handle promoter payouts in the Rails app (where promoters are users creating events), track all order payments in the database for auditing and fee calculation. Save payments (e.g., via Stripe webhooks) and apply platform fees per order processed—e.g., promoter gets 90% of ticket revenue minus your fee, stored in a new `earnings` table linked to events/orders.
## Recommended Architecture
### 1. Models & DB
- Add `has_many :earnings, dependent: :destroy` to `Event` and `User` models.
- Create `Earnings` model: `belongs_to :event, :user; fields: amount_cents (Decimal), fee_cents (Decimal), status (enum: pending/paid), stripe_payout_id (String), order_id (ref)`.
- On order payment success (in your Stripe webhook or after_create callback on Order), create Earnings record: `earnings = event.earnings.create!(amount_cents: total_revenue_cents * 0.9, fee_cents: total_revenue_cents * 0.1, status: :pending, order: order)`.
### 2. Payout Processing
- Use Stripe Connect (setup promoter Stripe accounts via `account_links` in user onboarding).
- Create a `PayoutService`: Batch pending earnings per promoter, transfer via `Stripe::Transfer.create` to their connected account, update status to `:paid`.
- Run via cron job (e.g., in `lib/tasks/payouts.rake`) or admin-triggered job.
### 3. Admin Dashboard for Due Payouts
- Add admin routes: `resources :admin, only: [] do; resources :payouts; end` in `config/routes.rb`.
- Controller: `Admin::PayoutsController` with `index` action querying `Earnings.pending.where(user_id: params[:promoter_id]).group_by(&:user).sum(:amount_cents)`.
- View: Table showing promoter name, total due, unpaid earnings list; button to trigger payout.
- Use Pundit or CanCanCan for admin-only access (add `is_admin?` to User).
This ensures transparency, scalability, and easy auditing. Start by migrating the Earnings model: `rails g model Earnings event:references user:references order:references amount_cents:decimal fee_cents:decimal status:integer stripe_payout_id:string`. Test with Stripe test mode.