diff --git a/tournaments/services/payment_service.py b/tournaments/services/payment_service.py index 8c99a5e..c2b259b 100644 --- a/tournaments/services/payment_service.py +++ b/tournaments/services/payment_service.py @@ -593,31 +593,75 @@ class PaymentService: payload = request.body sig_header = request.META.get('HTTP_STRIPE_SIGNATURE') - # Check if this is a Connect account webhook - stripe_account = request.META.get('HTTP_STRIPE_ACCOUNT') + # Check if this is a Connect account webhook (header method - for direct API calls) + stripe_account_header = request.META.get('HTTP_STRIPE_ACCOUNT') print("=== WEBHOOK DEBUG ===") print(f"Signature: {sig_header}") - print(f"Connect Account: {stripe_account}") + print(f"Connect Account Header: {stripe_account_header}") - 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}") + # First, try to construct the event with any available webhook secret to inspect the payload + webhook_secrets = [] + if hasattr(settings, 'XLR_STRIPE_WEBHOOK_SECRET') and settings.XLR_STRIPE_WEBHOOK_SECRET: + webhook_secrets.append(('XLR', settings.XLR_STRIPE_WEBHOOK_SECRET)) + if hasattr(settings, 'TOURNAMENT_STRIPE_WEBHOOK_SECRET') and settings.TOURNAMENT_STRIPE_WEBHOOK_SECRET: + webhook_secrets.append(('TOURNAMENT', settings.TOURNAMENT_STRIPE_WEBHOOK_SECRET)) + if hasattr(settings, 'SHOP_STRIPE_WEBHOOK_SECRET') and settings.SHOP_STRIPE_WEBHOOK_SECRET: + webhook_secrets.append(('SHOP', settings.SHOP_STRIPE_WEBHOOK_SECRET)) + + print(f"Available webhook secrets: {[name for name, _ in webhook_secrets]}") + + event = None + used_secret = None + + # Try to verify with each secret to get the event payload + for secret_name, secret_value in webhook_secrets: + try: + print(f"Trying {secret_name} webhook secret...") + event = stripe.Webhook.construct_event(payload, sig_header, secret_value) + used_secret = secret_name + print(f"SUCCESS: Webhook verified with {secret_name} secret") + break + except stripe.error.SignatureVerificationError as e: + print(f"Failed with {secret_name} secret: {str(e)}") + continue + + if not event: + print("ERROR: No webhook secret worked") + return HttpResponse("Webhook signature verification failed", status=400) + + # Now check if this is a Connect webhook by looking at the payload + connect_account_id = event.get('account') # This is how Connect webhooks are identified + print(f"Connect Account ID from payload: {connect_account_id}") + + # Log webhook details + print(f"Event ID: {event.get('id')}") + print(f"Event Type: {event.get('type')}") + print(f"Live Mode: {event.get('livemode')}") + + # Determine if this should have used a different webhook secret based on the account + if connect_account_id: + print(f"This is a Connect webhook from account: {connect_account_id}") + # Check if the account matches the expected tournament account + if connect_account_id == "acct_1S0jbSAs9xuFLROy": + print("This matches the expected tournament Connect account") + if used_secret != 'TOURNAMENT': + print(f"WARNING: Used {used_secret} secret but should probably use TOURNAMENT secret") + else: + print(f"Unknown Connect account: {connect_account_id}") else: - # This is platform account (corporate tournament) - webhook_secret = settings.XLR_STRIPE_WEBHOOK_SECRET - print("Using XLR company webhook secret") + print("This is a platform/direct webhook (no Connect account)") + if used_secret != 'XLR': + print(f"WARNING: Used {used_secret} secret but should probably use XLR secret") try: - event = stripe.Webhook.construct_event(payload, sig_header, webhook_secret) - print(f"Tournament webhook event type: {event['type']}") - - # Debug metadata + # Process the webhook event stripe_object = event['data']['object'] 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')}") + print(f"stripe_account_type: {metadata.get('stripe_account_type', 'unknown')}") + print(f"stripe_account_id: {metadata.get('stripe_account_id', 'unknown')}") if event['type'] == 'checkout.session.completed': success = PaymentService.process_direct_payment(stripe_object) @@ -628,33 +672,20 @@ class PaymentService: print(f"Failed to process completed checkout session") return HttpResponse(status=400) - elif event['type'] == 'payment_intent.payment_failed': - success = PaymentService.process_failed_payment_intent(stripe_object) - if success: - print(f"Successfully processed failed payment intent") - return HttpResponse(status=200) - else: - print(f"Failed to process failed payment intent") - return HttpResponse(status=400) - - elif event['type'] == 'checkout.session.expired': - success = PaymentService.process_expired_checkout_session(stripe_object) - if success: - print(f"Successfully processed expired checkout session") - return HttpResponse(status=200) - else: - print(f"Failed to process expired checkout session") - return HttpResponse(status=400) + # Handle other event types if needed + elif event['type'] == 'payment_intent.succeeded': + print(f"Payment intent succeeded - you might want to handle this") + return HttpResponse(status=200) else: print(f"Unhandled event type: {event['type']}") return HttpResponse(status=200) except Exception as e: - print(f"Webhook error: {str(e)}") + print(f"Error processing webhook: {str(e)}") import traceback traceback.print_exc() - return HttpResponse(status=400) + return HttpResponse("Webhook processing failed", status=500) @staticmethod def create_payment_link(team_registration_id):