@ -1,7 +1,6 @@
from django . shortcuts import get_object_or_404 , redirect
from django . shortcuts import get_object_or_404
from django . conf import settings
from django . conf import settings
from django . urls import reverse
from django . urls import reverse
from django . contrib import messages
import stripe
import stripe
from . . models import TeamRegistration , PlayerRegistration , Tournament
from . . models import TeamRegistration , PlayerRegistration , Tournament
@ -26,6 +25,19 @@ class PaymentService:
stripe . api_key = self . stripe_api_key
stripe . api_key = self . stripe_api_key
tournament = get_object_or_404 ( Tournament , id = tournament_id )
tournament = get_object_or_404 ( Tournament , id = tournament_id )
# Check if payments are enabled for this tournament
if not tournament . should_request_payment ( ) :
raise Exception ( " Les paiements ne sont pas activés pour ce tournoi. " )
# Get the umpire's Stripe account ID
stripe_account_id = tournament . stripe_account_id
if not stripe_account_id :
raise Exception ( " L ' arbitre n ' a pas configuré son compte Stripe. " )
# Calculate commission
commission_rate = tournament . effective_commission_rate ( ) / 100
platform_amount = int ( ( team_fee * commission_rate ) * 100 ) # Commission in cents
# Get user email if authenticated
# Get user email if authenticated
customer_email = self . request . user . email if self . request . user . is_authenticated else None
customer_email = self . request . user . email if self . request . user . is_authenticated else None
@ -60,6 +72,12 @@ class PaymentService:
reverse ( ' tournament-payment-success ' , kwargs = { ' tournament_id ' : tournament_id } )
reverse ( ' tournament-payment-success ' , kwargs = { ' tournament_id ' : tournament_id } )
) ,
) ,
' cancel_url ' : cancel_url ,
' cancel_url ' : cancel_url ,
' payment_intent_data ' : {
' application_fee_amount ' : platform_amount ,
' transfer_data ' : {
' destination ' : stripe_account_id ,
} ,
} ,
' metadata ' : {
' metadata ' : {
' tournament_id ' : str ( tournament_id ) , # Convert UUID to string
' tournament_id ' : str ( tournament_id ) , # Convert UUID to string
' user_id ' : str ( self . request . user . id ) if self . request . user . is_authenticated else None , # Convert UUID to string
' user_id ' : str ( self . request . user . id ) if self . request . user . is_authenticated else None , # Convert UUID to string
@ -79,6 +97,7 @@ class PaymentService:
checkout_session_params [ ' customer_email ' ] = customer_email
checkout_session_params [ ' customer_email ' ] = customer_email
# Create the checkout session
# Create the checkout session
try :
checkout_session = stripe . checkout . Session . create ( * * checkout_session_params )
checkout_session = stripe . checkout . Session . create ( * * checkout_session_params )
# Store checkout session ID and source page in session
# Store checkout session ID and source page in session
@ -87,6 +106,12 @@ class PaymentService:
self . request . session . modified = True
self . request . session . modified = True
return checkout_session
return checkout_session
except stripe . error . StripeError as e :
# Handle specific Stripe errors more gracefully
if ' destination ' in str ( e ) :
raise Exception ( " Erreur avec le compte Stripe de l ' arbitre. Contactez l ' administrateur. " )
else :
raise Exception ( f " Erreur Stripe: { str ( e ) } " )
def process_successful_payment ( self , tournament_id , checkout_session ) :
def process_successful_payment ( self , tournament_id , checkout_session ) :
"""
"""
@ -191,3 +216,53 @@ class PaymentService:
player_reg . save ( )
player_reg . save ( )
return True
return True
def process_refund ( self , team_registration_id ) :
"""
Process a refund for a tournament registration as part of unregistration
Returns a tuple ( success , message )
"""
stripe . api_key = self . stripe_api_key
try :
# Get the team registration
team_registration = get_object_or_404 ( TeamRegistration , id = team_registration_id )
tournament = team_registration . tournament
# Check if refund is possible for this tournament
if not tournament . is_refund_possible ( ) :
return False , " Les remboursements ne sont plus possibles pour ce tournoi. " , None
# Get payment ID from player registrations
player_registrations = PlayerRegistration . objects . filter ( team_registration = team_registration )
payment_id = None
for player_reg in player_registrations :
# Find the first valid payment ID
if player_reg . payment_id and player_reg . payment_type == PlayerPaymentType . CREDIT_CARD :
payment_id = player_reg . payment_id
break
if not payment_id :
return False , " Aucun paiement trouvé pour cette équipe. " , None
# Get the Stripe payment intent
payment_intent = stripe . PaymentIntent . retrieve ( payment_id )
if payment_intent . status != ' succeeded ' :
return False , " Le paiement n ' a pas été complété, il ne peut pas être remboursé. " , None
# Process the refund
refund = stripe . Refund . create (
payment_intent = payment_id ,
refund_application_fee = True ,
reverse_transfer = True
)
# Return success with refund object
return True , " Votre inscription a été remboursée automatiquement. " , refund
except stripe . error . StripeError as e :
return False , f " Erreur de remboursement Stripe: { str ( e ) } " , None
except Exception as e :
return False , f " Erreur lors du remboursement: { str ( e ) } " , None