import logging import os import stripe from django.conf import settings from django.http import HttpResponse from django.shortcuts import redirect, render from django.urls import reverse from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST from home.models import CoursePage from purchase.models import CoursePurchase logger = logging.getLogger(__name__) def mock_purchase_course(request, course_id): course = CoursePage.objects.get(id=course_id) course.mock_purchase(request.user) return redirect(course.url) def mock_refund_purchase(request, purchase_id): purchase = CoursePurchase.objects.get(id=purchase_id) purchase.mock_refund() return redirect(purchase.course.url) def purchase_success(request): return render(request, "success.html") @csrf_exempt def stripe_webhook(request): stripe.api_key = getattr( settings, "STRIPE_SECRET_KEY", os.getenv("STRIPE_SECRET_KEY") ) webhook_secret = getattr( settings, "STRIPE_WEBHOOK_SECRET", os.getenv("STRIPE_WEBHOOK_SECRET") ) payload = request.body sig_header = request.META.get("HTTP_STRIPE_SIGNATURE") event = None try: if webhook_secret: event = stripe.Webhook.construct_event(payload, sig_header, webhook_secret) else: event = stripe.Event.construct_from(request.json(), stripe.api_key) except ValueError as e: logger.error(f"Invalid payload: {e}") return HttpResponse(status=400) except stripe.error.SignatureVerificationError as e: logger.error(f"Webhook signature verification failed: {e}") return HttpResponse(status=400) # Handle the event logger.info(f"Received Stripe event: {event['type']}") # Example: handle successful payment if event["type"] == "checkout.session.completed": session = event["data"]["object"] session_id = session["id"] logger.info(f"Checkout session completed: {session}") # Try to find the CoursePurchase by Stripe session ID try: purchase = CoursePurchase.objects.get(stripe_checkout_session_id=session_id) purchase.status = CoursePurchase.Status.PAID purchase.refunded = False purchase.save() logger.info(f"Marked CoursePurchase {purchase.id} as PAID.") except CoursePurchase.DoesNotExist: logger.warning(f"No CoursePurchase found for session {session_id}") elif event["type"] == "checkout.session.expired": session = event["data"]["object"] session_id = session["id"] try: purchase = CoursePurchase.objects.get(stripe_checkout_session_id=session_id) purchase.status = CoursePurchase.Status.FAILED purchase.save() logger.info(f"Marked CoursePurchase {purchase.id} as FAILED (expired).") except CoursePurchase.DoesNotExist: logger.warning(f"No CoursePurchase found for expired session {session_id}") elif event["type"] == "checkout.session.async_payment_failed": session = event["data"]["object"] session_id = session["id"] try: purchase = CoursePurchase.objects.get(stripe_checkout_session_id=session_id) purchase.status = CoursePurchase.Status.FAILED purchase.save() logger.info( f"Marked CoursePurchase {purchase.id} as FAILED (async payment failed)." ) except CoursePurchase.DoesNotExist: logger.warning(f"No CoursePurchase found for failed session {session_id}") elif event["type"] == "checkout.session.async_payment_succeeded": session = event["data"]["object"] session_id = session["id"] try: purchase = CoursePurchase.objects.get(stripe_checkout_session_id=session_id) purchase.status = CoursePurchase.Status.PAID purchase.refunded = False purchase.save() logger.info( f"Marked CoursePurchase {purchase.id} as PAID (async succeeded)." ) except CoursePurchase.DoesNotExist: logger.warning( f"No CoursePurchase found for async succeeded session {session_id}" ) return HttpResponse(status=200)