Im trying to create an order for my application i have a big issue with the webhook

@login_required def cart_detail(request): # Try to fetch the cart for the logged-in user cart = Cart.objects.filter(user=request.user).first()

if not cart or not cart.items.exists():  # Ensure that cart has items
    # If no cart exists or cart is empty, pass a flag to indicate an empty cart
    context = {'cart_exists': False}
    return render(request, 'services/cart_detail.html', context)

# Calculate the total price for the cart
total_price = sum(item.total_price() for item in cart.items.all())

context = {
    'cart': cart,
    'total_price': total_price,
    'cart_exists': True,  
    'STRIPE_PUBLISHABLE_KEY': settings.STRIPE_PUBLISHABLE_KEY,
}

return render(request, 'services/cart_detail.html', context)

Payment is initiated with the cart detail goes to create checkout

class CreateCheckoutSessionView(View): def post(self, request, *args, **kwargs): cart = get_object_or_404(Cart, user=request.user)

    if not cart.items.exists():
        return JsonResponse({'error': 'Cart is empty'}, status=400)

    line_items = []
    total_price = 0  # To calculate total price of the cart for the order

    # Prepare line items for Stripe
    for item in cart.items.all():
        name = item.plan.name if item.plan else item.extra_service.title
        amount = int(item.get_price() * 100)  # Amount in cents for Stripe
        total_price += item.total_price()

        line_items.append({
            'price_data': {
                'currency': 'usd',
                'unit_amount': amount,
                'product_data': {
                    'name': name,
                },
            },
            'quantity': item.quantity,
        })

    success_url = request.build_absolute_uri('/success/')
    cancel_url = request.build_absolute_uri('/cancel/')

    # Create Stripe Checkout session
    checkout_session = stripe.checkout.Session.create(
        payment_method_types=['card'],
        line_items=line_items,
        mode='payment',
        success_url=success_url,
        cancel_url=cancel_url,
    )

    # Create a temporary "unpaid" order to track the session
    order = Order.objects.create(
        user=request.user,
        total_price=total_price,
        order_number=checkout_session.id[:50],  # Truncate to fit 50 characters
        status='PENDING',  # Order is pending payment
        slug=checkout_session.id[:50],  # Truncate to fit 50 characters
    )

    # Save Stripe checkout session ID to the order
    order.stripe_checkout_id = checkout_session.id
    order.save()

    # Save Stripe checkout session ID to the cart
    cart.stripe_checkout_id = checkout_session.id
    cart.save()

    # Clear the cart after creating OrderItems
    cart.items.all().delete()

    # Return the session ID in JSON response
    return JsonResponse({'id': checkout_session.id})

class StripeWebhookView(View): def post(self, request, *args, **kwargs): payload = request.body sig_header = request.META['HTTP_STRIPE_SIGNATURE'] event = None

    # Replace with your Stripe Webhook Secret
    endpoint_secret = settings.STRIPE_WEBHOOK_SECRET

    try:
        # Verify the webhook signature
        event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
    except ValueError as e:
        # Invalid payload
        return JsonResponse({'error': 'Invalid payload'}, status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return JsonResponse({'error': 'Invalid signature'}, status=400)

    # Handle the event
    if event['type'] == 'checkout.session.completed':
        session = event['data']['object']

        # Retrieve the Order using the checkout session ID
        order = Order.objects.filter(order_number=session['id']).first()

        if order:
            # Mark the order as PAID
            order.status = 'PAID'
            order.save()

            # Send the order confirmation email
            user = order.user
            full_name = f"{user.first_name} {user.last_name}".strip() or user.email

            # Collect all the items in the order and format them
            item_lines = [
                f"- {item.quantity}x {item.product} @ ${item.price}" for item in order.items.all()
            ]
            item_details = "\n".join(item_lines)

            # Construct the subject and message for the email
            subject = f"🛒 New Order #{order.order_number} by {full_name}"
            message = f"""
                        A new order has been placed.

                        Order ID: {order.order_number}
                        User: {full_name} ({user.email})
                        Company: {user.company or 'N/A'}
                        Total Price: ${order.total_price}

                        Items Ordered:
                        {item_details}

                        Please log in to the admin dashboard to view and process this order.
                        """

            # Send the email
            send_mail(
                subject,
                message,
                settings.DEFAULT_FROM_EMAIL,
                ['orders@saasiskey.com'],
                fail_silently=False,
            )

    # Return a 200 response to acknowledge receipt of the event
    return JsonResponse({'status': 'success'}, status=200)

i wanna create an order mark order as paid but only after payment went through with stripe, bit now it is created before payment is recorded, that is my issue i also wanna trigger a signal but it is not eign troggered

Вернуться на верх