import pprint from datetime import datetime import stripe from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.http import JsonResponse from django.shortcuts import redirect, render from django.urls import reverse, reverse_lazy from django.views import View from django.views.generic.edit import CreateView from rest_framework.parsers import JSONParser from rest_framework.views import APIView from core.forms import NewUserForm from core.lib.products import assemble_plan_map from core.models import Plan, Session, User pp = pprint.PrettyPrinter(indent=4) # Create your views here class Home(View): template_name = "index.html" def get(self, request): return render(request, self.template_name) class Billing(LoginRequiredMixin, View): template_name = "billing.html" def get(self, request): context = {"plans": Plan.objects.all(), "user_plans": request.user.plans.all()} return render(request, self.template_name, context) class Order(LoginRequiredMixin, View): def get(self, request, product_id): try: session = stripe.checkout.Session.create( payment_method_types=settings.ALLOWED_PAYMENT_METHODS, mode="subscription", customer=request.user.stripe_id, line_items=assemble_plan_map(product_id_filter=product_id), success_url=request.build_absolute_uri(reverse("success")), cancel_url=request.build_absolute_uri(reverse("cancel")), ) Session.objects.create(user=request.user, session=session.id) return redirect(session.url) # return JsonResponse({'id': session.id}) except Exception as e: # Raise a server error return JsonResponse({"error": str(e)}, status=500) class Signup(CreateView): form_class = NewUserForm success_url = reverse_lazy("login") template_name = "registration/signup.html" class Portal(LoginRequiredMixin, View): def get(self, request): session = stripe.billing_portal.Session.create( customer=request.user.stripe_id, return_url=request.build_absolute_uri(reverse("billing")), ) return redirect(session.url) class Callback(APIView): parser_classes = [JSONParser] def post(self, request): pp.pprint(request.data) if request.data is None: return JsonResponse({"success": False}, status=500) if "type" in request.data.keys(): rtype = request.data["type"] if rtype == "checkout.session.completed": session = request.data["data"]["object"]["id"] subscription_id = request.data["data"]["object"]["subscription"] session_map = Session.objects.get(session=session) print("querying session", session) if not session_map: return JsonResponse({"success": False}, status=500) user = session_map.user session_map.subscription_id = subscription_id session_map.save() if rtype == "customer.subscription.updated": stripe_id = request.data["data"]["object"]["customer"] if not stripe_id: print("No user found for customer:", stripe_id) return JsonResponse({"success": False}, status=500) user = User.objects.get(stripe_id=stripe_id) # ssubscription_active subscription_id = request.data["data"]["object"]["id"] sessions = Session.objects.filter(user=user) session = None for session_iter in sessions: if session_iter.subscription_id == subscription_id: session = session_iter if not session: print(f"No session found for subscription id {subscription_id}") return JsonResponse({"success": False}, status=500) # query Session objects # iterate and check against product_id session.request = request.data["request"]["id"] product_id = request.data["data"]["object"]["plan"]["id"] plan = Plan.objects.get(product_id=product_id) if not plan: print(f"Plan not found: {product_id}") return JsonResponse({"success": False}, status=500) session.plan = plan session.save() elif rtype == "payment_intent.succeeded": customer = request.data["data"]["object"]["customer"] print("customer", customer) user = User.objects.get(stripe_id=customer) if not user: print("No user found for customer:", customer) return JsonResponse({"success": False}, status=500) print("got", user.email) session = Session.objects.get(request=request.data["request"]["id"]) print("Got session", session) user.plans.add(session.plan) print("ADDING PLAN TO USER PLANS") user.last_payment = datetime.utcnow() user.save() elif rtype == "customer.subscription.deleted": customer = request.data["data"]["object"]["customer"] user = User.objects.get(stripe_id=customer) if not user: print("No user found for customer:", customer) return JsonResponse({"success": False}, status=500) product_id = request.data["data"]["object"]["plan"]["id"] plan = Plan.objects.get(product_id=product_id) user.plans.remove(plan) user.save() else: return JsonResponse({"success": False}, status=500) return JsonResponse({"success": True})