import uuid from django.http import JsonResponse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.forms.models import model_to_dict from rest_framework.views import APIView from banking_operations.models import PaymentGateway, PaymentGatewayCredentials from mobile_api.utils import validate_token_and_get_user def _payment_gateway_to_dict(gateway, request=None): """Serialize PaymentGateway for JSON.""" data = model_to_dict( gateway, fields=[ "id", "payment_gateway_id", "payment_gateway_name", "payment_gateway_description", "payment_gateway_url", "payment_gateway_api_key", "payment_gateway_api_secret", "payment_gateway_api_url", "payment_gateway_api_version", "payment_gateway_api_method", "is_active", "created_date", "updated_date", "gateway_priority", ], ) # Add logo URL if exists if gateway.payment_gateway_logo: if request: data["payment_gateway_logo"] = gateway.payment_gateway_logo.url else: data["payment_gateway_logo"] = gateway.payment_gateway_logo.url else: data["payment_gateway_logo"] = None return data @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayCreateAPI(APIView): """ Create a new PaymentGateway. Body: token, username, payment_gateway_name, payment_gateway_description, payment_gateway_api_key, payment_gateway_api_secret, payment_gateway_api_version, payment_gateway_api_method (required); payment_gateway_logo (file upload), payment_gateway_url, payment_gateway_api_url, is_active, gateway_priority (optional). """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response payment_gateway_name = data.get("payment_gateway_name") payment_gateway_description = data.get("payment_gateway_description") payment_gateway_api_key = data.get("payment_gateway_api_key") payment_gateway_api_secret = data.get("payment_gateway_api_secret") payment_gateway_api_version = data.get("payment_gateway_api_version") payment_gateway_api_method = data.get("payment_gateway_api_method") if not all([ payment_gateway_name, payment_gateway_description, payment_gateway_api_key, payment_gateway_api_secret, payment_gateway_api_version, payment_gateway_api_method, ]): return JsonResponse( { "status": "error", "message": "payment_gateway_name, payment_gateway_description, payment_gateway_api_key, " "payment_gateway_api_secret, payment_gateway_api_version, and " "payment_gateway_api_method are required.", }, status=400, ) # Generate payment_gateway_id if not provided payment_gateway_id = data.get("payment_gateway_id") if not payment_gateway_id: payment_gateway_id = str(uuid.uuid4().hex[:10]).upper() gateway = PaymentGateway.objects.create( payment_gateway_id=payment_gateway_id, payment_gateway_name=payment_gateway_name, payment_gateway_description=payment_gateway_description, payment_gateway_url=data.get("payment_gateway_url"), payment_gateway_api_key=payment_gateway_api_key, payment_gateway_api_secret=payment_gateway_api_secret, payment_gateway_api_url=data.get("payment_gateway_api_url"), payment_gateway_api_version=payment_gateway_api_version, payment_gateway_api_method=payment_gateway_api_method, is_active=data.get("is_active", True), gateway_priority=data.get("gateway_priority", 0), ) # Handle logo upload if provided if "payment_gateway_logo" in request.FILES: gateway.payment_gateway_logo = request.FILES["payment_gateway_logo"] gateway.save() return JsonResponse( {"status": "success", "payment_gateway": _payment_gateway_to_dict(gateway, request)}, status=201, ) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayListAPI(APIView): """ List PaymentGateways, optionally filtered by is_active. Body: token, username, is_active (optional). """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response qs = PaymentGateway.objects.all().order_by("-gateway_priority", "-created_date") is_active = data.get("is_active") if is_active is not None: qs = qs.filter(is_active=bool(is_active)) gateways = [_payment_gateway_to_dict(g, request) for g in qs] return JsonResponse({"status": "success", "payment_gateways": gateways}, status=200) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayUpdateAPI(APIView): """ Update an existing PaymentGateway. Body: token, username, payment_gateway_id (required); payment_gateway_name, payment_gateway_description, payment_gateway_url, payment_gateway_api_key, payment_gateway_api_secret, payment_gateway_api_url, payment_gateway_api_version, payment_gateway_api_method, is_active, gateway_priority (optional); payment_gateway_logo (file upload, optional). """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response payment_gateway_id = data.get("payment_gateway_id") if not payment_gateway_id: return JsonResponse( {"status": "error", "message": "payment_gateway_id is required."}, status=400, ) try: gateway = PaymentGateway.objects.get(payment_gateway_id=payment_gateway_id) except PaymentGateway.DoesNotExist: return JsonResponse( {"status": "error", "message": "PaymentGateway not found."}, status=404, ) # Update fields if provided if data.get("payment_gateway_name") is not None: gateway.payment_gateway_name = data["payment_gateway_name"] if data.get("payment_gateway_description") is not None: gateway.payment_gateway_description = data["payment_gateway_description"] if "payment_gateway_url" in data: gateway.payment_gateway_url = data["payment_gateway_url"] or None if data.get("payment_gateway_api_key") is not None: gateway.payment_gateway_api_key = data["payment_gateway_api_key"] if data.get("payment_gateway_api_secret") is not None: gateway.payment_gateway_api_secret = data["payment_gateway_api_secret"] if "payment_gateway_api_url" in data: gateway.payment_gateway_api_url = data["payment_gateway_api_url"] or None if data.get("payment_gateway_api_version") is not None: gateway.payment_gateway_api_version = data["payment_gateway_api_version"] if data.get("payment_gateway_api_method") is not None: gateway.payment_gateway_api_method = data["payment_gateway_api_method"] if data.get("is_active") is not None: gateway.is_active = bool(data["is_active"]) if data.get("gateway_priority") is not None: try: gateway.gateway_priority = int(data["gateway_priority"]) except (TypeError, ValueError): return JsonResponse( {"status": "error", "message": "gateway_priority must be an integer."}, status=400, ) # Handle logo upload if provided if "payment_gateway_logo" in request.FILES: gateway.payment_gateway_logo = request.FILES["payment_gateway_logo"] gateway.save() return JsonResponse( {"status": "success", "payment_gateway": _payment_gateway_to_dict(gateway, request)}, status=200, ) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayDeleteAPI(APIView): """ Delete an existing PaymentGateway. Body: token, username, payment_gateway_id. """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response payment_gateway_id = data.get("payment_gateway_id") if not payment_gateway_id: return JsonResponse( {"status": "error", "message": "payment_gateway_id is required."}, status=400, ) try: gateway = PaymentGateway.objects.get(payment_gateway_id=payment_gateway_id) except PaymentGateway.DoesNotExist: return JsonResponse( {"status": "error", "message": "PaymentGateway not found."}, status=404, ) gateway_name = gateway.payment_gateway_name gateway.delete() return JsonResponse( {"status": "success", "message": f"PaymentGateway '{gateway_name}' deleted successfully."}, status=200, ) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) def _payment_gateway_credentials_to_dict(credentials, request=None): """Serialize PaymentGatewayCredentials for JSON.""" data = model_to_dict( credentials, fields=[ "id", "payment_gateway_credentials_value", "created_date", "updated_date", ], ) data["payment_gateway_id"] = credentials.payment_gateway_id data["payment_gateway_name"] = credentials.payment_gateway.payment_gateway_name data["payment_gateway_payment_gateway_id"] = credentials.payment_gateway.payment_gateway_id return data @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayCredentialsCreateAPI(APIView): """ Create a new PaymentGatewayCredentials. Body: token, username, payment_gateway_id (or payment_gateway_payment_gateway_id), payment_gateway_credentials_value (required). """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response payment_gateway_id = data.get("payment_gateway_id") or data.get("payment_gateway_payment_gateway_id") payment_gateway_credentials_value = data.get("payment_gateway_credentials_value") if not payment_gateway_id or not payment_gateway_credentials_value: return JsonResponse( { "status": "error", "message": "payment_gateway_id (or payment_gateway_payment_gateway_id) and payment_gateway_credentials_value are required.", }, status=400, ) try: gateway = PaymentGateway.objects.get(payment_gateway_id=payment_gateway_id) except PaymentGateway.DoesNotExist: return JsonResponse( {"status": "error", "message": "PaymentGateway not found."}, status=404, ) credentials = PaymentGatewayCredentials.objects.create( payment_gateway=gateway, payment_gateway_credentials_value=payment_gateway_credentials_value, ) return JsonResponse( {"status": "success", "credentials": _payment_gateway_credentials_to_dict(credentials, request)}, status=201, ) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayCredentialsListAPI(APIView): """ List PaymentGatewayCredentials, optionally filtered by payment_gateway_id. Body: token, username, payment_gateway_id (optional). """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response qs = PaymentGatewayCredentials.objects.select_related("payment_gateway").all().order_by("-created_date") payment_gateway_id = data.get("payment_gateway_id") or data.get("payment_gateway_payment_gateway_id") if payment_gateway_id: try: gateway = PaymentGateway.objects.get(payment_gateway_id=payment_gateway_id) qs = qs.filter(payment_gateway=gateway) except PaymentGateway.DoesNotExist: return JsonResponse( {"status": "error", "message": "PaymentGateway not found."}, status=404, ) credentials_list = [_payment_gateway_credentials_to_dict(c, request) for c in qs] return JsonResponse({"status": "success", "credentials": credentials_list}, status=200) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayCredentialsUpdateAPI(APIView): """ Update an existing PaymentGatewayCredentials. Body: token, username, credentials_id (required); payment_gateway_credentials_value (optional). """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response credentials_id = data.get("credentials_id") if not credentials_id: return JsonResponse( {"status": "error", "message": "credentials_id is required."}, status=400, ) try: credentials = PaymentGatewayCredentials.objects.select_related("payment_gateway").get(id=credentials_id) except PaymentGatewayCredentials.DoesNotExist: return JsonResponse( {"status": "error", "message": "PaymentGatewayCredentials not found."}, status=404, ) # Update credentials value if provided if data.get("payment_gateway_credentials_value") is not None: credentials.payment_gateway_credentials_value = data["payment_gateway_credentials_value"] credentials.save() return JsonResponse( {"status": "success", "credentials": _payment_gateway_credentials_to_dict(credentials, request)}, status=200, ) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500) @method_decorator(csrf_exempt, name="dispatch") class PaymentGatewayCredentialsDeleteAPI(APIView): """ Delete an existing PaymentGatewayCredentials. Body: token, username, credentials_id. """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request) if error_response: return error_response credentials_id = data.get("credentials_id") if not credentials_id: return JsonResponse( {"status": "error", "message": "credentials_id is required."}, status=400, ) try: credentials = PaymentGatewayCredentials.objects.select_related("payment_gateway").get(id=credentials_id) except PaymentGatewayCredentials.DoesNotExist: return JsonResponse( {"status": "error", "message": "PaymentGatewayCredentials not found."}, status=404, ) gateway_name = credentials.payment_gateway.payment_gateway_name credentials.delete() return JsonResponse( { "status": "success", "message": f"PaymentGatewayCredentials for '{gateway_name}' deleted successfully.", }, status=200, ) except Exception as e: return JsonResponse({"status": "error", "message": str(e)}, status=500)