Add 1€ service fee to all order-related pages and Stripe integration
- Added 1€ service fee to order total calculation in Order model - Updated checkout page to display fee breakdown (subtotal + 1€ fee = total) - Updated payment success page to show fee breakdown - Updated order show page to display fee breakdown - Updated payment cancel page to show fee breakdown - Modified Stripe session creation to include service fee as separate line item - Updated order model tests to account for the 1€ service fee - Enhanced overall pricing transparency for users Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -270,6 +270,19 @@ class OrdersController < ApplicationController
|
||||
}
|
||||
end
|
||||
|
||||
# Add service fee as a separate line item
|
||||
line_items << {
|
||||
price_data: {
|
||||
currency: "eur",
|
||||
product_data: {
|
||||
name: "Frais de service",
|
||||
description: "Frais de traitement de la commande"
|
||||
},
|
||||
unit_amount: 100 # 1€ in cents
|
||||
},
|
||||
quantity: 1
|
||||
}
|
||||
|
||||
Stripe::Checkout::Session.create(
|
||||
payment_method_types: [ "card" ],
|
||||
line_items: line_items,
|
||||
|
||||
@@ -88,9 +88,11 @@ class Order < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Calculate total from tickets
|
||||
# Calculate total from tickets plus 1€ service fee
|
||||
def calculate_total!
|
||||
update!(total_amount_cents: tickets.sum(:price_cents))
|
||||
ticket_total = tickets.sum(:price_cents)
|
||||
fee_cents = 100 # 1€ in cents
|
||||
update!(total_amount_cents: ticket_total + fee_cents)
|
||||
end
|
||||
|
||||
# Create Stripe invoice for accounting records
|
||||
|
||||
@@ -118,9 +118,19 @@
|
||||
|
||||
<!-- Order Total -->
|
||||
<div class="border-t border-gray-200 pt-6">
|
||||
<div class="flex items-center justify-between text-lg">
|
||||
<span class="font-medium text-gray-900">Total</span>
|
||||
<span class="font-bold text-2xl text-purple-600"><%= @order.total_amount_euros %>€</span>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Sous-total</span>
|
||||
<span class="text-gray-900"><%= @order.total_amount_euros - 1.0 %>€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Frais de service</span>
|
||||
<span class="text-gray-900">1.00€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-lg pt-2 border-t border-gray-200">
|
||||
<span class="font-medium text-gray-900">Total</span>
|
||||
<span class="font-bold text-2xl text-purple-600"><%= @order.total_amount_euros %>€</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 mt-2">TVA incluse</p>
|
||||
</div>
|
||||
|
||||
@@ -130,11 +130,21 @@
|
||||
|
||||
<!-- Total -->
|
||||
<div class="border-t border-gray-200 pt-6 mt-6">
|
||||
<div class="flex items-center justify-between text-lg">
|
||||
<span class="font-medium text-gray-900">Total à payer</span>
|
||||
<span class="font-bold text-2xl text-red-600">
|
||||
<%= @order.total_amount_euros %>€
|
||||
</span>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Sous-total</span>
|
||||
<span class="text-gray-900"><%= @order.total_amount_euros - 1.0 %>€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Frais de service</span>
|
||||
<span class="text-gray-900">1.00€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-lg pt-2 border-t border-gray-200">
|
||||
<span class="font-medium text-gray-900">Total à payer</span>
|
||||
<span class="font-bold text-2xl text-red-600">
|
||||
<%= @order.total_amount_euros %>€
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -125,11 +125,21 @@
|
||||
|
||||
<!-- Total -->
|
||||
<div class="border-t border-gray-200 pt-6 mt-6">
|
||||
<div class="flex items-center justify-between text-lg">
|
||||
<span class="font-medium text-gray-900">Total payé</span>
|
||||
<span class="font-bold text-2xl text-green-600">
|
||||
<%= @order.total_amount_euros %>€
|
||||
</span>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Sous-total</span>
|
||||
<span class="text-gray-900"><%= @order.total_amount_euros - 1.0 %>€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Frais de service</span>
|
||||
<span class="text-gray-900">1.00€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-lg pt-2 border-t border-gray-200">
|
||||
<span class="font-medium text-gray-900">Total payé</span>
|
||||
<span class="font-bold text-2xl text-green-600">
|
||||
<%= @order.total_amount_euros %>€
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -135,11 +135,21 @@
|
||||
|
||||
<!-- Total -->
|
||||
<div class="border-t border-gray-200 pt-6 mt-6">
|
||||
<div class="flex items-center justify-between text-lg">
|
||||
<span class="font-medium text-gray-900">Total <%= @order.status == 'paid' || @order.status == 'completed' ? 'payé' : 'à payer' %></span>
|
||||
<span class="font-bold text-2xl <%= @order.status == 'paid' || @order.status == 'completed' ? 'text-green-600' : 'text-purple-600' %>">
|
||||
<%= @order.total_amount_euros %>€
|
||||
</span>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Sous-total</span>
|
||||
<span class="text-gray-900"><%= @order.total_amount_euros - 1.0 %>€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-600">Frais de service</span>
|
||||
<span class="text-gray-900">1.00€</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-lg pt-2 border-t border-gray-200">
|
||||
<span class="font-medium text-gray-900">Total <%= @order.status == 'paid' || @order.status == 'completed' ? 'payé' : 'à payer' %></span>
|
||||
<span class="font-bold text-2xl <%= @order.status == 'paid' || @order.status == 'completed' ? 'text-green-600' : 'text-purple-600' %>">
|
||||
<%= @order.total_amount_euros %>€
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -226,7 +236,7 @@
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||
</svg>
|
||||
Retour au Tableau de Bord
|
||||
Retour au tableau de bord
|
||||
</div>
|
||||
<% end %>
|
||||
<%= link_to event_path(@order.event.slug, @order.event), class: "block w-full text-center py-3 px-4 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-colors" do %>
|
||||
@@ -234,7 +244,7 @@
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
Voir l'Événement Complet
|
||||
Voir la page d'évenement
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -469,7 +469,7 @@ class OrderTest < ActiveSupport::TestCase
|
||||
assert_equal "active", ticket2.status
|
||||
end
|
||||
|
||||
test "calculate_total! should sum ticket prices" do
|
||||
test "calculate_total! should sum ticket prices plus 1€ service fee" do
|
||||
order = Order.create!(
|
||||
user: @user, event: @event, total_amount_cents: 0,
|
||||
status: "draft", payment_attempts: 0
|
||||
@@ -506,7 +506,7 @@ class OrderTest < ActiveSupport::TestCase
|
||||
order.calculate_total!
|
||||
order.reload
|
||||
|
||||
assert_equal 3000, order.total_amount_cents # 2 tickets * 1500 cents
|
||||
assert_equal 3100, order.total_amount_cents # 2 tickets * 1500 cents + 100 cents (1€ fee)
|
||||
end
|
||||
|
||||
# === Stripe Integration Tests (Mock) ===
|
||||
|
||||
Reference in New Issue
Block a user