class EventsController < ApplicationController before_action :authenticate_user!, only: [:checkout, :payment_success, :download_ticket] before_action :set_event, only: [:show, :checkout] # Display all events def index @events = Event.includes(:user).upcoming.page(params[:page]).per(12) end # Display desired event def show # Event is set by set_event callback end # Handle checkout process - Create Stripe session def checkout cart_data = JSON.parse(params[:cart] || "{}") if cart_data.empty? redirect_to event_path(@event.slug, @event), alert: "Veuillez sélectionner au moins un billet" return end # Create order items from cart line_items = [] order_items = [] total_amount = 0 cart_data.each do |ticket_type_id, item| ticket_type = @event.ticket_types.find_by(id: ticket_type_id) next unless ticket_type quantity = item["quantity"].to_i next if quantity <= 0 # Check availability available = ticket_type.quantity - ticket_type.tickets.count if quantity > available redirect_to event_path(@event.slug, @event), alert: "Pas assez de billets disponibles pour #{ticket_type.name}" return end # Create Stripe line item line_items << { price_data: { currency: 'eur', product_data: { name: "#{@event.name} - #{ticket_type.name}", description: ticket_type.description, }, unit_amount: ticket_type.price_cents, }, quantity: quantity, } # Store for ticket creation order_items << { ticket_type_id: ticket_type.id, ticket_type_name: ticket_type.name, quantity: quantity, price_cents: ticket_type.price_cents } total_amount += ticket_type.price_cents * quantity end if order_items.empty? redirect_to event_path(@event.slug, @event), alert: "Commande invalide" return end begin # Create Stripe Checkout Session session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: line_items, mode: 'payment', success_url: payment_success_url(event_id: @event.id, session_id: '{CHECKOUT_SESSION_ID}'), cancel_url: event_url(@event.slug, @event), customer_email: current_user.email, metadata: { event_id: @event.id, user_id: current_user.id, order_items: order_items.to_json } }) redirect_to session.url, allow_other_host: true rescue Stripe::StripeError => e redirect_to event_path(@event.slug, @event), alert: "Erreur de traitement du paiement : #{e.message}" end end # Handle successful payment def payment_success session_id = params[:session_id] event_id = params[:event_id] begin session = Stripe::Checkout::Session.retrieve(session_id) if session.payment_status == 'paid' # Create tickets @event = Event.find(event_id) order_items = JSON.parse(session.metadata['order_items']) @tickets = [] order_items.each do |item| ticket_type = TicketType.find(item['ticket_type_id']) item['quantity'].times do ticket = Ticket.create!( user: current_user, ticket_type: ticket_type, status: 'active' ) @tickets << ticket # Send confirmation email for each ticket TicketMailer.purchase_confirmation(ticket).deliver_now end end render 'payment_success' else redirect_to event_path(@event.slug, @event), alert: "Le paiement n'a pas été complété avec succès" end rescue Stripe::StripeError => e redirect_to dashboard_path, alert: "Erreur lors du traitement de votre confirmation de paiement : #{e.message}" rescue => e redirect_to dashboard_path, alert: "Une erreur inattendue s'est produite : #{e.message}" end end # Download ticket PDF def download_ticket @ticket = current_user.tickets.find(params[:ticket_id]) respond_to do |format| format.pdf do pdf = @ticket.to_pdf send_data pdf, filename: "ticket-#{@ticket.event.name.parameterize}-#{@ticket.qr_code[0..7]}.pdf", type: 'application/pdf', disposition: 'attachment' end end end private def set_event @event = Event.find(params[:id]) end end