Django Stripe Webhook not consistent Statuscode 500 sometimes 201

L.S.

I am working on my first Django project and struggling with the Stripe integration. My webhook is acting inconsistently—it worked fine when running locally on localhost with the Stripe CLI. However, after deploying with Nginx and Gunicorn, it has become unreliable. Sometimes it goes through, but in most cases, I receive a 500 status code.

I want to send an email to the customer with a PDF attachment when the checkout.session.completed webhook is triggered. I read that the webhook should return a 200 status code as quickly as possible; otherwise, Stripe might time out. Or could the issue be caused by a time difference between the request and the server?

Regardless, I’m unsure how to properly fix this. I’d really appreciate any guidance from someone with experience.

import datetime
import stripe
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from webshop.models import Product, Customer, Order, OrderItem
from django.core.mail import EmailMessage

@csrf_exempt
def stripe_webhook(request):
    payload = request.body
    sig_header = request.META.get("HTTP_STRIPE_SIGNATURE")
    endpoint_secret = settings.STRIPE_WEBHOOK_SECRET

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

    # Handle checkout success
    if event["type"] == "checkout.session.completed":
        session = event["data"]["object"]
        session_id = session["id"]

        # Fetch line items from Stripe
        line_items = stripe.checkout.Session.list_line_items(session_id)

        # Extract order details
        customer_email = session.get("customer_details").get("email")
        customer_name = session.get("customer_details").get("name")
        amount_total = session.get("amount_total") / 100 
        payment_status = session.get("payment_status") == "paid"

        # Get or create customer
        customer, created = Customer.objects.get_or_create(email=customer_email, defaults={"name": customer_name})

        # Create new order
        order = Order.objects.create(
            customer=customer,
            date_ordered=datetime.datetime.now(),
            payment_status=payment_status,
            total_price=amount_total,
        )
        
        ordered_products = []  # Store product names for email

        # Add order items
        for item in line_items["data"]:
            product_name = item["description"]
            quantity = item["quantity"]

            # Get product from database
            try:
                product = Product.objects.get(name=product_name)
                OrderItem.objects.create(order=order, product=product, quantity=quantity)
                ordered_products.append(product_name)
            except Product.DoesNotExist:
                print(f"⚠️ Product '{product_name}' not found in database, skipping.")

        print(f"✅ Order created: {order}")
        
        if ordered_products:
            send_email_with_pdf(ordered_products, customer_email)
        
        return JsonResponse({"status": "Order created"}, status=201)

    return JsonResponse({"status": "success"}, status=200)

def send_email_with_pdf(product_name_list, recipient_email):
    try:
        email = EmailMessage(
            subject='Your PDF(s)',
            body='Please find the attached PDFs.',
            from_email='test123456733@gmail.com',
            to=[recipient_email],
        )

        # Attach multiple PDFs
        for name in product_name_list:
            try:
                product_obj = Product.objects.get(name=name)
                if product_obj.remschema:
                    pdf_name = product_obj.remschema.name
                    pdf_content = product_obj.remschema.read()
                    email.attach(pdf_name, pdf_content, 'application/pdf')
            except Product.DoesNotExist:
                print(f"Product '{name}' not found.")

        # Send the email only if there are attachments
        if email.attachments:
            email.send()
            return "Email sent successfully!"
        else:
            return "No PDFs found to send."
    
    except Product.DoesNotExist:
        print("Product nog found")
        return "PDF not found."
    except Exception as e:
        print(f"Error: {e}")
        return f"Error: {e}"

stripe dashboard sc

I have the feeling that maybe the view is to slow?

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