init
This commit is contained in:
0
backend/thirdparty/gopay/__init__.py
vendored
Normal file
0
backend/thirdparty/gopay/__init__.py
vendored
Normal file
3
backend/thirdparty/gopay/admin.py
vendored
Normal file
3
backend/thirdparty/gopay/admin.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
backend/thirdparty/gopay/apps.py
vendored
Normal file
6
backend/thirdparty/gopay/apps.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class GopayConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'gopay'
|
||||
0
backend/thirdparty/gopay/migrations/__init__.py
vendored
Normal file
0
backend/thirdparty/gopay/migrations/__init__.py
vendored
Normal file
3
backend/thirdparty/gopay/models.py
vendored
Normal file
3
backend/thirdparty/gopay/models.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
37
backend/thirdparty/gopay/serializers.py
vendored
Normal file
37
backend/thirdparty/gopay/serializers.py
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class GoPayCreatePaymentRequestSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=12, decimal_places=2, min_value=0.01)
|
||||
currency = serializers.CharField(required=False, default="CZK")
|
||||
order_number = serializers.CharField(required=False, allow_blank=True, default="order-001")
|
||||
order_description = serializers.CharField(required=False, allow_blank=True, default="Example GoPay payment")
|
||||
return_url = serializers.URLField(required=False)
|
||||
notify_url = serializers.URLField(required=False)
|
||||
preauthorize = serializers.BooleanField(required=False, default=False)
|
||||
|
||||
|
||||
class GoPayPaymentCreatedResponseSerializer(serializers.Serializer):
|
||||
id = serializers.IntegerField()
|
||||
state = serializers.CharField()
|
||||
gw_url = serializers.URLField(required=False, allow_null=True)
|
||||
|
||||
|
||||
class GoPayStatusResponseSerializer(serializers.Serializer):
|
||||
id = serializers.IntegerField()
|
||||
state = serializers.CharField()
|
||||
|
||||
|
||||
class GoPayRefundRequestSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=12, decimal_places=2, required=False, min_value=0.01)
|
||||
|
||||
|
||||
class GoPayCaptureRequestSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=12, decimal_places=2, required=False, min_value=0.01)
|
||||
|
||||
|
||||
class GoPayCreateRecurrenceRequestSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=12, decimal_places=2, min_value=0.01)
|
||||
currency = serializers.CharField(required=False, default="CZK")
|
||||
order_number = serializers.CharField(required=False, allow_blank=True, default="recur-001")
|
||||
order_description = serializers.CharField(required=False, allow_blank=True, default="Recurring payment")
|
||||
3
backend/thirdparty/gopay/tests.py
vendored
Normal file
3
backend/thirdparty/gopay/tests.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
20
backend/thirdparty/gopay/urls.py
vendored
Normal file
20
backend/thirdparty/gopay/urls.py
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
from django.urls import path
|
||||
from .views import (
|
||||
GoPayPaymentView,
|
||||
GoPayPaymentStatusView,
|
||||
GoPayRefundPaymentView,
|
||||
GoPayCaptureAuthorizationView,
|
||||
GoPayVoidAuthorizationView,
|
||||
GoPayCreateRecurrenceView,
|
||||
GoPayPaymentInstrumentsView,
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
path('payment/', GoPayPaymentView.as_view(), name='gopay-payment'),
|
||||
path('payment/<int:payment_id>/status/', GoPayPaymentStatusView.as_view(), name='gopay-payment-status'),
|
||||
path('payment/<int:payment_id>/refund/', GoPayRefundPaymentView.as_view(), name='gopay-refund-payment'),
|
||||
path('payment/<int:payment_id>/capture/', GoPayCaptureAuthorizationView.as_view(), name='gopay-capture-authorization'),
|
||||
path('payment/<int:payment_id>/void/', GoPayVoidAuthorizationView.as_view(), name='gopay-void-authorization'),
|
||||
path('payment/<int:payment_id>/recurrence/', GoPayCreateRecurrenceView.as_view(), name='gopay-create-recurrence'),
|
||||
path('payment-instruments/', GoPayPaymentInstrumentsView.as_view(), name='gopay-payment-instruments'),
|
||||
]
|
||||
233
backend/thirdparty/gopay/views.py
vendored
Normal file
233
backend/thirdparty/gopay/views.py
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
import gopay
|
||||
from gopay.enums import TokenScope, Language
|
||||
import os
|
||||
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample, OpenApiParameter
|
||||
from .serializers import (
|
||||
GoPayCreatePaymentRequestSerializer,
|
||||
GoPayPaymentCreatedResponseSerializer,
|
||||
GoPayStatusResponseSerializer,
|
||||
GoPayRefundRequestSerializer,
|
||||
GoPayCaptureRequestSerializer,
|
||||
GoPayCreateRecurrenceRequestSerializer,
|
||||
)
|
||||
|
||||
|
||||
class GoPayClientMixin:
|
||||
"""Shared helpers for configuring GoPay client and formatting responses."""
|
||||
def get_gopay_client(self):
|
||||
gateway_url = os.getenv("GOPAY_GATEWAY_URL", "https://gw.sandbox.gopay.com/api")
|
||||
return gopay.payments({
|
||||
"goid": os.getenv("GOPAY_GOID"),
|
||||
"client_id": os.getenv("GOPAY_CLIENT_ID"),
|
||||
"client_secret": os.getenv("GOPAY_CLIENT_SECRET"),
|
||||
"gateway_url": gateway_url,
|
||||
"scope": TokenScope.ALL,
|
||||
"language": Language.CZECH,
|
||||
})
|
||||
|
||||
def _to_response(self, sdk_response):
|
||||
# The GoPay SDK returns a response object with has_succeed(), json, errors, status_code
|
||||
try:
|
||||
if hasattr(sdk_response, "has_succeed") and sdk_response.has_succeed():
|
||||
return Response(getattr(sdk_response, "json", {}))
|
||||
status = getattr(sdk_response, "status_code", 400)
|
||||
errors = getattr(sdk_response, "errors", None)
|
||||
if errors is None and hasattr(sdk_response, "json"):
|
||||
errors = sdk_response.json
|
||||
if errors is None:
|
||||
errors = {"detail": "GoPay request failed"}
|
||||
return Response({"errors": errors}, status=status)
|
||||
except Exception as e:
|
||||
return Response({"errors": str(e)}, status=500)
|
||||
|
||||
|
||||
class GoPayPaymentView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Create GoPay payment",
|
||||
description="Creates a GoPay payment and returns gateway URL and payment info.",
|
||||
request=GoPayCreatePaymentRequestSerializer,
|
||||
responses={
|
||||
200: OpenApiResponse(response=GoPayPaymentCreatedResponseSerializer, description="Payment created"),
|
||||
400: OpenApiResponse(description="Validation error or SDK error"),
|
||||
},
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
"Create payment",
|
||||
value={
|
||||
"amount": 123.45,
|
||||
"currency": "CZK",
|
||||
"order_number": "order-001",
|
||||
"order_description": "Example GoPay payment",
|
||||
"return_url": "https://yourfrontend.com/success",
|
||||
"notify_url": "https://yourbackend.com/gopay/notify",
|
||||
"preauthorize": False,
|
||||
},
|
||||
request_only=True,
|
||||
)
|
||||
]
|
||||
)
|
||||
def post(self, request):
|
||||
amount = request.data.get("amount")
|
||||
currency = request.data.get("currency", "CZK")
|
||||
order_number = request.data.get("order_number", "order-001")
|
||||
order_description = request.data.get("order_description", "Example GoPay payment")
|
||||
return_url = request.data.get("return_url", "https://yourfrontend.com/success")
|
||||
notify_url = request.data.get("notify_url", "https://yourbackend.com/gopay/notify")
|
||||
preauthorize = bool(request.data.get("preauthorize", False))
|
||||
|
||||
if not amount:
|
||||
return Response({"error": "Amount is required"}, status=400)
|
||||
|
||||
payments = self.get_gopay_client()
|
||||
|
||||
payment_data = {
|
||||
"payer": {
|
||||
"allowed_payment_instruments": ["PAYMENT_CARD"],
|
||||
"default_payment_instrument": "PAYMENT_CARD",
|
||||
"allowed_swifts": ["FIOB"],
|
||||
"contact": {
|
||||
"first_name": getattr(request.user, "first_name", ""),
|
||||
"last_name": getattr(request.user, "last_name", ""),
|
||||
"email": getattr(request.user, "email", ""),
|
||||
},
|
||||
},
|
||||
"amount": int(float(amount) * 100), # GoPay expects amount in cents
|
||||
"currency": currency,
|
||||
"order_number": order_number,
|
||||
"order_description": order_description,
|
||||
"items": [
|
||||
{"name": "Example Item", "amount": int(float(amount) * 100)}
|
||||
],
|
||||
"callback": {"return_url": return_url, "notify_url": notify_url},
|
||||
"preauthorize": preauthorize,
|
||||
}
|
||||
|
||||
resp = payments.create_payment(payment_data)
|
||||
return self._to_response(resp)
|
||||
|
||||
|
||||
class GoPayPaymentStatusView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Get GoPay payment status",
|
||||
parameters=[OpenApiParameter(name="payment_id", required=True, type=int, location=OpenApiParameter.PATH)],
|
||||
responses={200: OpenApiResponse(response=GoPayStatusResponseSerializer, description="Payment status")},
|
||||
)
|
||||
def get(self, request, payment_id: int):
|
||||
payments = self.get_gopay_client()
|
||||
resp = payments.get_status(payment_id)
|
||||
return self._to_response(resp)
|
||||
|
||||
|
||||
class GoPayRefundPaymentView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Refund GoPay payment",
|
||||
parameters=[OpenApiParameter(name="payment_id", required=True, type=int, location=OpenApiParameter.PATH)],
|
||||
request=GoPayRefundRequestSerializer,
|
||||
responses={200: OpenApiResponse(description="Refund processed")},
|
||||
)
|
||||
def post(self, request, payment_id: int):
|
||||
amount = request.data.get("amount") # optional for full refund
|
||||
payments = self.get_gopay_client()
|
||||
if amount is None or amount == "":
|
||||
# Full refund
|
||||
resp = payments.refund_payment(payment_id)
|
||||
else:
|
||||
resp = payments.refund_payment(payment_id, int(float(amount) * 100))
|
||||
return self._to_response(resp)
|
||||
|
||||
|
||||
class GoPayCaptureAuthorizationView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Capture GoPay authorization",
|
||||
parameters=[OpenApiParameter(name="payment_id", required=True, type=int, location=OpenApiParameter.PATH)],
|
||||
request=GoPayCaptureRequestSerializer,
|
||||
responses={200: OpenApiResponse(description="Capture processed")},
|
||||
)
|
||||
def post(self, request, payment_id: int):
|
||||
amount = request.data.get("amount") # optional for partial capture
|
||||
payments = self.get_gopay_client()
|
||||
if amount is None or amount == "":
|
||||
resp = payments.capture_authorization(payment_id)
|
||||
else:
|
||||
resp = payments.capture_authorization(payment_id, int(float(amount) * 100))
|
||||
return self._to_response(resp)
|
||||
|
||||
|
||||
class GoPayVoidAuthorizationView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Void GoPay authorization",
|
||||
parameters=[OpenApiParameter(name="payment_id", required=True, type=int, location=OpenApiParameter.PATH)],
|
||||
responses={200: OpenApiResponse(description="Authorization voided")},
|
||||
)
|
||||
def post(self, request, payment_id: int):
|
||||
payments = self.get_gopay_client()
|
||||
resp = payments.void_authorization(payment_id)
|
||||
return self._to_response(resp)
|
||||
|
||||
|
||||
class GoPayCreateRecurrenceView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Create GoPay recurrence",
|
||||
parameters=[OpenApiParameter(name="payment_id", required=True, type=int, location=OpenApiParameter.PATH)],
|
||||
request=GoPayCreateRecurrenceRequestSerializer,
|
||||
responses={200: OpenApiResponse(description="Recurrence created")},
|
||||
)
|
||||
def post(self, request, payment_id: int):
|
||||
amount = request.data.get("amount")
|
||||
currency = request.data.get("currency", "CZK")
|
||||
order_number = request.data.get("order_number", "recur-001")
|
||||
order_description = request.data.get("order_description", "Recurring payment")
|
||||
if not amount:
|
||||
return Response({"error": "Amount is required"}, status=400)
|
||||
payments = self.get_gopay_client()
|
||||
recurrence_payload = {
|
||||
"amount": int(float(amount) * 100),
|
||||
"currency": currency,
|
||||
"order_number": order_number,
|
||||
"order_description": order_description,
|
||||
}
|
||||
resp = payments.create_recurrence(payment_id, recurrence_payload)
|
||||
return self._to_response(resp)
|
||||
|
||||
|
||||
class GoPayPaymentInstrumentsView(GoPayClientMixin, APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["GoPay"],
|
||||
summary="Get GoPay payment instruments",
|
||||
parameters=[OpenApiParameter(name="currency", required=False, type=str, location=OpenApiParameter.QUERY)],
|
||||
responses={200: OpenApiResponse(description="Available payment instruments returned")},
|
||||
)
|
||||
def get(self, request):
|
||||
currency = request.query_params.get("currency", "CZK")
|
||||
goid = os.getenv("GOPAY_GOID")
|
||||
if not goid:
|
||||
return Response({"error": "GOPAY_GOID is not configured"}, status=500)
|
||||
payments = self.get_gopay_client()
|
||||
resp = payments.get_payment_instruments(goid, currency)
|
||||
return self._to_response(resp)
|
||||
0
backend/thirdparty/stripe/__init__.py
vendored
Normal file
0
backend/thirdparty/stripe/__init__.py
vendored
Normal file
3
backend/thirdparty/stripe/admin.py
vendored
Normal file
3
backend/thirdparty/stripe/admin.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
backend/thirdparty/stripe/apps.py
vendored
Normal file
6
backend/thirdparty/stripe/apps.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class StripeConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'stripe'
|
||||
0
backend/thirdparty/stripe/migrations/__init__.py
vendored
Normal file
0
backend/thirdparty/stripe/migrations/__init__.py
vendored
Normal file
3
backend/thirdparty/stripe/models.py
vendored
Normal file
3
backend/thirdparty/stripe/models.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
12
backend/thirdparty/stripe/serializers.py
vendored
Normal file
12
backend/thirdparty/stripe/serializers.py
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class StripeCheckoutRequestSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=12, decimal_places=2, min_value=0.01)
|
||||
product_name = serializers.CharField(required=False, default="Example Product")
|
||||
success_url = serializers.URLField(required=False)
|
||||
cancel_url = serializers.URLField(required=False)
|
||||
|
||||
|
||||
class StripeCheckoutResponseSerializer(serializers.Serializer):
|
||||
url = serializers.URLField()
|
||||
3
backend/thirdparty/stripe/tests.py
vendored
Normal file
3
backend/thirdparty/stripe/tests.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
6
backend/thirdparty/stripe/urls.py
vendored
Normal file
6
backend/thirdparty/stripe/urls.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.urls import path
|
||||
from .views import StripeCheckoutCZKView
|
||||
|
||||
urlpatterns = [
|
||||
path('checkout/', StripeCheckoutCZKView.as_view(), name='stripe-checkout-czk'),
|
||||
]
|
||||
71
backend/thirdparty/stripe/views.py
vendored
Normal file
71
backend/thirdparty/stripe/views.py
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import stripe
|
||||
import os
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
|
||||
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample, OpenApiParameter
|
||||
from .serializers import (
|
||||
StripeCheckoutRequestSerializer,
|
||||
StripeCheckoutResponseSerializer,
|
||||
)
|
||||
|
||||
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
|
||||
|
||||
|
||||
class StripeCheckoutCZKView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
tags=["Stripe"],
|
||||
summary="Create Stripe Checkout session in CZK",
|
||||
description="Creates a Stripe Checkout session for payment in Czech Koruna (CZK). Requires authentication.",
|
||||
request=StripeCheckoutRequestSerializer,
|
||||
responses={
|
||||
200: OpenApiResponse(response=StripeCheckoutResponseSerializer, description="Stripe Checkout session URL returned successfully."),
|
||||
400: OpenApiResponse(description="Amount is required or invalid."),
|
||||
},
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
"Success",
|
||||
value={"url": "https://checkout.stripe.com/pay/cs_test_123456"},
|
||||
response_only=True,
|
||||
status_codes=["200"],
|
||||
),
|
||||
OpenApiExample(
|
||||
"Missing amount",
|
||||
value={"error": "Amount is required"},
|
||||
response_only=True,
|
||||
status_codes=["400"],
|
||||
),
|
||||
]
|
||||
)
|
||||
def post(self, request):
|
||||
serializer = StripeCheckoutRequestSerializer(data=request.data)
|
||||
if not serializer.is_valid():
|
||||
return Response(serializer.errors, status=400)
|
||||
|
||||
amount = serializer.validated_data.get("amount")
|
||||
product_name = serializer.validated_data.get("product_name", "Example Product")
|
||||
success_url = serializer.validated_data.get("success_url", "https://yourfrontend.com/success")
|
||||
cancel_url = serializer.validated_data.get("cancel_url", "https://yourfrontend.com/cancel")
|
||||
# Stripe expects amount in the smallest currency unit (haléř = 1/100 CZK)
|
||||
amount_in_haler = int(amount * 100)
|
||||
session = stripe.checkout.Session.create(
|
||||
payment_method_types=['card'],
|
||||
line_items=[{
|
||||
'price_data': {
|
||||
'currency': 'czk',
|
||||
'product_data': {
|
||||
'name': product_name,
|
||||
},
|
||||
'unit_amount': amount_in_haler,
|
||||
},
|
||||
'quantity': 1,
|
||||
}],
|
||||
mode='payment',
|
||||
success_url=success_url,
|
||||
cancel_url=cancel_url,
|
||||
customer_email=getattr(request.user, 'email', None)
|
||||
)
|
||||
return Response({"url": session.url})
|
||||
0
backend/thirdparty/trading212/__init__.py
vendored
Normal file
0
backend/thirdparty/trading212/__init__.py
vendored
Normal file
3
backend/thirdparty/trading212/admin.py
vendored
Normal file
3
backend/thirdparty/trading212/admin.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
backend/thirdparty/trading212/apps.py
vendored
Normal file
6
backend/thirdparty/trading212/apps.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class Trading212Config(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'trading212'
|
||||
0
backend/thirdparty/trading212/migrations/__init__.py
vendored
Normal file
0
backend/thirdparty/trading212/migrations/__init__.py
vendored
Normal file
3
backend/thirdparty/trading212/models.py
vendored
Normal file
3
backend/thirdparty/trading212/models.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
11
backend/thirdparty/trading212/serializers.py
vendored
Normal file
11
backend/thirdparty/trading212/serializers.py
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# thirdparty/trading212/serializers.py
|
||||
from rest_framework import serializers
|
||||
|
||||
class Trading212AccountCashSerializer(serializers.Serializer):
|
||||
blocked = serializers.FloatField()
|
||||
free = serializers.FloatField()
|
||||
invested = serializers.FloatField()
|
||||
pieCash = serializers.FloatField()
|
||||
ppl = serializers.FloatField()
|
||||
result = serializers.FloatField()
|
||||
total = serializers.FloatField()
|
||||
3
backend/thirdparty/trading212/tests.py
vendored
Normal file
3
backend/thirdparty/trading212/tests.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
6
backend/thirdparty/trading212/urls.py
vendored
Normal file
6
backend/thirdparty/trading212/urls.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.urls import path
|
||||
from .views import YourTrading212View # Replace with actual view class
|
||||
|
||||
urlpatterns = [
|
||||
path('your-endpoint/', YourTrading212View.as_view(), name='trading212-endpoint'),
|
||||
]
|
||||
37
backend/thirdparty/trading212/views.py
vendored
Normal file
37
backend/thirdparty/trading212/views.py
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# thirdparty/trading212/views.py
|
||||
import os
|
||||
import requests
|
||||
from decouple import config
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from .serializers import Trading212AccountCashSerializer
|
||||
|
||||
from drf_spectacular.utils import extend_schema
|
||||
|
||||
class Trading212AccountCashView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Trading212 account cash",
|
||||
responses=Trading212AccountCashSerializer
|
||||
)
|
||||
def get(self, request):
|
||||
api_key = os.getenv("API_KEY_TRADING212")
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
url = "https://api.trading212.com/api/v0/equity/account/cash"
|
||||
|
||||
try:
|
||||
resp = requests.get(url, headers=headers, timeout=10)
|
||||
resp.raise_for_status()
|
||||
except requests.RequestException as exc:
|
||||
return Response({"error": str(exc)}, status=400)
|
||||
|
||||
data = resp.json()
|
||||
serializer = Trading212AccountCashSerializer(data=data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
return Response(serializer.data)
|
||||
Reference in New Issue
Block a user