project initialization
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
This commit is contained in:
617
backend/src/core/api/payment_views.py
Normal file
617
backend/src/core/api/payment_views.py
Normal file
@@ -0,0 +1,617 @@
|
||||
"""
|
||||
Payment Management API Views
|
||||
Handles payment processing, transactions, and financial management endpoints
|
||||
"""
|
||||
from rest_framework import viewsets, status, permissions
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.utils import timezone
|
||||
from drf_spectacular.utils import extend_schema, OpenApiParameter
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
|
||||
from core.models.payment import (
|
||||
PaymentTransaction, PaymentStatus, PaymentMethod, PaymentProvider,
|
||||
RefundTransaction, DisputeTransaction, PaymentWebhook
|
||||
)
|
||||
from core.models.subscription import Subscription
|
||||
from core.services.payment_service import PaymentService
|
||||
from core.services.subscription_service import SubscriptionService
|
||||
from core.auth.permissions import TenantPermission, IsTenantAdmin
|
||||
from core.serializers.payment import (
|
||||
PaymentTransactionSerializer,
|
||||
PaymentCreateSerializer,
|
||||
PaymentUpdateSerializer,
|
||||
RefundTransactionSerializer,
|
||||
DisputeTransactionSerializer,
|
||||
PaymentMethodSerializer,
|
||||
PaymentStatsSerializer,
|
||||
PaymentWebhookSerializer
|
||||
)
|
||||
|
||||
|
||||
class PaymentTransactionViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Payment Transaction ViewSet
|
||||
Provides CRUD operations for payment transactions with comprehensive financial logic
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated, TenantPermission]
|
||||
serializer_class = PaymentTransactionSerializer
|
||||
lookup_field = 'id'
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
Filter payment transactions based on tenant and permissions
|
||||
"""
|
||||
user = self.request.user
|
||||
tenant = user.tenant
|
||||
|
||||
if not tenant:
|
||||
return PaymentTransaction.objects.none()
|
||||
|
||||
# Superusers see all transactions
|
||||
if user.is_superuser:
|
||||
return PaymentTransaction.objects.all()
|
||||
|
||||
# Tenant admins/managers see their tenant's transactions
|
||||
if user.role in ['admin', 'manager']:
|
||||
return PaymentTransaction.objects.filter(tenant=tenant)
|
||||
|
||||
# Regular users see only their own transactions
|
||||
return PaymentTransaction.objects.filter(tenant=tenant, user=user)
|
||||
|
||||
def get_serializer_class(self):
|
||||
"""
|
||||
Return appropriate serializer based on action
|
||||
"""
|
||||
if self.action == 'create':
|
||||
return PaymentCreateSerializer
|
||||
elif self.action in ['update', 'partial_update']:
|
||||
return PaymentUpdateSerializer
|
||||
elif self.action == 'refund':
|
||||
return RefundTransactionSerializer
|
||||
elif self.action == 'dispute':
|
||||
return DisputeTransactionSerializer
|
||||
elif self.action == 'stats':
|
||||
return PaymentStatsSerializer
|
||||
elif self.action == 'methods':
|
||||
return PaymentMethodSerializer
|
||||
elif self.action == 'webhook':
|
||||
return PaymentWebhookSerializer
|
||||
return PaymentTransactionSerializer
|
||||
|
||||
def perform_create(self, serializer):
|
||||
"""
|
||||
Create payment transaction with proper initialization
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
transaction = payment_service.create_payment(serializer.validated_data)
|
||||
serializer.instance = transaction
|
||||
|
||||
def perform_update(self, serializer):
|
||||
"""
|
||||
Update payment transaction with validation
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
transaction = payment_service.update_payment(
|
||||
self.get_object(),
|
||||
serializer.validated_data
|
||||
)
|
||||
serializer.instance = transaction
|
||||
|
||||
@extend_schema(
|
||||
summary="Process Payment",
|
||||
description="Process payment with various payment methods",
|
||||
request=OpenApiTypes.OBJECT,
|
||||
responses={200: PaymentTransactionSerializer}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def process(self, request, *args, **kwargs):
|
||||
"""
|
||||
Process payment transaction
|
||||
"""
|
||||
transaction = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
result = payment_service.process_payment(transaction, request.data)
|
||||
serializer = PaymentTransactionSerializer(result)
|
||||
return Response(serializer.data)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Payment processing failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Refund Payment",
|
||||
description="Refund payment transaction",
|
||||
request=RefundTransactionSerializer,
|
||||
responses={200: RefundTransactionSerializer}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def refund(self, request, *args, **kwargs):
|
||||
"""
|
||||
Refund payment transaction
|
||||
"""
|
||||
transaction = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
refund = payment_service.refund_payment(transaction, request.data)
|
||||
serializer = RefundTransactionSerializer(refund)
|
||||
return Response(serializer.data)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Refund failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Dispute Payment",
|
||||
description="Dispute payment transaction",
|
||||
request=DisputeTransactionSerializer,
|
||||
responses={200: DisputeTransactionSerializer}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def dispute(self, request, *args, **kwargs):
|
||||
"""
|
||||
Dispute payment transaction
|
||||
"""
|
||||
transaction = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
dispute = payment_service.dispute_payment(transaction, request.data)
|
||||
serializer = DisputeTransactionSerializer(dispute)
|
||||
return Response(serializer.data)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Dispute failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Payment Receipt",
|
||||
description="Generate payment receipt",
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=True, methods=['get'])
|
||||
def receipt(self, request, *args, **kwargs):
|
||||
"""
|
||||
Get payment receipt
|
||||
"""
|
||||
transaction = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
receipt = payment_service.generate_receipt(transaction)
|
||||
return Response(receipt)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Receipt generation failed: {str(e)}'},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Payment Stats",
|
||||
description="Retrieve payment statistics",
|
||||
responses={200: PaymentStatsSerializer}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def stats(self, request):
|
||||
"""
|
||||
Get payment statistics
|
||||
"""
|
||||
tenant = request.user.tenant
|
||||
if not tenant:
|
||||
return Response(
|
||||
{'detail': 'Tenant not found'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
payment_service = PaymentService()
|
||||
stats = payment_service.get_payment_stats(tenant)
|
||||
serializer = PaymentStatsSerializer(stats)
|
||||
return Response(serializer.data)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Payment Methods",
|
||||
description="Retrieve available payment methods",
|
||||
responses={200: PaymentMethodSerializer(many=True)}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def methods(self, request):
|
||||
"""
|
||||
Get available payment methods
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
methods = payment_service.get_available_payment_methods()
|
||||
serializer = PaymentMethodSerializer(methods, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@extend_schema(
|
||||
summary="Validate Payment Method",
|
||||
description="Validate payment method details",
|
||||
request=OpenApiTypes.OBJECT,
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=False, methods=['post'])
|
||||
def validate_method(self, request):
|
||||
"""
|
||||
Validate payment method
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
validation_result = payment_service.validate_payment_method(request.data)
|
||||
return Response(validation_result)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Validation failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Handle Payment Webhook",
|
||||
description="Process payment provider webhook",
|
||||
request=PaymentWebhookSerializer,
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=False, methods=['post'])
|
||||
def webhook(self, request):
|
||||
"""
|
||||
Handle payment webhook
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
result = payment_service.handle_webhook(request.data)
|
||||
return Response(result)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Webhook processing failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Transaction History",
|
||||
description="Retrieve transaction history with filters",
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
name='start_date',
|
||||
description='Start date filter',
|
||||
type=OpenApiTypes.DATE
|
||||
),
|
||||
OpenApiParameter(
|
||||
name='end_date',
|
||||
description='End date filter',
|
||||
type=OpenApiTypes.DATE
|
||||
),
|
||||
OpenApiParameter(
|
||||
name='status',
|
||||
description='Status filter',
|
||||
type=OpenApiTypes.STR
|
||||
),
|
||||
OpenApiParameter(
|
||||
name='provider',
|
||||
description='Provider filter',
|
||||
type=OpenApiTypes.STR
|
||||
)
|
||||
],
|
||||
responses={200: PaymentTransactionSerializer(many=True)}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def history(self, request):
|
||||
"""
|
||||
Get transaction history
|
||||
"""
|
||||
tenant = request.user.tenant
|
||||
if not tenant:
|
||||
return Response(
|
||||
{'detail': 'Tenant not found'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
# Parse filters
|
||||
start_date = request.query_params.get('start_date')
|
||||
end_date = request.query_params.get('end_date')
|
||||
status_filter = request.query_params.get('status')
|
||||
provider_filter = request.query_params.get('provider')
|
||||
|
||||
payment_service = PaymentService()
|
||||
transactions = payment_service.get_transaction_history(
|
||||
tenant=tenant,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
status=status_filter,
|
||||
provider=provider_filter
|
||||
)
|
||||
serializer = PaymentTransactionSerializer(transactions, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Payment Analytics",
|
||||
description="Retrieve payment analytics and insights",
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
name='period',
|
||||
description='Analysis period (day, week, month, year)',
|
||||
type=OpenApiTypes.STR,
|
||||
default='month'
|
||||
)
|
||||
],
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def analytics(self, request):
|
||||
"""
|
||||
Get payment analytics
|
||||
"""
|
||||
tenant = request.user.tenant
|
||||
if not tenant:
|
||||
return Response(
|
||||
{'detail': 'Tenant not found'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
period = request.query_params.get('period', 'month')
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
analytics = payment_service.get_payment_analytics(tenant, period)
|
||||
return Response(analytics)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Analytics retrieval failed: {str(e)}'},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
def get_permissions(self):
|
||||
"""
|
||||
Override permissions based on action
|
||||
"""
|
||||
if self.action in ['refund', 'dispute', 'stats', 'analytics', 'webhook']:
|
||||
permission_classes = [IsAuthenticated, IsTenantAdmin]
|
||||
elif self.action in ['create', 'update', 'partial_update', 'destroy']:
|
||||
permission_classes = [IsAuthenticated, IsTenantAdmin]
|
||||
else:
|
||||
permission_classes = [IsAuthenticated, TenantPermission]
|
||||
|
||||
return [permission() for permission in permission_classes]
|
||||
|
||||
|
||||
class RefundTransactionViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Refund Transaction ViewSet
|
||||
Manages refund transactions
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated, IsTenantAdmin]
|
||||
serializer_class = RefundTransactionSerializer
|
||||
lookup_field = 'id'
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
Filter refund transactions based on tenant
|
||||
"""
|
||||
user = self.request.user
|
||||
tenant = user.tenant
|
||||
|
||||
if not tenant:
|
||||
return RefundTransaction.objects.none()
|
||||
|
||||
# Superusers see all refunds
|
||||
if user.is_superuser:
|
||||
return RefundTransaction.objects.all()
|
||||
|
||||
return RefundTransaction.objects.filter(payment_transaction__tenant=tenant)
|
||||
|
||||
@extend_schema(
|
||||
summary="Process Refund",
|
||||
description="Process refund transaction",
|
||||
responses={200: RefundTransactionSerializer}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def process(self, request, *args, **kwargs):
|
||||
"""
|
||||
Process refund transaction
|
||||
"""
|
||||
refund = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
result = payment_service.process_refund(refund)
|
||||
serializer = RefundTransactionSerializer(result)
|
||||
return Response(serializer.data)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Refund processing failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Cancel Refund",
|
||||
description="Cancel refund transaction",
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def cancel(self, request, *args, **kwargs):
|
||||
"""
|
||||
Cancel refund transaction
|
||||
"""
|
||||
refund = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
payment_service.cancel_refund(refund)
|
||||
return Response({'detail': 'Refund cancelled successfully'})
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Refund cancellation failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
|
||||
class DisputeTransactionViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Dispute Transaction ViewSet
|
||||
Manages dispute transactions
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated, IsTenantAdmin]
|
||||
serializer_class = DisputeTransactionSerializer
|
||||
lookup_field = 'id'
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
Filter dispute transactions based on tenant
|
||||
"""
|
||||
user = self.request.user
|
||||
tenant = user.tenant
|
||||
|
||||
if not tenant:
|
||||
return DisputeTransaction.objects.none()
|
||||
|
||||
# Superusers see all disputes
|
||||
if user.is_superuser:
|
||||
return DisputeTransaction.objects.all()
|
||||
|
||||
return DisputeTransaction.objects.filter(payment_transaction__tenant=tenant)
|
||||
|
||||
@extend_schema(
|
||||
summary="Submit Evidence",
|
||||
description="Submit evidence for dispute",
|
||||
request=OpenApiTypes.OBJECT,
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def submit_evidence(self, request, *args, **kwargs):
|
||||
"""
|
||||
Submit dispute evidence
|
||||
"""
|
||||
dispute = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
payment_service.submit_dispute_evidence(dispute, request.data)
|
||||
return Response({'detail': 'Evidence submitted successfully'})
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Evidence submission failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
summary="Escalate Dispute",
|
||||
description="Escalate dispute to payment provider",
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=True, methods=['post'])
|
||||
def escalate(self, request, *args, **kwargs):
|
||||
"""
|
||||
Escalate dispute
|
||||
"""
|
||||
dispute = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
payment_service.escalate_dispute(dispute)
|
||||
return Response({'detail': 'Dispute escalated successfully'})
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Dispute escalation failed: {str(e)}'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
|
||||
class PaymentMethodViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""
|
||||
Payment Method ViewSet
|
||||
Provides read-only access to payment methods
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated, TenantPermission]
|
||||
serializer_class = PaymentMethodSerializer
|
||||
lookup_field = 'id'
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
Return available payment methods
|
||||
"""
|
||||
return PaymentMethod.objects.filter(is_active=True)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Payment Method Fees",
|
||||
description="Retrieve payment method fees",
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=True, methods=['get'])
|
||||
def fees(self, request, *args, **kwargs):
|
||||
"""
|
||||
Get payment method fees
|
||||
"""
|
||||
payment_method = self.get_object()
|
||||
payment_service = PaymentService()
|
||||
|
||||
try:
|
||||
fees = payment_service.get_payment_method_fees(payment_method)
|
||||
return Response(fees)
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{'detail': f'Fee retrieval failed: {str(e)}'},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
|
||||
class PublicPaymentViewSet(viewsets.ViewSet):
|
||||
"""
|
||||
Public Payment ViewSet
|
||||
Provides public access to payment information
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Available Payment Methods",
|
||||
description="Retrieve publicly available payment methods",
|
||||
responses={200: PaymentMethodSerializer(many=True)}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def available_methods(self, request):
|
||||
"""
|
||||
Get available payment methods
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
methods = payment_service.get_public_payment_methods()
|
||||
serializer = PaymentMethodSerializer(methods, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Payment Providers",
|
||||
description="Retrieve supported payment providers",
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def providers(self, request):
|
||||
"""
|
||||
Get payment providers
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
providers = payment_service.get_payment_providers()
|
||||
return Response(providers)
|
||||
|
||||
@extend_schema(
|
||||
summary="Get Currency Information",
|
||||
description="Retrieve supported currencies and exchange rates",
|
||||
responses={200: OpenApiTypes.OBJECT}
|
||||
)
|
||||
@action(detail=False, methods=['get'])
|
||||
def currencies(self, request):
|
||||
"""
|
||||
Get currency information
|
||||
"""
|
||||
payment_service = PaymentService()
|
||||
currencies = payment_service.get_currency_info()
|
||||
return Response(currencies)
|
||||
Reference in New Issue
Block a user