feat(payouts): implement promoter earnings viewing, request flow, and admin Stripe processing with webhooks
Add model methods for accurate net calculations (€0.50 + 1.5% fees), eligibility, refund handling Update promoter/payouts controller for index (pending events), create (eligibility checks) Integrate admin processing via Stripe::Transfer, webhook for status sync Enhance views: index pending cards, events/show preview/form Add comprehensive tests (models, controllers, service, integration); run migrations
This commit is contained in:
@@ -277,7 +277,7 @@
|
||||
<i data-lucide="ticket" class="w-4 h-4 mr-2"></i>
|
||||
Gérer les types de billets
|
||||
<% end %>
|
||||
|
||||
|
||||
<% if @event.sold_out? %>
|
||||
<%= button_to mark_available_promoter_event_path(@event), method: :patch, class: "w-full inline-flex items-center justify-center px-4 py-3 bg-blue-50 text-blue-700 font-medium text-sm rounded-lg hover:bg-blue-100 transition-colors duration-200" do %>
|
||||
<i data-lucide="refresh-ccw" class="w-4 h-4 mr-2"></i>
|
||||
@@ -289,76 +289,9 @@
|
||||
Marquer comme complet
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<!-- Payout section -->
|
||||
<% if @event.event_ended? && @event.can_request_payout? %>
|
||||
<hr class="border-gray-200">
|
||||
<div class="space-y-4">
|
||||
<h4 class="text-lg font-medium text-gray-900">Paiement des Revenus</h4>
|
||||
|
||||
<!-- Earnings Summary -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||
<div class="bg-gray-50 rounded-lg p-4">
|
||||
<p class="text-sm text-gray-500">Revenus Bruts</p>
|
||||
<p class="text-lg font-bold text-gray-900">€<%= @event.total_earnings_cents / 100.0 %></p>
|
||||
</div>
|
||||
<%= render 'earnings_preview' %>
|
||||
|
||||
<div class="bg-gray-50 rounded-lg p-4">
|
||||
<p class="text-sm text-gray-500">Frais Plateforme</p>
|
||||
<p class="text-lg font-bold text-gray-900">-€<%= @event.total_fees_cents / 100.0 %></p>
|
||||
</div>
|
||||
|
||||
<div class="payout-summary-card">
|
||||
<p class="payout-summary-label">Revenus Nets</p>
|
||||
<p class="payout-summary-amount">€<%= @event.net_earnings_cents / 100.0 %></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payout Status -->
|
||||
<% if @event.payout_status != "not_requested" %>
|
||||
<div class="bg-blue-50 rounded-lg p-4 border border-blue-200">
|
||||
<div class="flex items-center">
|
||||
<% case @event.payout_status %>
|
||||
<% when "requested" %>
|
||||
<i data-lucide="clock" class="w-5 h-5 text-blue-500 mr-2"></i>
|
||||
<span class="font-medium text-blue-800">Paiement Demandé</span>
|
||||
<% when "processing" %>
|
||||
<i data-lucide="refresh-cw" class="w-5 h-5 text-blue-500 mr-2"></i>
|
||||
<span class="font-medium text-blue-800">Paiement en Traitement</span>
|
||||
<% when "completed" %>
|
||||
<i data-lucide="check-circle" class="w-5 h-5 text-green-500 mr-2"></i>
|
||||
<span class="font-medium text-green-800">Paiement Complété</span>
|
||||
<% when "failed" %>
|
||||
<i data-lucide="x-circle" class="w-5 h-5 text-red-500 mr-2"></i>
|
||||
<span class="font-medium text-red-800">Paiement Échoué</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mt-1">Votre demande de paiement est en cours de traitement. Vous recevrez un email quand elle sera terminée.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Payout Action -->
|
||||
<% if @event.payout_status == "not_requested" %>
|
||||
<%= button_to promoter_payouts_path(event_id: @event.id), method: :post,
|
||||
data: { confirm: "Êtes-vous sûr de vouloir demander un paiement de €#{@event.net_earnings_cents / 100.0} ? Cette action ne peut pas être annulée." },
|
||||
class: "payout-action-button primary" do %>
|
||||
<i data-lucide="dollar-sign" class="w-5 h-5 mr-2"></i>
|
||||
Demander le Paiement de €<%= @event.net_earnings_cents / 100.0 %>
|
||||
<% end %>
|
||||
<% elsif @event.payout_status == "failed" %>
|
||||
<%= button_to promoter_payouts_path(event_id: @event.id), method: :post,
|
||||
data: { confirm: "Êtes-vous sûr de vouloir demander un nouveau paiement de €#{@event.net_earnings_cents / 100.0} ?" },
|
||||
class: "payout-action-button warning" do %>
|
||||
<i data-lucide="refresh-ccw" class="w-5 h-5 mr-2"></i>
|
||||
Réessayer le Paiement
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= link_to "Voir les Détails du Paiement", promoter_payouts_path,
|
||||
class: "payout-action-button secondary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<hr class="border-gray-200">
|
||||
<%= button_to promoter_event_path(@event), method: :delete,
|
||||
data: { confirm: "Êtes-vous sûr de vouloir supprimer cet événement ? Cette action est irréversible." },
|
||||
|
||||
Reference in New Issue
Block a user