django-cfg 1.2.31__py3-none-any.whl → 1.3.1__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/api/health/views.py +4 -2
- django_cfg/apps/knowbase/config/settings.py +16 -15
- django_cfg/apps/payments/README.md +326 -0
- django_cfg/apps/payments/admin/__init__.py +20 -10
- django_cfg/apps/payments/admin/api_keys_admin.py +521 -237
- django_cfg/apps/payments/admin/balance_admin.py +592 -297
- django_cfg/apps/payments/admin/currencies_admin.py +526 -222
- django_cfg/apps/payments/admin/filters.py +306 -199
- django_cfg/apps/payments/admin/payments_admin.py +465 -70
- django_cfg/apps/payments/admin/subscriptions_admin.py +578 -128
- django_cfg/apps/payments/admin_interface/__init__.py +18 -0
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +162 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +38 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/loading_spinner.html +16 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/notification.html +27 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/provider_card.html +86 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +39 -0
- django_cfg/apps/payments/admin_interface/templates/payments/currency_converter.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +300 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +303 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_status.html +500 -0
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +594 -0
- django_cfg/apps/payments/admin_interface/views/__init__.py +23 -0
- django_cfg/apps/payments/admin_interface/views/payment_views.py +259 -0
- django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +37 -0
- django_cfg/apps/payments/apps.py +34 -9
- django_cfg/apps/payments/config/__init__.py +28 -51
- django_cfg/apps/payments/config/constance/__init__.py +22 -0
- django_cfg/apps/payments/config/constance/config_service.py +123 -0
- django_cfg/apps/payments/config/constance/fields.py +69 -0
- django_cfg/apps/payments/config/constance/settings.py +160 -0
- django_cfg/apps/payments/config/django_cfg_integration.py +202 -0
- django_cfg/apps/payments/config/helpers.py +130 -0
- django_cfg/apps/payments/management/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/manage_currencies.py +303 -151
- django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
- django_cfg/apps/payments/middleware/__init__.py +3 -1
- django_cfg/apps/payments/middleware/api_access.py +329 -222
- django_cfg/apps/payments/middleware/rate_limiting.py +342 -152
- django_cfg/apps/payments/middleware/usage_tracking.py +249 -240
- django_cfg/apps/payments/migrations/0001_initial.py +708 -536
- django_cfg/apps/payments/models/__init__.py +13 -18
- django_cfg/apps/payments/models/api_keys.py +121 -43
- django_cfg/apps/payments/models/balance.py +150 -115
- django_cfg/apps/payments/models/base.py +68 -15
- django_cfg/apps/payments/models/currencies.py +172 -148
- django_cfg/apps/payments/models/managers/__init__.py +44 -0
- django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
- django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
- django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
- django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
- django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
- django_cfg/apps/payments/models/payments.py +235 -285
- django_cfg/apps/payments/models/subscriptions.py +257 -177
- django_cfg/apps/payments/models/tariffs.py +147 -40
- django_cfg/apps/payments/services/__init__.py +209 -56
- django_cfg/apps/payments/services/cache/__init__.py +6 -6
- django_cfg/apps/payments/services/cache/{simple_cache.py → cache_service.py} +112 -12
- django_cfg/apps/payments/services/core/__init__.py +10 -6
- django_cfg/apps/payments/services/core/balance_service.py +435 -360
- django_cfg/apps/payments/services/core/base.py +166 -0
- django_cfg/apps/payments/services/core/currency_service.py +478 -0
- django_cfg/apps/payments/services/core/payment_service.py +346 -467
- django_cfg/apps/payments/services/core/subscription_service.py +425 -481
- django_cfg/apps/payments/services/core/webhook_service.py +410 -0
- django_cfg/apps/payments/services/integrations/__init__.py +29 -0
- django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
- django_cfg/apps/payments/services/providers/__init__.py +9 -14
- django_cfg/apps/payments/services/providers/base.py +234 -174
- django_cfg/apps/payments/services/providers/nowpayments.py +478 -0
- django_cfg/apps/payments/services/providers/registry.py +367 -301
- django_cfg/apps/payments/services/types/__init__.py +78 -0
- django_cfg/apps/payments/services/types/data.py +177 -0
- django_cfg/apps/payments/services/types/requests.py +150 -0
- django_cfg/apps/payments/services/types/responses.py +156 -0
- django_cfg/apps/payments/services/types/webhooks.py +232 -0
- django_cfg/apps/payments/signals/__init__.py +33 -8
- django_cfg/apps/payments/signals/api_key_signals.py +210 -129
- django_cfg/apps/payments/signals/balance_signals.py +174 -0
- django_cfg/apps/payments/signals/payment_signals.py +128 -103
- django_cfg/apps/payments/signals/subscription_signals.py +194 -142
- django_cfg/apps/payments/static/payments/css/components.css +380 -0
- django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
- django_cfg/apps/payments/static/payments/js/components.js +545 -0
- django_cfg/apps/payments/static/payments/js/utils.js +412 -0
- django_cfg/apps/payments/templatetags/__init__.py +1 -1
- django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
- django_cfg/apps/payments/urls.py +45 -48
- django_cfg/apps/payments/urls_admin.py +33 -42
- django_cfg/apps/payments/views/api/__init__.py +101 -0
- django_cfg/apps/payments/views/api/api_keys.py +387 -0
- django_cfg/apps/payments/views/api/balances.py +381 -0
- django_cfg/apps/payments/views/api/base.py +298 -0
- django_cfg/apps/payments/views/api/currencies.py +402 -0
- django_cfg/apps/payments/views/api/payments.py +415 -0
- django_cfg/apps/payments/views/api/subscriptions.py +475 -0
- django_cfg/apps/payments/views/api/webhooks.py +476 -0
- django_cfg/apps/payments/views/serializers/__init__.py +99 -0
- django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
- django_cfg/apps/payments/views/serializers/balances.py +300 -0
- django_cfg/apps/payments/views/serializers/currencies.py +335 -0
- django_cfg/apps/payments/views/serializers/payments.py +387 -0
- django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
- django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +40 -4
- django_cfg/core/generation.py +25 -4
- django_cfg/core/integration/README.md +363 -0
- django_cfg/core/integration/__init__.py +47 -0
- django_cfg/core/integration/commands_collector.py +239 -0
- django_cfg/core/integration/display/__init__.py +15 -0
- django_cfg/core/integration/display/base.py +157 -0
- django_cfg/core/integration/display/ngrok.py +164 -0
- django_cfg/core/integration/display/startup.py +815 -0
- django_cfg/core/integration/url_integration.py +123 -0
- django_cfg/core/integration/version_checker.py +160 -0
- django_cfg/management/commands/auto_generate.py +4 -0
- django_cfg/management/commands/check_settings.py +6 -0
- django_cfg/management/commands/clear_constance.py +5 -2
- django_cfg/management/commands/create_token.py +6 -0
- django_cfg/management/commands/list_urls.py +6 -0
- django_cfg/management/commands/migrate_all.py +6 -0
- django_cfg/management/commands/migrator.py +3 -0
- django_cfg/management/commands/rundramatiq.py +6 -0
- django_cfg/management/commands/runserver_ngrok.py +51 -29
- django_cfg/management/commands/script.py +6 -0
- django_cfg/management/commands/show_config.py +12 -2
- django_cfg/management/commands/show_urls.py +4 -0
- django_cfg/management/commands/superuser.py +6 -0
- django_cfg/management/commands/task_clear.py +4 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -0
- django_cfg/management/commands/test_telegram.py +6 -0
- django_cfg/management/commands/test_twilio.py +6 -0
- django_cfg/management/commands/tree.py +6 -0
- django_cfg/management/commands/validate_config.py +155 -149
- django_cfg/models/constance.py +31 -11
- django_cfg/models/payments.py +175 -492
- django_cfg/modules/django_logger.py +160 -146
- django_cfg/modules/django_unfold/dashboard.py +64 -16
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/utils/smart_defaults.py +222 -571
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/METADATA +4 -1
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/RECORD +153 -185
- django_cfg/apps/payments/__init__.py +0 -8
- django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
- django_cfg/apps/payments/config/module.py +0 -70
- django_cfg/apps/payments/config/providers.py +0 -105
- django_cfg/apps/payments/config/settings.py +0 -96
- django_cfg/apps/payments/config/utils.py +0 -52
- django_cfg/apps/payments/decorators.py +0 -291
- django_cfg/apps/payments/management/commands/README.md +0 -146
- django_cfg/apps/payments/management/commands/currency_stats.py +0 -304
- django_cfg/apps/payments/managers/__init__.py +0 -23
- django_cfg/apps/payments/managers/api_key_manager.py +0 -35
- django_cfg/apps/payments/managers/balance_manager.py +0 -361
- django_cfg/apps/payments/managers/currency_manager.py +0 -306
- django_cfg/apps/payments/managers/payment_manager.py +0 -192
- django_cfg/apps/payments/managers/subscription_manager.py +0 -37
- django_cfg/apps/payments/managers/tariff_manager.py +0 -29
- django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +0 -241
- django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +0 -30
- django_cfg/apps/payments/models/events.py +0 -73
- django_cfg/apps/payments/serializers/__init__.py +0 -57
- django_cfg/apps/payments/serializers/api_keys.py +0 -51
- django_cfg/apps/payments/serializers/balance.py +0 -59
- django_cfg/apps/payments/serializers/currencies.py +0 -63
- django_cfg/apps/payments/serializers/payments.py +0 -62
- django_cfg/apps/payments/serializers/subscriptions.py +0 -71
- django_cfg/apps/payments/serializers/tariffs.py +0 -56
- django_cfg/apps/payments/services/billing/__init__.py +0 -8
- django_cfg/apps/payments/services/cache/base.py +0 -30
- django_cfg/apps/payments/services/core/fallback_service.py +0 -432
- django_cfg/apps/payments/services/internal_types.py +0 -461
- django_cfg/apps/payments/services/middleware/__init__.py +0 -8
- django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
- django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -76
- django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
- django_cfg/apps/payments/services/providers/cryptapi/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/cryptapi/config.py +0 -8
- django_cfg/apps/payments/services/providers/cryptapi/models.py +0 -192
- django_cfg/apps/payments/services/providers/cryptapi/provider.py +0 -439
- django_cfg/apps/payments/services/providers/cryptomus/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/cryptomus/models.py +0 -176
- django_cfg/apps/payments/services/providers/cryptomus/provider.py +0 -429
- django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +0 -564
- django_cfg/apps/payments/services/providers/models/__init__.py +0 -34
- django_cfg/apps/payments/services/providers/models/currencies.py +0 -190
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/nowpayments/models.py +0 -196
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +0 -380
- django_cfg/apps/payments/services/providers/stripe/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/stripe/models.py +0 -184
- django_cfg/apps/payments/services/providers/stripe/provider.py +0 -109
- django_cfg/apps/payments/services/security/__init__.py +0 -34
- django_cfg/apps/payments/services/security/error_handler.py +0 -635
- django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
- django_cfg/apps/payments/services/security/webhook_validator.py +0 -474
- django_cfg/apps/payments/static/payments/css/payments.css +0 -340
- django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
- django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
- django_cfg/apps/payments/static/payments/js/theme.js +0 -86
- django_cfg/apps/payments/tasks/__init__.py +0 -12
- django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +0 -50
- django_cfg/apps/payments/templates/payments/base.html +0 -182
- django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -43
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
- django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -34
- django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -148
- django_cfg/apps/payments/templates/payments/dashboard.html +0 -258
- django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +0 -35
- django_cfg/apps/payments/templates/payments/payment_create.html +0 -579
- django_cfg/apps/payments/templates/payments/payment_detail.html +0 -373
- django_cfg/apps/payments/templates/payments/payment_list.html +0 -354
- django_cfg/apps/payments/templates/payments/stats.html +0 -261
- django_cfg/apps/payments/templates/payments/test.html +0 -213
- django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
- django_cfg/apps/payments/utils/__init__.py +0 -43
- django_cfg/apps/payments/utils/billing_utils.py +0 -342
- django_cfg/apps/payments/utils/config_utils.py +0 -239
- django_cfg/apps/payments/utils/middleware_utils.py +0 -228
- django_cfg/apps/payments/utils/validation_utils.py +0 -94
- django_cfg/apps/payments/views/__init__.py +0 -63
- django_cfg/apps/payments/views/api_key_views.py +0 -164
- django_cfg/apps/payments/views/balance_views.py +0 -75
- django_cfg/apps/payments/views/currency_views.py +0 -122
- django_cfg/apps/payments/views/payment_views.py +0 -149
- django_cfg/apps/payments/views/subscription_views.py +0 -135
- django_cfg/apps/payments/views/tariff_views.py +0 -131
- django_cfg/apps/payments/views/templates/__init__.py +0 -25
- django_cfg/apps/payments/views/templates/ajax.py +0 -451
- django_cfg/apps/payments/views/templates/base.py +0 -212
- django_cfg/apps/payments/views/templates/dashboard.py +0 -60
- django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
- django_cfg/apps/payments/views/templates/payment_management.py +0 -158
- django_cfg/apps/payments/views/templates/qr_code.py +0 -174
- django_cfg/apps/payments/views/templates/stats.py +0 -244
- django_cfg/apps/payments/views/templates/utils.py +0 -181
- django_cfg/apps/payments/views/webhook_views.py +0 -266
- django_cfg/apps/payments/viewsets.py +0 -66
- django_cfg/core/integration.py +0 -160
- django_cfg/template_archive/.gitignore +0 -1
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/urls.py +0 -33
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,259 @@
|
|
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)
|
@@ -0,0 +1,37 @@
|
|
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
|
django_cfg/apps/payments/apps.py
CHANGED
@@ -1,22 +1,47 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Universal Payment System v2.0 - Django App Configuration.
|
3
|
+
|
4
|
+
Simplified payment system focused on NowPayments with extensible architecture.
|
3
5
|
"""
|
4
6
|
|
5
7
|
from django.apps import AppConfig
|
8
|
+
from django_cfg.modules.django_logger import get_logger
|
9
|
+
|
10
|
+
logger = get_logger("payments")
|
6
11
|
|
7
12
|
|
8
13
|
class PaymentsConfig(AppConfig):
|
9
|
-
"""
|
14
|
+
"""Payment system app configuration."""
|
10
15
|
|
11
16
|
default_auto_field = 'django.db.models.BigAutoField'
|
12
17
|
name = 'django_cfg.apps.payments'
|
13
|
-
|
14
|
-
verbose_name = 'Universal Payments'
|
18
|
+
verbose_name = 'Universal Payment System v2.0'
|
15
19
|
|
16
20
|
def ready(self):
|
17
|
-
"""
|
18
|
-
|
21
|
+
"""Initialize payment system when Django starts."""
|
22
|
+
logger.info("Initializing Universal Payment System v2.0")
|
23
|
+
|
24
|
+
# Import signals to register them
|
25
|
+
try:
|
26
|
+
from . import signals # noqa: F401
|
27
|
+
logger.info("Payment signals registered successfully")
|
28
|
+
except ImportError as e:
|
29
|
+
logger.warning(f"Failed to import payment signals: {e}")
|
30
|
+
|
31
|
+
# Initialize provider registry
|
32
|
+
try:
|
33
|
+
from .services.providers.registry import get_provider_registry
|
34
|
+
registry = get_provider_registry()
|
35
|
+
logger.info(f"Provider registry initialized with {len(registry.get_available_providers())} providers")
|
36
|
+
except Exception as e:
|
37
|
+
logger.error(f"Failed to initialize provider registry: {e}")
|
38
|
+
|
39
|
+
# Initialize cache services
|
19
40
|
try:
|
20
|
-
from . import
|
21
|
-
|
22
|
-
|
41
|
+
from .services.cache import get_cache_service
|
42
|
+
cache_service = get_cache_service()
|
43
|
+
logger.info("Cache service initialized successfully")
|
44
|
+
except Exception as e:
|
45
|
+
logger.warning(f"Cache service initialization failed: {e}")
|
46
|
+
|
47
|
+
logger.info("Universal Payment System v2.0 ready")
|
@@ -1,65 +1,42 @@
|
|
1
1
|
"""
|
2
|
-
Universal Payment
|
2
|
+
Configuration module for the Universal Payment System v2.0.
|
3
3
|
|
4
|
-
|
4
|
+
Provides clean separation between:
|
5
|
+
- django-cfg integration (static config)
|
6
|
+
- Constance integration (dynamic config)
|
7
|
+
- Configuration utilities and helpers
|
5
8
|
"""
|
6
9
|
|
7
|
-
#
|
8
|
-
from .
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
SecuritySettings,
|
13
|
-
RateLimitSettings,
|
14
|
-
NotificationSettings,
|
15
|
-
SubscriptionSettings
|
10
|
+
# Django-cfg integration
|
11
|
+
from .django_cfg_integration import (
|
12
|
+
PaymentsConfigMixin,
|
13
|
+
get_payments_config,
|
14
|
+
is_payments_enabled,
|
16
15
|
)
|
17
16
|
|
18
|
-
#
|
19
|
-
from
|
20
|
-
|
21
|
-
|
22
|
-
StripeConfig,
|
23
|
-
CryptAPIConfig
|
17
|
+
# Constance integration (safe - no Django models)
|
18
|
+
from .constance import (
|
19
|
+
get_django_cfg_payments_constance_fields,
|
20
|
+
PaymentConstanceSettings,
|
24
21
|
)
|
25
22
|
|
26
|
-
#
|
27
|
-
from .
|
28
|
-
|
29
|
-
|
30
|
-
from .module import PaymentsCfgModule
|
31
|
-
|
32
|
-
# Utility functions
|
33
|
-
from .utils import (
|
34
|
-
get_payments_config,
|
35
|
-
get_provider_config,
|
36
|
-
is_payments_enabled
|
23
|
+
# Configuration helpers
|
24
|
+
from .helpers import (
|
25
|
+
MiddlewareConfigHelper,
|
26
|
+
CacheConfigHelper,
|
37
27
|
)
|
38
28
|
|
39
|
-
# Backwards compatibility exports
|
40
|
-
payments_config = PaymentsCfgModule()
|
41
|
-
|
42
29
|
__all__ = [
|
43
|
-
#
|
44
|
-
'
|
45
|
-
'SecuritySettings',
|
46
|
-
'RateLimitSettings',
|
47
|
-
'NotificationSettings',
|
48
|
-
'SubscriptionSettings',
|
49
|
-
|
50
|
-
# Provider configurations
|
51
|
-
'PaymentProviderConfig',
|
52
|
-
'NowPaymentsConfig',
|
53
|
-
'StripeConfig',
|
54
|
-
'CryptAPIConfig',
|
55
|
-
'CryptomusConfig',
|
56
|
-
|
57
|
-
# Configuration module
|
58
|
-
'PaymentsCfgModule',
|
59
|
-
'payments_config',
|
60
|
-
|
61
|
-
# Utility functions
|
30
|
+
# Django-cfg integration
|
31
|
+
'PaymentsConfigMixin',
|
62
32
|
'get_payments_config',
|
63
|
-
'get_provider_config',
|
64
33
|
'is_payments_enabled',
|
34
|
+
|
35
|
+
# Constance integration
|
36
|
+
'get_django_cfg_payments_constance_fields',
|
37
|
+
'PaymentConstanceSettings',
|
38
|
+
|
39
|
+
# Configuration helpers
|
40
|
+
'MiddlewareConfigHelper',
|
41
|
+
'CacheConfigHelper',
|
65
42
|
]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""
|
2
|
+
Constance configuration for Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Centralized configuration for dynamic settings that can be changed at runtime
|
5
|
+
through Django admin interface.
|
6
|
+
|
7
|
+
This module provides:
|
8
|
+
- Field definitions for Constance
|
9
|
+
- Settings validation and defaults
|
10
|
+
- Integration with django-cfg PaymentsConfig
|
11
|
+
"""
|
12
|
+
|
13
|
+
from .fields import get_django_cfg_payments_constance_fields
|
14
|
+
from .settings import PaymentConstanceSettings
|
15
|
+
from .config_service import PaymentConfigService, get_payment_config_service
|
16
|
+
|
17
|
+
__all__ = [
|
18
|
+
'get_django_cfg_payments_constance_fields',
|
19
|
+
'PaymentConstanceSettings',
|
20
|
+
'PaymentConfigService',
|
21
|
+
'get_payment_config_service',
|
22
|
+
]
|
@@ -0,0 +1,123 @@
|
|
1
|
+
"""
|
2
|
+
Configuration service for payments using Constance.
|
3
|
+
|
4
|
+
Provides easy access to Constance settings with type safety and caching.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, Any, Optional
|
8
|
+
from django_cfg.modules.django_logger import get_logger
|
9
|
+
from .settings import PaymentConstanceSettings, get_payment_settings
|
10
|
+
|
11
|
+
logger = get_logger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
class PaymentConfigService:
|
15
|
+
"""
|
16
|
+
Service for accessing payment configuration from Constance.
|
17
|
+
|
18
|
+
Provides type-safe access to dynamic settings with caching and validation.
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self):
|
22
|
+
"""Initialize config service."""
|
23
|
+
self._cached_settings: Optional[PaymentConstanceSettings] = None
|
24
|
+
self._cache_timeout = 60 # Cache for 1 minute
|
25
|
+
self._last_refresh = 0
|
26
|
+
|
27
|
+
def get_settings(self, force_refresh: bool = False) -> PaymentConstanceSettings:
|
28
|
+
"""
|
29
|
+
Get current payment settings from Constance.
|
30
|
+
|
31
|
+
Args:
|
32
|
+
force_refresh: Force refresh from Constance (ignore cache)
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
PaymentConstanceSettings instance
|
36
|
+
"""
|
37
|
+
import time
|
38
|
+
|
39
|
+
current_time = time.time()
|
40
|
+
|
41
|
+
if (force_refresh or
|
42
|
+
self._cached_settings is None or
|
43
|
+
(current_time - self._last_refresh) > self._cache_timeout):
|
44
|
+
|
45
|
+
try:
|
46
|
+
self._cached_settings = get_payment_settings()
|
47
|
+
self._last_refresh = current_time
|
48
|
+
logger.debug("Refreshed payment settings from Constance")
|
49
|
+
except Exception as e:
|
50
|
+
logger.error(f"Failed to refresh payment settings: {e}")
|
51
|
+
if self._cached_settings is None:
|
52
|
+
# Fallback to defaults if no cache
|
53
|
+
self._cached_settings = PaymentConstanceSettings()
|
54
|
+
|
55
|
+
return self._cached_settings
|
56
|
+
|
57
|
+
def is_enabled(self) -> bool:
|
58
|
+
"""Check if payments system is enabled."""
|
59
|
+
return self.get_settings().enabled
|
60
|
+
|
61
|
+
def is_middleware_enabled(self) -> bool:
|
62
|
+
"""Check if payments middleware is enabled."""
|
63
|
+
return self.get_settings().middleware_enabled
|
64
|
+
|
65
|
+
def is_rate_limiting_enabled(self) -> bool:
|
66
|
+
"""Check if rate limiting is enabled."""
|
67
|
+
return self.get_settings().rate_limiting_enabled
|
68
|
+
|
69
|
+
def is_usage_tracking_enabled(self) -> bool:
|
70
|
+
"""Check if usage tracking is enabled."""
|
71
|
+
return self.get_settings().usage_tracking_enabled
|
72
|
+
|
73
|
+
def get_rate_limits(self) -> Dict[str, int]:
|
74
|
+
"""Get rate limits configuration."""
|
75
|
+
return self.get_settings().get_rate_limits()
|
76
|
+
|
77
|
+
def get_cache_timeouts(self) -> Dict[str, int]:
|
78
|
+
"""Get cache timeouts configuration."""
|
79
|
+
return self.get_settings().get_cache_timeouts()
|
80
|
+
|
81
|
+
def get_provider_config(self, provider: str) -> Dict[str, Any]:
|
82
|
+
"""Get provider-specific configuration."""
|
83
|
+
return self.get_settings().get_provider_config(provider)
|
84
|
+
|
85
|
+
def get_nowpayments_config(self) -> Dict[str, Any]:
|
86
|
+
"""Get NowPayments configuration."""
|
87
|
+
return self.get_provider_config('nowpayments')
|
88
|
+
|
89
|
+
def refresh_configuration(self):
|
90
|
+
"""Force refresh configuration from Constance."""
|
91
|
+
self.get_settings(force_refresh=True)
|
92
|
+
|
93
|
+
def get_all_provider_configs(self) -> Dict[str, Dict[str, Any]]:
|
94
|
+
"""Get all provider configurations."""
|
95
|
+
return {
|
96
|
+
'nowpayments': self.get_nowpayments_config(),
|
97
|
+
}
|
98
|
+
|
99
|
+
def get_constance_settings(self) -> PaymentConstanceSettings:
|
100
|
+
"""
|
101
|
+
Alias for get_settings() for backward compatibility.
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
PaymentConstanceSettings instance
|
105
|
+
"""
|
106
|
+
return self.get_settings()
|
107
|
+
|
108
|
+
|
109
|
+
# Global instance
|
110
|
+
_config_service: Optional[PaymentConfigService] = None
|
111
|
+
|
112
|
+
|
113
|
+
def get_payment_config_service() -> PaymentConfigService:
|
114
|
+
"""
|
115
|
+
Get global payment config service instance.
|
116
|
+
|
117
|
+
Returns:
|
118
|
+
PaymentConfigService instance
|
119
|
+
"""
|
120
|
+
global _config_service
|
121
|
+
if _config_service is None:
|
122
|
+
_config_service = PaymentConfigService()
|
123
|
+
return _config_service
|
@@ -0,0 +1,69 @@
|
|
1
|
+
"""
|
2
|
+
Constance fields configuration for Payments app.
|
3
|
+
|
4
|
+
This module defines ONLY dynamic settings that need to be changed at runtime.
|
5
|
+
Static configuration is handled by PaymentsConfig Pydantic model.
|
6
|
+
|
7
|
+
Note: This file MUST NOT import Django models or anything that requires
|
8
|
+
Django apps to be loaded, as it's imported during settings generation.
|
9
|
+
"""
|
10
|
+
|
11
|
+
from typing import List
|
12
|
+
from django_cfg.models.constance import ConstanceField
|
13
|
+
|
14
|
+
|
15
|
+
def get_django_cfg_payments_constance_fields() -> List[ConstanceField]:
|
16
|
+
"""
|
17
|
+
Get Constance field definitions for Payments app.
|
18
|
+
|
19
|
+
Only includes settings that need runtime configuration:
|
20
|
+
- API keys and secrets (change per environment)
|
21
|
+
- Rate limits (admins need to adjust)
|
22
|
+
- Usage tracking preferences
|
23
|
+
- Currency update intervals
|
24
|
+
|
25
|
+
Static settings (enabled flags, middleware, cache timeouts) are handled
|
26
|
+
by PaymentsConfig Pydantic model and auto-detection.
|
27
|
+
|
28
|
+
Returns:
|
29
|
+
List of ConstanceField objects for runtime-configurable settings
|
30
|
+
"""
|
31
|
+
# Import PaymentsConfigManager for consistent config access
|
32
|
+
from ..django_cfg_integration import PaymentsConfigManager
|
33
|
+
|
34
|
+
# Get default values from initialized Pydantic config using PaymentsConfigManager
|
35
|
+
default_config = PaymentsConfigManager.get_payments_config()
|
36
|
+
|
37
|
+
return [
|
38
|
+
# === 📊 Usage Tracking ===
|
39
|
+
ConstanceField(
|
40
|
+
name='PAYMENTS_TRACK_ANONYMOUS_USAGE',
|
41
|
+
default=default_config.track_anonymous_usage,
|
42
|
+
help_text="📊 Usage Tracking: Track usage for anonymous users (privacy setting)",
|
43
|
+
field_type='bool',
|
44
|
+
group='Payments'
|
45
|
+
),
|
46
|
+
|
47
|
+
# === 🔌 NowPayments Provider ===
|
48
|
+
ConstanceField(
|
49
|
+
name='PAYMENTS_NOWPAYMENTS_API_KEY',
|
50
|
+
default='',
|
51
|
+
help_text="🔌 NowPayments: API key for production (sensitive)",
|
52
|
+
field_type='str',
|
53
|
+
group='Payments'
|
54
|
+
),
|
55
|
+
ConstanceField(
|
56
|
+
name='PAYMENTS_NOWPAYMENTS_IPN_SECRET',
|
57
|
+
default='',
|
58
|
+
help_text="🔌 NowPayments: IPN secret for webhook verification (sensitive)",
|
59
|
+
field_type='str',
|
60
|
+
group='Payments'
|
61
|
+
),
|
62
|
+
ConstanceField(
|
63
|
+
name='PAYMENTS_NOWPAYMENTS_SANDBOX_MODE',
|
64
|
+
default=True,
|
65
|
+
help_text="🔌 NowPayments: Use sandbox mode for testing",
|
66
|
+
field_type='bool',
|
67
|
+
group='Payments'
|
68
|
+
),
|
69
|
+
]
|