239 lines
9.2 KiB
Python
239 lines
9.2 KiB
Python
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)
|