import json from django.shortcuts import get_object_or_404 import requests from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from accounts.models import IAmPrincipal, IAmPrincipalType from goodtimes import services, constants from decimal import Decimal from manage_referrals.models import GoodTimeCoins from manage_wallets import models from django.conf import settings from django.utils import timezone from . import serializers from goodtimes.utils import ApiResponse # from PayTm import Checksum, check # from Paytm_Python.paytmchecksum import PaytmChecksum # from paytmchecksum import PaytmChecksum # from nifty11_project.services import SMSError, SMSService from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework_simplejwt.authentication import JWTAuthentication import stripe @method_decorator(csrf_exempt, name="dispatch") class StripeWebhookTest(APIView): authentication_classes = [] permission_classes = [AllowAny] 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.STRIPE_WEBHOOK_SECRET endpoint_secret = ( "whsec_ccf1f87295603cdd1733995ee2d3c0d6f74c7ceaf28916ea45114a54b7ce1d0f" ) event = None try: event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret) 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_id = metadata.get("principal_id") principal_type = metadata.get("principal_type") print("user_id: ", principal_id) print("user_type: ", principal_type) try: principal = IAmPrincipal.objects.get(id=principal_id) 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) wallet_manager = services.WalletManager( principal=get_object_or_404(IAmPrincipal, id=principal_id), principal_type=principal_type, ) deposit_amount = event.data.object.amount deposit_transaction = wallet_manager.deposit( deposit_amount, "merchant_deposit" ) 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) class GetWallet(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] model = models.Wallet def get(self, request): try: # Get the Wallet associated with the request.user wallet_obj = models.Wallet.objects.get(principal_id=request.user.id) # Serialize the wallet data serializer = serializers.WalletSerializer(wallet_obj) return ApiResponse.success( status=status.HTTP_200_OK, message=constants.SUCCESS, data=serializer.data, ) except Exception as e: # Handle any exceptions and return an error response error_response = { "status": status.HTTP_400_BAD_REQUEST, "message": constants.FAILURE, "errors": str(e), } return ApiResponse.error(**error_response) class TransactionView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def get(self, request): queryset = models.Transaction.objects.filter( principal_id=request.user.id, transaction_status__in=[ models.TransactionStatus.SUCCESS, models.TransactionStatus.FAIL, ], ) serializer = serializers.TransactionSerializer(queryset, many=True) response = { "status": status.HTTP_200_OK, "message": constants.SUCCESS, "data": serializer.data, } return ApiResponse.success(**response) class TestWebhookAPI(APIView): authentication_classes = [] permission_classes = [AllowAny] # event = None def post(self, request): event = request.data.get("event", {}) print(event) # return Response({"data": data}) if event.get("type") == "payment_intent.succeeded": payment_intent = event.get("data", {}).get("object", {}) print("Intent succ") print("payment_intent: ", payment_intent) metadata = payment_intent.get("metadata", {}) print("metadata: ", metadata) principal_id = metadata.get("principal_id") principal_type = metadata.get("principal_type") print("user_id: ", principal_id) print("user_type: ", principal_type) try: principal = IAmPrincipal.objects.get(id=principal_id) except IAmPrincipal.DoesNotExist as e: principal_error_response = { "status": status.HTTP_404_NOT_FOUND, "message": constants.RECORD_NOT_FOUND, "errors": str(e), } return ApiResponse.error(**principal_error_response) wallet_manager = services.WalletManager( principal=get_object_or_404(IAmPrincipal, id=principal_id), principal_type=principal_type, ) deposit_amount = event.get("data", {}).get("object", {}).get("amount", {}) deposit_transaction = wallet_manager.deposit( deposit_amount, "merchant_deposit" ) 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) class TestWebhookAPIWithdraw(APIView): authentication_classes = [] permission_classes = [AllowAny] # event = None def post(self, request): event = request.data.get("event", {}) print(event) # return Response({"data": data}) if event.get("type") == "payment_intent.succeeded": payment_intent = event.get("data", {}).get("object", {}) print("Intent succ") print("payment_intent: ", payment_intent) metadata = payment_intent.get("metadata", {}) print("metadata: ", metadata) principal_id = metadata.get("principal_id") principal_type = metadata.get("principal_type") print("user_id: ", principal_id) print("user_type: ", principal_type) try: principal = IAmPrincipal.objects.get(id=principal_id) 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) wallet_manager = services.WalletManager( principal=get_object_or_404(IAmPrincipal, id=principal_id), principal_type=principal_type, ) withdraw_amount = event.get("data", {}).get("object", {}).get("amount", {}) try: withdraw_transaction = wallet_manager.withdraw( withdraw_amount, "player_deposit" ) except Exception as e: exception_response = { "status": status.HTTP_400_BAD_REQUEST, "message": constants.WITHDRAWAL_FAILED, "errors": str(e), } return ApiResponse.error(**exception_response) 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) class CreateStripeConnectAccount(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def post(self, request): stripe.api_key = settings.STRIPE_SECRET_KEY # country_code = request.data.get("country_code") try: account = stripe.Account.create( country="GB", email=request.user.email, type="express", capabilities={ "card_payments": {"requested": True}, "transfers": {"requested": True}, }, business_type="individual", business_profile={ "name": request.user.first_name, "support_email": request.user.email, }, tos_acceptance={"service_agreement": "recipient"}, ) except Exception as e: exception_response = { "status": status.HTTP_400_BAD_REQUEST, "message": constants.FAILURE, "errors": str(e), } return ApiResponse.error(**exception_response) link = stripe.AccountLink.create( account=account.id, refresh_url=request.build_absolute_uri("/subscriptions/success/"), return_url=request.build_absolute_uri("/subscriptions/cancel/"), type="account_onboarding", ) models.StripeConnectAccount.objects.create( principal=request.user, stripe_connect_id=account.id, ) intent_response = { "data": link.url, "status": status.HTTP_200_OK, "message": "Link Sent", } return ApiResponse.success(**intent_response) class PrincipalBankAccountCreateAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def post(self, request, *args, **kwargs): serializer = serializers.PrincipalBankAccountSerializer( data=request.data, context={"request": request} ) if serializer.is_valid(): serializer.save() intent_response = { "data": serializer.data, "status": status.HTTP_200_OK, "message": "Successfully Added Bank Account", } return ApiResponse.success(**intent_response) exception_response = { "status": status.HTTP_400_BAD_REQUEST, "message": constants.FAILURE, "errors": serializer.errors, } return ApiResponse.error(**exception_response) class WithdrawalRequestCreateAPI(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def post(self, request, *args, **kwargs): user = request.user wallet = models.Wallet.objects.filter(principal=user).first() coins_amount = ( GoodTimeCoins.objects.filter(active=True, deleted=False) .last() .value_in_pound ) # Check if the user has a wallet and sufficient coins if wallet is None or wallet.coins <= 0: return ApiResponse.error( errors="Insufficient balance.", status=status.HTTP_400_BAD_REQUEST, message=constants.FAILURE, ) amount = coins_amount * wallet.coins print("amount: ", amount) serializer = serializers.WithdrawalRequestSerializer(data=request.data) if serializer.is_valid(): notes = serializer.validated_data.get("notes") or "No Notes by User" # Save the withdrawal request with notes (either provided or default) serializer.save( principal=user, created_on=timezone.now(), coins=wallet.coins, notes=notes, amount=amount, ) # Reset the wallet's coins to 0 wallet.coins = 0 wallet.save() return ApiResponse.success( data=serializer.data, status=status.HTTP_200_OK, message="Request Sent Successfully", ) else: return ApiResponse.error( errors=serializer.errors, status=status.HTTP_400_BAD_REQUEST, message=constants.FAILURE, ) class WithdrawalRequestView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def get(self, request): # Get the logged-in principal principal = request.user # Filter withdrawal requests by the logged-in principal withdrawal_requests = models.WithdrawalRequest.objects.filter( principal=principal ).order_by("-created_on") serializer = serializers.WithdrawalRequestViewSerializer( withdrawal_requests, many=True ) return ApiResponse.success( data=serializer.data, status=status.HTTP_200_OK, message=constants.SUCCESS, ) class PrincipalBankAccountCheck(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def get(self, request): queryset = models.PrincipalBankAccount.objects.filter(principal=request.user) if queryset: response = { "status": status.HTTP_200_OK, "message": constants.SUCCESS, "data": True, } return ApiResponse.success(**response) false_response = { "status": status.HTTP_200_OK, "message": constants.SUCCESS, "data": False, } return ApiResponse.success(**false_response)