dev: new app for capturing payments

This commit is contained in:
pablohashescobar
2024-05-27 18:49:45 +05:30
parent 86ee4034c2
commit 8dfb400d1c
6 changed files with 202 additions and 0 deletions

View File

View File

@@ -0,0 +1,5 @@
from django.apps import AppConfig
class ApiConfig(AppConfig):
name = "plane.payment"

View File

@@ -0,0 +1,132 @@
# Python imports
import zoneinfo
# Django imports
from django.conf import settings
from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import IntegrityError
# Third party imports
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
# Module imports
from plane.authentication.session import BaseSessionAuthentication
from plane.utils.exception_logger import log_exception
class TimezoneMixin:
"""
This enables timezone conversion according
to the user set timezone
"""
def initial(self, request, *args, **kwargs):
super().initial(request, *args, **kwargs)
if request.user.is_authenticated:
timezone.activate(zoneinfo.ZoneInfo(request.user.user_timezone))
else:
timezone.deactivate()
class BaseAPIView(TimezoneMixin, APIView):
permission_classes = [
IsAuthenticated,
]
authentication_classes = [
BaseSessionAuthentication,
]
filterset_fields = []
search_fields = []
def filter_queryset(self, queryset):
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
def handle_exception(self, exc):
"""
Handle any exception that occurs, by returning an appropriate response,
or re-raising the error.
"""
try:
response = super().handle_exception(exc)
return response
except Exception as e:
if isinstance(e, IntegrityError):
return Response(
{"error": "The payload is not valid"},
status=status.HTTP_400_BAD_REQUEST,
)
if isinstance(e, ValidationError):
return Response(
{"error": "Please provide valid detail"},
status=status.HTTP_400_BAD_REQUEST,
)
if isinstance(e, ObjectDoesNotExist):
return Response(
{"error": "The required object does not exist."},
status=status.HTTP_404_NOT_FOUND,
)
if isinstance(e, KeyError):
return Response(
{"error": "The required key does not exist."},
status=status.HTTP_400_BAD_REQUEST,
)
log_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
def dispatch(self, request, *args, **kwargs):
try:
response = super().dispatch(request, *args, **kwargs)
if settings.DEBUG:
from django.db import connection
print(
f"{request.method} - {request.get_full_path()} of Queries: {len(connection.queries)}"
)
return response
except Exception as exc:
response = self.handle_exception(exc)
return exc
@property
def workspace_slug(self):
return self.kwargs.get("slug", None)
@property
def project_id(self):
return self.kwargs.get("project_id", None)
@property
def fields(self):
fields = [
field
for field in self.request.GET.get("fields", "").split(",")
if field
]
return fields if fields else None
@property
def expand(self):
expand = [
expand
for expand in self.request.GET.get("expand", "").split(",")
if expand
]
return expand if expand else None

View File

@@ -0,0 +1,61 @@
# Python imports
import requests
# Django imports
from django.conf import settings
# Third party imports
from rest_framework import status
from rest_framework.response import Response
# Module imports
from .base import BaseAPIView
class ProductEndpoint(BaseAPIView):
def get(self, request):
try:
if settings.PAYMENT_SERVER_BASE_URL:
quantity = request.GET.get("quantity", 1)
response = requests.get(
f"{settings.PAYMENT_SERVER_BASE_URL}/api/products/?quantity={quantity}",
headers={"content-type": "application/json"},
)
response = response.json()
return Response(response, status=status.HTTP_200_OK)
else:
return Response(
{"error": "error fetching product details"},
status=status.HTTP_400_BAD_REQUEST,
)
except requests.exceptions.RequestException:
return Response(
{"error": "error fetching product details"},
status=status.HTTP_400_BAD_REQUEST,
)
class PaymentLinkEndpoint(BaseAPIView):
def post(self, request):
try:
if settings.PAYMENT_SERVER_BASE_URL:
data = request.data
response = requests.post(
f"{settings.PAYMENT_SERVER_BASE_URL}/api/payment-links/",
json=data,
headers={"content-type": "application/json"},
)
response = response.json()
return Response(response, status=status.HTTP_200_OK)
else:
return Response(
{"error": "error fetching payment link"},
status=status.HTTP_400_BAD_REQUEST,
)
except requests.exceptions.RequestException:
return Response(
{"error": "error fetching payment link"},
status=status.HTTP_400_BAD_REQUEST,
)

View File

@@ -45,6 +45,7 @@ INSTALLED_APPS = [
"plane.license",
"plane.api",
"plane.authentication",
"plane.payment",
# Third-party things
"rest_framework",
"corsheaders",
@@ -353,3 +354,6 @@ CSRF_COOKIE_DOMAIN = os.environ.get("COOKIE_DOMAIN", None)
ADMIN_BASE_URL = os.environ.get("ADMIN_BASE_URL", None)
SPACE_BASE_URL = os.environ.get("SPACE_BASE_URL", None)
APP_BASE_URL = os.environ.get("APP_BASE_URL") or os.environ.get("WEB_URL")
# Cloud server base url
PAYMENT_SERVER_BASE_URL = os.environ.get("PAYMENT_SERVER_BASE_URL", None)