django-cfg 1.3.1__py3-none-any.whl → 1.3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/payments/admin_interface/old/payments/base.html +175 -0
- django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +125 -0
- django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +113 -0
- django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +35 -0
- django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +309 -0
- django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +303 -0
- django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +382 -0
- django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +518 -0
- django_cfg/apps/payments/{static → admin_interface/old/static}/payments/css/components.css +248 -9
- django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +163 -0
- django_cfg/apps/payments/admin_interface/serializers/__init__.py +39 -0
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +149 -0
- django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +114 -0
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +55 -90
- django_cfg/apps/payments/admin_interface/templates/payments/components/dialog.html +81 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_help_dialog.html +112 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +175 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +21 -17
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +123 -250
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +170 -269
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +152 -355
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +202 -551
- django_cfg/apps/payments/admin_interface/views/__init__.py +25 -14
- django_cfg/apps/payments/admin_interface/views/api/__init__.py +20 -0
- django_cfg/apps/payments/admin_interface/views/api/payments.py +191 -0
- django_cfg/apps/payments/admin_interface/views/api/stats.py +206 -0
- django_cfg/apps/payments/admin_interface/views/api/users.py +60 -0
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +257 -0
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +70 -0
- django_cfg/apps/payments/admin_interface/views/base.py +114 -0
- django_cfg/apps/payments/admin_interface/views/dashboard.py +60 -0
- django_cfg/apps/payments/admin_interface/views/forms.py +94 -0
- django_cfg/apps/payments/config/helpers.py +2 -2
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +429 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +443 -0
- django_cfg/apps/payments/management/commands/manage_currencies.py +9 -20
- django_cfg/apps/payments/management/commands/manage_providers.py +5 -5
- django_cfg/apps/payments/management/commands/process_pending_payments.py +357 -0
- django_cfg/apps/payments/management/commands/test_providers.py +434 -0
- django_cfg/apps/payments/middleware/api_access.py +35 -34
- django_cfg/apps/payments/migrations/0001_initial.py +1 -1
- django_cfg/apps/payments/models/balance.py +5 -2
- django_cfg/apps/payments/models/managers/api_key_managers.py +6 -2
- django_cfg/apps/payments/models/managers/balance_managers.py +3 -3
- django_cfg/apps/payments/models/managers/payment_managers.py +5 -0
- django_cfg/apps/payments/models/managers/subscription_managers.py +3 -3
- django_cfg/apps/payments/models/subscriptions.py +0 -24
- django_cfg/apps/payments/services/cache/__init__.py +1 -1
- django_cfg/apps/payments/services/cache_service/__init__.py +143 -0
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +37 -0
- django_cfg/apps/payments/services/cache_service/interfaces.py +32 -0
- django_cfg/apps/payments/services/cache_service/keys.py +49 -0
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +47 -0
- django_cfg/apps/payments/services/cache_service/simple_cache.py +101 -0
- django_cfg/apps/payments/services/core/balance_service.py +13 -2
- django_cfg/apps/payments/services/core/payment_service.py +49 -22
- django_cfg/apps/payments/services/integrations/ngrok_service.py +3 -3
- django_cfg/apps/payments/services/providers/registry.py +20 -0
- django_cfg/apps/payments/signals/api_key_signals.py +2 -2
- django_cfg/apps/payments/signals/balance_signals.py +8 -5
- django_cfg/apps/payments/static/payments/js/api-client.js +385 -0
- django_cfg/apps/payments/static/payments/js/ngrok-status.js +58 -0
- django_cfg/apps/payments/static/payments/js/payment-dashboard.js +50 -0
- django_cfg/apps/payments/static/payments/js/payment-form.js +175 -0
- django_cfg/apps/payments/static/payments/js/payment-list.js +95 -0
- django_cfg/apps/payments/static/payments/js/webhook-dashboard.js +154 -0
- django_cfg/apps/payments/urls.py +4 -0
- django_cfg/apps/payments/urls_admin.py +37 -18
- django_cfg/apps/payments/views/api/api_keys.py +14 -0
- django_cfg/apps/payments/views/api/base.py +1 -0
- django_cfg/apps/payments/views/api/currencies.py +2 -2
- django_cfg/apps/payments/views/api/payments.py +11 -5
- django_cfg/apps/payments/views/api/subscriptions.py +36 -31
- django_cfg/apps/payments/views/overview/__init__.py +40 -0
- django_cfg/apps/payments/views/overview/serializers.py +205 -0
- django_cfg/apps/payments/views/overview/services.py +439 -0
- django_cfg/apps/payments/views/overview/urls.py +27 -0
- django_cfg/apps/payments/views/overview/views.py +231 -0
- django_cfg/apps/payments/views/serializers/api_keys.py +20 -6
- django_cfg/apps/payments/views/serializers/balances.py +5 -8
- django_cfg/apps/payments/views/serializers/currencies.py +2 -6
- django_cfg/apps/payments/views/serializers/payments.py +37 -32
- django_cfg/apps/payments/views/serializers/subscriptions.py +4 -26
- django_cfg/apps/urls.py +2 -1
- django_cfg/core/config.py +25 -15
- django_cfg/core/generation.py +12 -12
- django_cfg/core/integration/display/startup.py +1 -1
- django_cfg/core/validation.py +4 -4
- django_cfg/management/commands/show_config.py +2 -2
- django_cfg/management/commands/tree.py +1 -3
- django_cfg/middleware/__init__.py +2 -0
- django_cfg/middleware/static_nocache.py +55 -0
- django_cfg/models/payments.py +13 -15
- django_cfg/models/security.py +15 -0
- django_cfg/modules/django_ngrok.py +6 -0
- django_cfg/modules/django_unfold/dashboard.py +1 -3
- django_cfg/utils/smart_defaults.py +51 -5
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.5.dist-info}/METADATA +1 -1
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.5.dist-info}/RECORD +111 -69
- django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +0 -38
- django_cfg/apps/payments/admin_interface/views/payment_views.py +0 -259
- django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +0 -37
- django_cfg/apps/payments/services/cache/cache_service.py +0 -235
- /django_cfg/apps/payments/admin_interface/{templates → old}/payments/components/loading_spinner.html +0 -0
- /django_cfg/apps/payments/admin_interface/{templates → old}/payments/components/notification.html +0 -0
- /django_cfg/apps/payments/admin_interface/{templates → old}/payments/components/provider_card.html +0 -0
- /django_cfg/apps/payments/admin_interface/{templates → old}/payments/currency_converter.html +0 -0
- /django_cfg/apps/payments/admin_interface/{templates → old}/payments/payment_status.html +0 -0
- /django_cfg/apps/payments/{static → admin_interface/old/static}/payments/css/dashboard.css +0 -0
- /django_cfg/apps/payments/{static → admin_interface/old/static}/payments/js/components.js +0 -0
- /django_cfg/apps/payments/{static → admin_interface/old/static}/payments/js/utils.js +0 -0
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.5.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.5.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.5.dist-info}/licenses/LICENSE +0 -0
@@ -1,259 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Payment Template Views for Universal Payment System v2.0.
|
3
|
-
|
4
|
-
Django template views for payment forms and status pages.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from django.views.generic import TemplateView, DetailView
|
8
|
-
from django.contrib.auth.mixins import LoginRequiredMixin
|
9
|
-
from django.shortcuts import get_object_or_404
|
10
|
-
from django.http import JsonResponse
|
11
|
-
from django.utils import timezone
|
12
|
-
|
13
|
-
from ...models import UniversalPayment
|
14
|
-
from ...services.core.payment_service import PaymentService
|
15
|
-
from ...services.core.currency_service import CurrencyService
|
16
|
-
from ...services.integrations.providers_config import get_all_providers_info
|
17
|
-
|
18
|
-
|
19
|
-
class PaymentFormView(LoginRequiredMixin, TemplateView):
|
20
|
-
"""
|
21
|
-
Payment creation form view.
|
22
|
-
|
23
|
-
Displays a form for creating new payments with provider selection
|
24
|
-
and real-time currency conversion.
|
25
|
-
"""
|
26
|
-
template_name = 'payments/payment_form.html'
|
27
|
-
|
28
|
-
def get_context_data(self, **kwargs):
|
29
|
-
context = super().get_context_data(**kwargs)
|
30
|
-
|
31
|
-
# Add form data
|
32
|
-
context.update({
|
33
|
-
'page_title': 'Create Payment',
|
34
|
-
'page_subtitle': 'Process a payment through our universal payment system',
|
35
|
-
})
|
36
|
-
|
37
|
-
return context
|
38
|
-
|
39
|
-
def post(self, request, *args, **kwargs):
|
40
|
-
"""Handle AJAX payment creation."""
|
41
|
-
if not request.headers.get('Content-Type', '').startswith('application/json'):
|
42
|
-
return super().get(request, *args, **kwargs)
|
43
|
-
|
44
|
-
try:
|
45
|
-
import json
|
46
|
-
data = json.loads(request.body)
|
47
|
-
|
48
|
-
# Create payment using service
|
49
|
-
payment_service = PaymentService()
|
50
|
-
result = payment_service.create_payment(
|
51
|
-
user_id=request.user.id,
|
52
|
-
amount_usd=float(data.get('amount', 0)),
|
53
|
-
currency_code=data.get('currency', 'USD'),
|
54
|
-
provider=data.get('provider'),
|
55
|
-
callback_url=data.get('callback_url')
|
56
|
-
)
|
57
|
-
|
58
|
-
if result.success:
|
59
|
-
return JsonResponse({
|
60
|
-
'success': True,
|
61
|
-
'payment': {
|
62
|
-
'id': str(result.data.id),
|
63
|
-
'external_id': result.data.external_id,
|
64
|
-
'status': result.data.status,
|
65
|
-
'amount_usd': result.data.amount_usd,
|
66
|
-
'currency_code': result.data.currency_code,
|
67
|
-
'provider': result.data.provider,
|
68
|
-
'payment_url': result.data.payment_url,
|
69
|
-
'qr_code_url': result.data.qr_code_url,
|
70
|
-
}
|
71
|
-
})
|
72
|
-
else:
|
73
|
-
return JsonResponse({
|
74
|
-
'success': False,
|
75
|
-
'error': result.error_message
|
76
|
-
}, status=400)
|
77
|
-
|
78
|
-
except Exception as e:
|
79
|
-
return JsonResponse({
|
80
|
-
'success': False,
|
81
|
-
'error': str(e)
|
82
|
-
}, status=500)
|
83
|
-
|
84
|
-
|
85
|
-
class PaymentStatusView(DetailView):
|
86
|
-
"""
|
87
|
-
Payment status tracking view.
|
88
|
-
|
89
|
-
Displays payment status with real-time updates and timeline.
|
90
|
-
"""
|
91
|
-
model = UniversalPayment
|
92
|
-
template_name = 'payments/payment_status.html'
|
93
|
-
context_object_name = 'payment'
|
94
|
-
|
95
|
-
def get_object(self, queryset=None):
|
96
|
-
"""Get payment by ID with optimized query."""
|
97
|
-
if queryset is None:
|
98
|
-
queryset = self.get_queryset()
|
99
|
-
|
100
|
-
# Get payment ID from URL
|
101
|
-
payment_id = self.kwargs.get('pk')
|
102
|
-
|
103
|
-
return get_object_or_404(
|
104
|
-
queryset.select_related('currency', 'user')
|
105
|
-
.prefetch_related('transactions'),
|
106
|
-
id=payment_id
|
107
|
-
)
|
108
|
-
|
109
|
-
def get_context_data(self, **kwargs):
|
110
|
-
context = super().get_context_data(**kwargs)
|
111
|
-
payment = self.object
|
112
|
-
|
113
|
-
# Add page metadata
|
114
|
-
context.update({
|
115
|
-
'page_title': f'Payment #{payment.external_id or str(payment.id)[:8]}',
|
116
|
-
'page_subtitle': 'Track your payment progress in real-time',
|
117
|
-
})
|
118
|
-
|
119
|
-
return context
|
120
|
-
|
121
|
-
def get(self, request, *args, **kwargs):
|
122
|
-
"""Handle both template and AJAX requests."""
|
123
|
-
self.object = self.get_object()
|
124
|
-
|
125
|
-
# Handle AJAX requests for status updates
|
126
|
-
if request.headers.get('Accept') == 'application/json':
|
127
|
-
payment = self.object
|
128
|
-
|
129
|
-
return JsonResponse({
|
130
|
-
'id': str(payment.id),
|
131
|
-
'external_id': payment.external_id,
|
132
|
-
'status': payment.status,
|
133
|
-
'status_display': payment.get_status_display(),
|
134
|
-
'amount_usd': payment.amount_usd,
|
135
|
-
'amount_crypto': str(payment.amount_crypto) if payment.amount_crypto else None,
|
136
|
-
'currency_code': payment.currency.code,
|
137
|
-
'provider': payment.provider,
|
138
|
-
'network': payment.network,
|
139
|
-
'created_at': payment.created_at.isoformat(),
|
140
|
-
'updated_at': payment.updated_at.isoformat(),
|
141
|
-
'confirmed_at': payment.confirmed_at.isoformat() if payment.confirmed_at else None,
|
142
|
-
'payment_url': payment.payment_url,
|
143
|
-
'qr_code_url': payment.qr_code_url,
|
144
|
-
'exchange_rate': str(payment.exchange_rate) if payment.exchange_rate else None,
|
145
|
-
})
|
146
|
-
|
147
|
-
# Regular template response
|
148
|
-
return super().get(request, *args, **kwargs)
|
149
|
-
|
150
|
-
|
151
|
-
class PaymentListView(LoginRequiredMixin, TemplateView):
|
152
|
-
"""
|
153
|
-
Payment list view with filtering and search.
|
154
|
-
|
155
|
-
Displays a paginated list of payments with advanced filtering options.
|
156
|
-
"""
|
157
|
-
template_name = 'payments/payment_list.html'
|
158
|
-
|
159
|
-
def get_context_data(self, **kwargs):
|
160
|
-
context = super().get_context_data(**kwargs)
|
161
|
-
|
162
|
-
# Add page metadata
|
163
|
-
context.update({
|
164
|
-
'page_title': 'Payment History',
|
165
|
-
'page_subtitle': 'View and manage your payment transactions',
|
166
|
-
})
|
167
|
-
|
168
|
-
return context
|
169
|
-
|
170
|
-
|
171
|
-
class PaymentDashboardView(LoginRequiredMixin, TemplateView):
|
172
|
-
"""
|
173
|
-
Main payment dashboard view.
|
174
|
-
|
175
|
-
Displays payment statistics, recent activity, and quick actions.
|
176
|
-
"""
|
177
|
-
template_name = 'payments/payment_dashboard.html'
|
178
|
-
|
179
|
-
def get_context_data(self, **kwargs):
|
180
|
-
context = super().get_context_data(**kwargs)
|
181
|
-
|
182
|
-
# Get payment statistics
|
183
|
-
user_payments = UniversalPayment.objects.filter(user=self.request.user)
|
184
|
-
|
185
|
-
stats = {
|
186
|
-
'total_payments': user_payments.count(),
|
187
|
-
'completed_payments': user_payments.filter(status='completed').count(),
|
188
|
-
'pending_payments': user_payments.filter(status__in=['pending', 'processing']).count(),
|
189
|
-
'failed_payments': user_payments.filter(status__in=['failed', 'cancelled']).count(),
|
190
|
-
'total_amount': sum(p.amount_usd for p in user_payments.filter(status='completed')),
|
191
|
-
'recent_payments': user_payments.order_by('-created_at')[:5],
|
192
|
-
}
|
193
|
-
|
194
|
-
# Add page metadata
|
195
|
-
context.update({
|
196
|
-
'page_title': 'Payment Dashboard',
|
197
|
-
'page_subtitle': 'Overview of your payment activity',
|
198
|
-
'stats': stats,
|
199
|
-
})
|
200
|
-
|
201
|
-
return context
|
202
|
-
|
203
|
-
|
204
|
-
class CurrencyConverterView(TemplateView):
|
205
|
-
"""
|
206
|
-
Currency conversion tool view.
|
207
|
-
|
208
|
-
Provides real-time currency conversion rates and calculator.
|
209
|
-
"""
|
210
|
-
template_name = 'payments/currency_converter.html'
|
211
|
-
|
212
|
-
def get_context_data(self, **kwargs):
|
213
|
-
context = super().get_context_data(**kwargs)
|
214
|
-
|
215
|
-
# Add page metadata
|
216
|
-
context.update({
|
217
|
-
'page_title': 'Currency Converter',
|
218
|
-
'page_subtitle': 'Real-time currency conversion rates',
|
219
|
-
})
|
220
|
-
|
221
|
-
return context
|
222
|
-
|
223
|
-
def post(self, request, *args, **kwargs):
|
224
|
-
"""Handle AJAX conversion requests."""
|
225
|
-
if not request.headers.get('Content-Type', '').startswith('application/json'):
|
226
|
-
return super().get(request, *args, **kwargs)
|
227
|
-
|
228
|
-
try:
|
229
|
-
import json
|
230
|
-
data = json.loads(request.body)
|
231
|
-
|
232
|
-
# Use currency service for conversion
|
233
|
-
currency_service = CurrencyService()
|
234
|
-
result = currency_service.convert_currency(
|
235
|
-
amount=float(data.get('amount', 0)),
|
236
|
-
from_currency=data.get('from_currency', 'USD'),
|
237
|
-
to_currency=data.get('to_currency', 'BTC')
|
238
|
-
)
|
239
|
-
|
240
|
-
if result.success:
|
241
|
-
return JsonResponse({
|
242
|
-
'success': True,
|
243
|
-
'converted_amount': result.data.converted_amount,
|
244
|
-
'exchange_rate': result.data.exchange_rate,
|
245
|
-
'from_currency': result.data.from_currency,
|
246
|
-
'to_currency': result.data.to_currency,
|
247
|
-
'timestamp': timezone.now().isoformat(),
|
248
|
-
})
|
249
|
-
else:
|
250
|
-
return JsonResponse({
|
251
|
-
'success': False,
|
252
|
-
'error': result.error_message
|
253
|
-
}, status=400)
|
254
|
-
|
255
|
-
except Exception as e:
|
256
|
-
return JsonResponse({
|
257
|
-
'success': False,
|
258
|
-
'error': str(e)
|
259
|
-
}, status=500)
|
@@ -1,37 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Webhook dashboard template view.
|
3
|
-
|
4
|
-
Simple dashboard for monitoring webhook activity and provider status.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from django.views.generic import TemplateView
|
8
|
-
from django.contrib.admin.views.decorators import staff_member_required
|
9
|
-
from django.utils.decorators import method_decorator
|
10
|
-
from django.http import JsonResponse
|
11
|
-
|
12
|
-
|
13
|
-
@method_decorator(staff_member_required, name='dispatch')
|
14
|
-
class WebhookDashboardView(TemplateView):
|
15
|
-
"""
|
16
|
-
Webhook dashboard for monitoring and management.
|
17
|
-
|
18
|
-
Provides a simple interface for:
|
19
|
-
- Viewing webhook provider configurations
|
20
|
-
- Monitoring webhook activity
|
21
|
-
- Testing webhook endpoints
|
22
|
-
- Checking ngrok status
|
23
|
-
"""
|
24
|
-
|
25
|
-
template_name = 'payments/webhook_dashboard.html'
|
26
|
-
|
27
|
-
def get_context_data(self, **kwargs):
|
28
|
-
"""Add dashboard context data."""
|
29
|
-
context = super().get_context_data(**kwargs)
|
30
|
-
|
31
|
-
# Basic context - the real data comes from API endpoints
|
32
|
-
context.update({
|
33
|
-
'page_title': 'Webhook Dashboard',
|
34
|
-
'auto_refresh': True, # Enable auto-refresh
|
35
|
-
})
|
36
|
-
|
37
|
-
return context
|
@@ -1,235 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Cache services for the Universal Payment System v2.0.
|
3
|
-
|
4
|
-
Based on proven solutions from payments_old with improvements.
|
5
|
-
ONLY for API access control - NOT payment data!
|
6
|
-
"""
|
7
|
-
|
8
|
-
from abc import ABC, abstractmethod
|
9
|
-
from typing import Optional, Any, Dict
|
10
|
-
from django.core.cache import cache
|
11
|
-
from django_cfg.modules.django_logger import get_logger
|
12
|
-
|
13
|
-
logger = get_logger(__name__)
|
14
|
-
|
15
|
-
|
16
|
-
class CacheInterface(ABC):
|
17
|
-
"""Abstract cache interface."""
|
18
|
-
|
19
|
-
@abstractmethod
|
20
|
-
def get(self, key: str) -> Optional[Any]:
|
21
|
-
"""Get value from cache."""
|
22
|
-
pass
|
23
|
-
|
24
|
-
@abstractmethod
|
25
|
-
def set(self, key: str, value: Any, timeout: Optional[int] = None) -> bool:
|
26
|
-
"""Set value in cache."""
|
27
|
-
pass
|
28
|
-
|
29
|
-
@abstractmethod
|
30
|
-
def delete(self, key: str) -> bool:
|
31
|
-
"""Delete value from cache."""
|
32
|
-
pass
|
33
|
-
|
34
|
-
@abstractmethod
|
35
|
-
def exists(self, key: str) -> bool:
|
36
|
-
"""Check if key exists in cache."""
|
37
|
-
pass
|
38
|
-
|
39
|
-
|
40
|
-
class SimpleCache(CacheInterface):
|
41
|
-
"""
|
42
|
-
Simple cache implementation using Django's cache framework.
|
43
|
-
|
44
|
-
Falls back gracefully when cache is unavailable.
|
45
|
-
Based on proven solution from payments_old.
|
46
|
-
"""
|
47
|
-
|
48
|
-
def __init__(self, prefix: str = "payments"):
|
49
|
-
self.prefix = prefix
|
50
|
-
self.enabled = self._is_cache_enabled()
|
51
|
-
|
52
|
-
def _is_cache_enabled(self) -> bool:
|
53
|
-
"""Check if cache is enabled via PaymentsConfig."""
|
54
|
-
try:
|
55
|
-
from django_cfg.models.payments import PaymentsConfig
|
56
|
-
config = PaymentsConfig.get_current_config()
|
57
|
-
return config.enabled # Cache enabled if payments enabled
|
58
|
-
except Exception:
|
59
|
-
return True # Default to enabled with graceful fallback
|
60
|
-
|
61
|
-
def _make_key(self, key: str) -> str:
|
62
|
-
"""Create prefixed cache key."""
|
63
|
-
return f"{self.prefix}:{key}"
|
64
|
-
|
65
|
-
def get(self, key: str) -> Optional[Any]:
|
66
|
-
"""Get value from cache."""
|
67
|
-
if not self.enabled:
|
68
|
-
return None
|
69
|
-
|
70
|
-
try:
|
71
|
-
cache_key = self._make_key(key)
|
72
|
-
return cache.get(cache_key)
|
73
|
-
except Exception as e:
|
74
|
-
logger.warning(f"Cache get failed for key {key}: {e}")
|
75
|
-
return None
|
76
|
-
|
77
|
-
def set(self, key: str, value: Any, timeout: Optional[int] = None) -> bool:
|
78
|
-
"""Set value in cache."""
|
79
|
-
if not self.enabled:
|
80
|
-
return False
|
81
|
-
|
82
|
-
try:
|
83
|
-
cache_key = self._make_key(key)
|
84
|
-
cache.set(cache_key, value, timeout)
|
85
|
-
return True
|
86
|
-
except Exception as e:
|
87
|
-
logger.warning(f"Cache set failed for key {key}: {e}")
|
88
|
-
return False
|
89
|
-
|
90
|
-
def delete(self, key: str) -> bool:
|
91
|
-
"""Delete value from cache."""
|
92
|
-
if not self.enabled:
|
93
|
-
return False
|
94
|
-
|
95
|
-
try:
|
96
|
-
cache_key = self._make_key(key)
|
97
|
-
cache.delete(cache_key)
|
98
|
-
return True
|
99
|
-
except Exception as e:
|
100
|
-
logger.warning(f"Cache delete failed for key {key}: {e}")
|
101
|
-
return False
|
102
|
-
|
103
|
-
def exists(self, key: str) -> bool:
|
104
|
-
"""Check if key exists in cache."""
|
105
|
-
if not self.enabled:
|
106
|
-
return False
|
107
|
-
|
108
|
-
try:
|
109
|
-
cache_key = self._make_key(key)
|
110
|
-
return cache.get(cache_key) is not None
|
111
|
-
except Exception as e:
|
112
|
-
logger.warning(f"Cache exists check failed for key {key}: {e}")
|
113
|
-
return False
|
114
|
-
|
115
|
-
|
116
|
-
class ApiKeyCache:
|
117
|
-
"""Specialized cache for API key operations."""
|
118
|
-
|
119
|
-
def __init__(self):
|
120
|
-
self.cache = SimpleCache("api_keys")
|
121
|
-
self.default_timeout = self._get_cache_timeout('api_key')
|
122
|
-
|
123
|
-
def _get_cache_timeout(self, cache_type: str) -> int:
|
124
|
-
"""Get cache timeout from PaymentsConfig."""
|
125
|
-
try:
|
126
|
-
from django_cfg.models.payments import PaymentsConfig
|
127
|
-
config = PaymentsConfig.get_current_config()
|
128
|
-
return config.cache_timeouts.get(cache_type, 300)
|
129
|
-
except Exception:
|
130
|
-
return 300 # 5 minutes default
|
131
|
-
|
132
|
-
def get_api_key_data(self, api_key: str) -> Optional[dict]:
|
133
|
-
"""Get cached API key data."""
|
134
|
-
return self.cache.get(f"key:{api_key}")
|
135
|
-
|
136
|
-
def cache_api_key_data(self, api_key: str, data: dict) -> bool:
|
137
|
-
"""Cache API key data."""
|
138
|
-
return self.cache.set(f"key:{api_key}", data, self.default_timeout)
|
139
|
-
|
140
|
-
def invalidate_api_key(self, api_key: str) -> bool:
|
141
|
-
"""Invalidate cached API key."""
|
142
|
-
return self.cache.delete(f"key:{api_key}")
|
143
|
-
|
144
|
-
|
145
|
-
class RateLimitCache:
|
146
|
-
"""Specialized cache for rate limiting."""
|
147
|
-
|
148
|
-
def __init__(self):
|
149
|
-
self.cache = SimpleCache("rate_limit")
|
150
|
-
|
151
|
-
def get_usage_count(self, user_id: int, endpoint_group: str, window: str = "hour") -> int:
|
152
|
-
"""Get current usage count for rate limiting."""
|
153
|
-
key = f"usage:{user_id}:{endpoint_group}:{window}"
|
154
|
-
count = self.cache.get(key)
|
155
|
-
return count if count is not None else 0
|
156
|
-
|
157
|
-
def increment_usage(self, user_id: int, endpoint_group: str, window: str = "hour", ttl: Optional[int] = None) -> int:
|
158
|
-
"""Increment usage count and return new count."""
|
159
|
-
key = f"usage:{user_id}:{endpoint_group}:{window}"
|
160
|
-
|
161
|
-
# Get current count
|
162
|
-
current = self.get_usage_count(user_id, endpoint_group, window)
|
163
|
-
new_count = current + 1
|
164
|
-
|
165
|
-
# Get TTL from config or use defaults
|
166
|
-
if ttl is None:
|
167
|
-
try:
|
168
|
-
from django_cfg.models.payments import PaymentsConfig
|
169
|
-
config = PaymentsConfig.get_current_config()
|
170
|
-
ttl = config.cache_timeouts.get('rate_limit', 3600)
|
171
|
-
except Exception:
|
172
|
-
ttl = 3600 if window == "hour" else 86400 # 1 hour or 1 day
|
173
|
-
|
174
|
-
# Set new count with TTL
|
175
|
-
self.cache.set(key, new_count, ttl)
|
176
|
-
return new_count
|
177
|
-
|
178
|
-
def reset_usage(self, user_id: int, endpoint_group: str, window: str = "hour") -> bool:
|
179
|
-
"""Reset usage count."""
|
180
|
-
key = f"usage:{user_id}:{endpoint_group}:{window}"
|
181
|
-
return self.cache.delete(key)
|
182
|
-
|
183
|
-
|
184
|
-
class CacheService:
|
185
|
-
"""
|
186
|
-
Main cache service providing access to specialized caches.
|
187
|
-
|
188
|
-
Provides centralized access to different cache types.
|
189
|
-
"""
|
190
|
-
|
191
|
-
def __init__(self):
|
192
|
-
"""Initialize cache service with specialized caches."""
|
193
|
-
self.simple_cache = SimpleCache()
|
194
|
-
self.api_key_cache = ApiKeyCache()
|
195
|
-
self.rate_limit_cache = RateLimitCache()
|
196
|
-
|
197
|
-
def health_check(self) -> Dict[str, Any]:
|
198
|
-
"""Check cache health."""
|
199
|
-
try:
|
200
|
-
test_key = "health_check"
|
201
|
-
test_value = "ok"
|
202
|
-
|
203
|
-
# Test set/get/delete
|
204
|
-
self.simple_cache.set(test_key, test_value, 10)
|
205
|
-
retrieved = self.simple_cache.get(test_key)
|
206
|
-
self.simple_cache.delete(test_key)
|
207
|
-
|
208
|
-
is_healthy = retrieved == test_value
|
209
|
-
|
210
|
-
return {
|
211
|
-
'healthy': is_healthy,
|
212
|
-
'backend': cache.__class__.__name__,
|
213
|
-
'simple_cache': True,
|
214
|
-
'api_key_cache': True,
|
215
|
-
'rate_limit_cache': True
|
216
|
-
}
|
217
|
-
except Exception as e:
|
218
|
-
logger.error(f"Cache health check failed: {e}")
|
219
|
-
return {
|
220
|
-
'healthy': False,
|
221
|
-
'error': str(e),
|
222
|
-
'backend': cache.__class__.__name__
|
223
|
-
}
|
224
|
-
|
225
|
-
|
226
|
-
# Global cache service instance
|
227
|
-
_cache_service = None
|
228
|
-
|
229
|
-
|
230
|
-
def get_cache_service() -> CacheService:
|
231
|
-
"""Get global cache service instance."""
|
232
|
-
global _cache_service
|
233
|
-
if _cache_service is None:
|
234
|
-
_cache_service = CacheService()
|
235
|
-
return _cache_service
|
/django_cfg/apps/payments/admin_interface/{templates → old}/payments/components/loading_spinner.html
RENAMED
File without changes
|
/django_cfg/apps/payments/admin_interface/{templates → old}/payments/components/notification.html
RENAMED
File without changes
|
/django_cfg/apps/payments/admin_interface/{templates → old}/payments/components/provider_card.html
RENAMED
File without changes
|
/django_cfg/apps/payments/admin_interface/{templates → old}/payments/currency_converter.html
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|