from datetime import timedelta import datetime from django.db import transaction from django.shortcuts import get_object_or_404 from django.utils import timezone from rest_framework import status from rest_framework.views import APIView from django.conf import settings import stripe from accounts.models import IAmPrincipal from goodtimes import constants, services from manage_subscriptions.models import Subscription, PrincipalSubscription from goodtimes.utils import ApiResponse from accounts.resource_action import ( PRINCIPAL_TYPE_EVENT_USER, PRINCIPAL_TYPE_EVENT_MANAGER, PRINCIPAL_TYPE_FREE_USER, ) from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework_simplejwt.authentication import JWTAuthentication from .serializers import PrincipalSubscriptionSerializer from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from rest_framework.response import Response class CreatePrincipalSubscriptionApi(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] stripe.api_key = settings.STRIPE_SECRET_KEY def post(self, request): serializer = PrincipalSubscriptionSerializer(data=request.data) if serializer.is_valid(): subscription_id = serializer.validated_data.get("subscription") try: subscription = Subscription.objects.get(id=subscription_id) except Subscription.DoesNotExist: return ApiResponse.error( status=status.HTTP_404_NOT_FOUND, message="Subscription not found." ) order_id = ( "order_" + str(timezone.localtime().timestamp()) + str(request.user.email) ) print("order_id: ", order_id) try: customer = stripe.Customer.create( email=request.user.email, shipping={ "name": request.user.first_name, "address": { "line1": "Test Address", "city": "Test City", "postal_code": "SW1A 2AA", "country": "RU", # Adjust accordingly }, }, ) payment_intent = stripe.PaymentIntent.create( amount=int(subscription.amount * 100), currency="GBP", description="Principal Subscription", metadata={ "principal": request.user.id, "order_id": order_id, "subscription": subscription.id, }, customer=customer.id, ) return Response( { "client_secret": payment_intent.client_secret, "message": "Payment intent created successfully", } ) except stripe.error.StripeError as e: # Handle Stripe-related errors return Response({"error": str(e)}, status=400) else: fail_response = { "status": status.HTTP_400_BAD_REQUEST, "message": "Validation Failed", "errors": serializer.errors, } return ApiResponse.error(**fail_response) # class CreatePrincipalSubscriptionApi(APIView): # authentication_classes = [JWTAuthentication] # permission_classes = [IsAuthenticated] # def post(self, request): # serializer = PrincipalSubscriptionSerializer(data=request.data) # if serializer.is_valid(): # subscription_id = serializer.validated_data.get("subscription").id # try: # subscription = Subscription.objects.get(id=subscription_id) # except Subscription.DoesNotExist: # return ApiResponse.error( # status=status.HTTP_404_NOT_FOUND, message="Subscription not found." # ) # start_date = timezone.localtime().date() # end_date = start_date + timedelta(days=subscription.plan.days) # grace_period_end_date = end_date + timedelta(days=15) # # You can directly pass the additional fields as save method arguments # instance = serializer.save( # start_date=start_date, # end_date=end_date, # grace_period_end_date=grace_period_end_date, # created_by=request.user, # Assuming your model has this field and you want to track who created the subscription # ) # success_response = { # "status": status.HTTP_201_CREATED, # Use 201 for successful resource creation # "message": "Success", # "data": serializer.data, # } # return ApiResponse.success(**success_response) # else: # fail_response = { # "status": status.HTTP_400_BAD_REQUEST, # "message": "Validation Failed", # "errors": serializer.errors, # } # return ApiResponse.error(**fail_response) import json @method_decorator(csrf_exempt, name="dispatch") class StripeWebhookTest(APIView): authentication_classes = [] permission_classes = [AllowAny] @transaction.atomic def post(self, request): stripe.api_key = settings.STRIPE_SECRET_KEY payload = request.body print("payload", payload) sig_header = request.META["HTTP_STRIPE_SIGNATURE"] # endpoint_secret = settings.endpoint_secret endpoint_secret = ( "whsec_ccf1f87295603cdd1733995ee2d3c0d6f74c7ceaf28916ea45114a54b7ce1d0f" ) event = None try: # event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret) event = stripe.Event.construct_from(json.loads(payload), stripe.api_key) except ValueError as e: value_error_response = { "status": status.HTTP_400_BAD_REQUEST, "message": constants.ERROR_OCCURR.format(str(e)), "errors": str(e), } return ApiResponse.error(**value_error_response) except stripe.error.SignatureVerificationError as e: signature_error_response = { "status": status.HTTP_400_BAD_REQUEST, "message": constants.ERROR_OCCURR.format(str(e)), "errors": str(e), } return ApiResponse.error(**signature_error_response) if event["type"] == "payment_intent.succeeded": payment_intent = event["data"]["object"] print("Intent succ") print("payment_intent: ", payment_intent) metadata = event.data.object.metadata print("metadata: ", metadata) principal = metadata.get("principal") subscription = metadata.get("subscription") print("principal: ", principal) print("subscription: ", subscription) try: principal = IAmPrincipal.objects.get(id=principal) except IAmPrincipal.DoesNotExist as e: error_response = { "status": status.HTTP_404_NOT_FOUND, "message": constants.RECORD_NOT_FOUND, "errors": str(e), } return ApiResponse.error(**error_response) try: subscription = Subscription.objects.get(id=subscription) except IAmPrincipal.DoesNotExist as e: error_response = { "status": status.HTTP_404_NOT_FOUND, "message": constants.RECORD_NOT_FOUND, "errors": str(e), } return ApiResponse.error(**error_response) today = timezone.localtime().date() last_date = timedelta(days=subscription.plan.days) principal_subscription = PrincipalSubscription.objects.create( principal=principal, subscription=subscription, start_date=today, end_date=today + last_date, grace_period_end_date=last_date + timedelta(days=15), ) principal_subscription.save() wallet_manager = services.WalletManager( principal=principal, principal_type=principal.principal_type, ) deposit_amount = event.data.object.amount deposit_transaction = wallet_manager.deposit( deposit_amount, "subscription payment" ) print("Passed Through principal_wallet Object") success_response = { "status": status.HTTP_200_OK, "message": "Webhook received, payment succeeded", } return ApiResponse.success(**success_response) else: intent_response = { "status": status.HTTP_400_BAD_REQUEST, "message": "Webhook received, but payment failed", } return ApiResponse.success(**intent_response)