diff --git a/padelclub_backend/settings_local.py.dist b/padelclub_backend/settings_local.py.dist index f983539..5a4dc7c 100644 --- a/padelclub_backend/settings_local.py.dist +++ b/padelclub_backend/settings_local.py.dist @@ -42,6 +42,7 @@ STRIPE_PUBLISHABLE_KEY = '' STRIPE_SECRET_KEY = '' SHOP_STRIPE_WEBHOOK_SECRET = 'whsec_...' # Your existing webhook secret TOURNAMENT_STRIPE_WEBHOOK_SECRET = 'whsec_...' # New webhook secret for tournaments +XLR_STRIPE_WEBHOOK_SECRET = 'whsec_...' # New webhook secret for padel club STRIPE_FEE = 0.0075 TOURNAMENT_SETTINGS = { 'TIME_PROXIMITY_RULES': { diff --git a/tournaments/services/payment_service.py b/tournaments/services/payment_service.py index 20049bd..8c99a5e 100644 --- a/tournaments/services/payment_service.py +++ b/tournaments/services/payment_service.py @@ -592,20 +592,32 @@ class PaymentService: def stripe_webhook(request): payload = request.body sig_header = request.META.get('HTTP_STRIPE_SIGNATURE') - print("Received webhook call") + + # Check if this is a Connect account webhook + stripe_account = request.META.get('HTTP_STRIPE_ACCOUNT') + + print("=== WEBHOOK DEBUG ===") print(f"Signature: {sig_header}") + print(f"Connect Account: {stripe_account}") + + if stripe_account: + # This is a connected account (regular umpire tournament) + webhook_secret = settings.TOURNAMENT_STRIPE_WEBHOOK_SECRET + print(f"Using umpire webhook secret for connected account: {stripe_account}") + else: + # This is platform account (corporate tournament) + webhook_secret = settings.XLR_STRIPE_WEBHOOK_SECRET + print("Using XLR company webhook secret") try: - event = stripe.Webhook.construct_event( - payload, sig_header, settings.TOURNAMENT_STRIPE_WEBHOOK_SECRET - ) + event = stripe.Webhook.construct_event(payload, sig_header, webhook_secret) print(f"Tournament webhook event type: {event['type']}") + # Debug metadata stripe_object = event['data']['object'] - - # Debug: Print the object type - object_type = stripe_object.get('object', 'unknown') - print(f"Stripe object type: {object_type}") + metadata = stripe_object.get('metadata', {}) + print(f"is_corporate_tournament: {metadata.get('is_corporate_tournament', 'unknown')}") + print(f"payment_source: {metadata.get('payment_source', 'unknown')}") if event['type'] == 'checkout.session.completed': success = PaymentService.process_direct_payment(stripe_object) @@ -639,7 +651,7 @@ class PaymentService: return HttpResponse(status=200) except Exception as e: - print(f"Tournament webhook error: {str(e)}") + print(f"Webhook error: {str(e)}") import traceback traceback.print_exc() return HttpResponse(status=400) @@ -665,12 +677,26 @@ class PaymentService: stripe_amount = currency_service.convert_to_stripe_amount(team_fee, tournament.currency_code) customer_email = team_registration.team_contact() + currency_code = tournament.currency_code or 'EUR' + + print(f"[PAYMENT LINK] Tournament: {tournament.name}") + print(f"[PAYMENT LINK] is_corporate_tournament: {tournament.is_corporate_tournament}") + + # Base metadata (same as checkout session) + base_metadata = { + 'tournament_id': str(tournament.id), + 'team_registration_id': str(team_registration.id), + 'customer_email': customer_email or 'Non fourni', + 'payment_source': 'payment_link', + 'registration_type': 'direct', + 'currency_code': currency_code, + } - # Create payment link + # Create payment link params payment_link_params = { 'line_items': [{ 'price_data': { - 'currency': tournament.currency_code.lower(), + 'currency': currency_code.lower(), 'product_data': { 'name': f'{tournament.broadcast_display_name()} du {tournament.formatted_start_date()}', 'description': f'Lieu {tournament.event.club.name}', @@ -679,13 +705,6 @@ class PaymentService: }, 'quantity': 1, }], - 'metadata': { - 'tournament_id': str(tournament.id), - 'team_registration_id': str(team_registration.id), - 'customer_email': customer_email or 'Non fourni', - 'payment_source': 'payment_link', - 'registration_type': 'direct', - }, 'after_completion': { 'type': 'redirect', 'redirect': { @@ -694,31 +713,53 @@ class PaymentService: }, 'automatic_tax': {'enabled': False}, 'billing_address_collection': 'auto', - 'shipping_address_collection': None, } - # Add customer email if available - if customer_email: - payment_link_params['customer_creation'] = 'if_required' - # Note: Stripe Payment Links don't support customer_email parameter - # but will ask for email during checkout + # Handle corporate vs regular tournaments (same logic as checkout session) + if tournament.is_corporate_tournament: + print(f"[PAYMENT LINK] Corporate tournament - creating on platform account") + # Corporate tournament - create on platform account (no Connect account) + metadata = { + **base_metadata, + 'is_corporate_tournament': 'true', + 'stripe_account_type': 'direct' + } + payment_link_params['metadata'] = metadata - # Handle Stripe Connect account if needed - stripe_account_id = tournament.event.creator.stripe_account_id if hasattr(tournament.event.creator, 'stripe_account_id') else None + # Create payment link on platform account + payment_link = stripe.PaymentLink.create(**payment_link_params) + + else: + print(f"[PAYMENT LINK] Regular tournament - creating on connected account") + # Regular tournament - create on connected account + stripe_account_id = tournament.stripe_account_id + if not stripe_account_id: + print(f"[PAYMENT LINK] ERROR: No Stripe account ID for umpire") + return None + + metadata = { + **base_metadata, + 'is_corporate_tournament': 'false', + 'stripe_account_type': 'connect', + 'stripe_account_id': stripe_account_id + } + payment_link_params['metadata'] = metadata - if stripe_account_id: + print(f"[PAYMENT LINK] Creating payment link for connected account: {stripe_account_id}") + + # Create payment link on connected account payment_link = stripe.PaymentLink.create( **payment_link_params, stripe_account=stripe_account_id ) - else: - payment_link = stripe.PaymentLink.create(**payment_link_params) print(f"[PAYMENT LINK] Created payment link: {payment_link.url}") return payment_link.url except Exception as e: print(f"[PAYMENT LINK] Error creating payment link: {str(e)}") + import traceback + traceback.print_exc() return None @staticmethod