451 lines
16 KiB
Python
451 lines
16 KiB
Python
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,
|
|
],
|
|
).order_by("-created_on")
|
|
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)
|