120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
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)
|