django-cfg 1.3.7__py3-none-any.whl → 1.3.11__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/accounts/admin/__init__.py +24 -8
- django_cfg/apps/accounts/admin/activity_admin.py +146 -0
- django_cfg/apps/accounts/admin/filters.py +98 -22
- django_cfg/apps/accounts/admin/group_admin.py +86 -0
- django_cfg/apps/accounts/admin/inlines.py +42 -13
- django_cfg/apps/accounts/admin/otp_admin.py +115 -0
- django_cfg/apps/accounts/admin/registration_admin.py +173 -0
- django_cfg/apps/accounts/admin/resources.py +123 -19
- django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
- django_cfg/apps/accounts/admin/user_admin.py +362 -0
- django_cfg/apps/agents/admin/__init__.py +17 -4
- django_cfg/apps/agents/admin/execution_admin.py +204 -183
- django_cfg/apps/agents/admin/registry_admin.py +230 -255
- django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
- django_cfg/apps/agents/core/__init__.py +1 -1
- django_cfg/apps/agents/core/django_agent.py +221 -0
- django_cfg/apps/agents/core/exceptions.py +14 -0
- django_cfg/apps/agents/core/orchestrator.py +18 -3
- django_cfg/apps/knowbase/admin/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
- django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
- django_cfg/apps/knowbase/admin/document_admin.py +269 -262
- django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
- django_cfg/apps/knowbase/config/settings.py +21 -4
- django_cfg/apps/knowbase/views/chat_views.py +3 -0
- django_cfg/apps/leads/admin/__init__.py +3 -1
- django_cfg/apps/leads/admin/leads_admin.py +235 -35
- django_cfg/apps/maintenance/admin/__init__.py +2 -2
- django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
- django_cfg/apps/maintenance/admin/log_admin.py +143 -61
- django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
- django_cfg/apps/maintenance/admin/site_admin.py +213 -352
- django_cfg/apps/newsletter/admin/__init__.py +29 -2
- django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
- django_cfg/apps/payments/admin/__init__.py +18 -27
- django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
- django_cfg/apps/payments/admin/balance_admin.py +166 -632
- django_cfg/apps/payments/admin/currencies_admin.py +235 -607
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
- django_cfg/apps/payments/admin/filters.py +83 -3
- django_cfg/apps/payments/admin/networks_admin.py +269 -0
- django_cfg/apps/payments/admin/payments_admin.py +183 -460
- django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
- django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +153 -34
- django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +43 -17
- django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
- django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +109 -63
- django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
- django_cfg/apps/payments/config/__init__.py +14 -15
- django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
- django_cfg/apps/payments/config/helpers.py +8 -13
- django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
- django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
- django_cfg/apps/payments/middleware/api_access.py +32 -6
- django_cfg/apps/payments/migrations/0001_initial.py +33 -46
- django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
- django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
- django_cfg/apps/payments/models/balance.py +12 -0
- django_cfg/apps/payments/models/currencies.py +106 -32
- django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
- django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
- django_cfg/apps/payments/models/payments.py +94 -0
- django_cfg/apps/payments/services/core/base.py +4 -4
- django_cfg/apps/payments/services/core/currency_service.py +35 -28
- django_cfg/apps/payments/services/core/payment_service.py +266 -39
- django_cfg/apps/payments/services/providers/__init__.py +3 -0
- django_cfg/apps/payments/services/providers/base.py +303 -41
- django_cfg/apps/payments/services/providers/models/__init__.py +42 -0
- django_cfg/apps/payments/services/providers/models/base.py +145 -0
- django_cfg/apps/payments/services/providers/models/providers.py +87 -0
- django_cfg/apps/payments/services/providers/models/universal.py +48 -0
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
- django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
- django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +557 -0
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
- django_cfg/apps/payments/services/providers/registry.py +9 -37
- django_cfg/apps/payments/services/providers/sync_service.py +277 -0
- django_cfg/apps/payments/services/types/requests.py +19 -7
- django_cfg/apps/payments/signals/payment_signals.py +31 -2
- django_cfg/apps/payments/static/payments/js/api-client.js +29 -6
- django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
- django_cfg/apps/payments/static/payments/js/payment-form.js +98 -32
- django_cfg/apps/payments/tasks/__init__.py +39 -0
- django_cfg/apps/payments/tasks/types.py +73 -0
- django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
- django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
- django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
- django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
- django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
- django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
- django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
- django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
- django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
- django_cfg/apps/payments/urls.py +3 -2
- django_cfg/apps/payments/urls_admin.py +1 -1
- django_cfg/apps/payments/views/api/currencies.py +8 -5
- django_cfg/apps/payments/views/overview/services.py +2 -2
- django_cfg/apps/payments/views/serializers/currencies.py +22 -8
- django_cfg/apps/support/admin/__init__.py +10 -1
- django_cfg/apps/support/admin/support_admin.py +338 -141
- django_cfg/apps/tasks/admin/__init__.py +11 -0
- django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
- django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
- django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
- django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
- django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
- django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
- django_cfg/apps/tasks/tasks/__init__.py +10 -0
- django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
- django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
- django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
- django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
- django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
- django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
- django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
- django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
- django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
- django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
- django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
- django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
- django_cfg/apps/tasks/urls.py +2 -2
- django_cfg/apps/tasks/urls_admin.py +2 -2
- django_cfg/apps/tasks/utils/__init__.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +356 -0
- django_cfg/apps/tasks/views/__init__.py +16 -0
- django_cfg/apps/tasks/views/api.py +569 -0
- django_cfg/apps/tasks/views/dashboard.py +58 -0
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +10 -5
- django_cfg/core/generation.py +1 -1
- django_cfg/core/integration/__init__.py +21 -0
- django_cfg/management/commands/__init__.py +13 -1
- django_cfg/management/commands/migrate_all.py +9 -3
- django_cfg/management/commands/migrator.py +11 -6
- django_cfg/management/commands/rundramatiq.py +3 -2
- django_cfg/management/commands/rundramatiq_simulator.py +430 -0
- django_cfg/middleware/__init__.py +0 -2
- django_cfg/models/api_keys.py +115 -0
- django_cfg/models/constance.py +0 -11
- django_cfg/models/payments.py +137 -3
- django_cfg/modules/django_admin/__init__.py +64 -0
- django_cfg/modules/django_admin/decorators/__init__.py +13 -0
- django_cfg/modules/django_admin/decorators/actions.py +106 -0
- django_cfg/modules/django_admin/decorators/display.py +106 -0
- django_cfg/modules/django_admin/mixins/__init__.py +14 -0
- django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
- django_cfg/modules/django_admin/models/__init__.py +20 -0
- django_cfg/modules/django_admin/models/action_models.py +33 -0
- django_cfg/modules/django_admin/models/badge_models.py +20 -0
- django_cfg/modules/django_admin/models/base.py +26 -0
- django_cfg/modules/django_admin/models/display_models.py +31 -0
- django_cfg/modules/django_admin/utils/badges.py +159 -0
- django_cfg/modules/django_admin/utils/displays.py +247 -0
- django_cfg/modules/django_currency/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
- django_cfg/modules/django_currency/core/converter.py +12 -12
- django_cfg/modules/django_currency/database/__init__.py +2 -2
- django_cfg/modules/django_currency/database/database_loader.py +93 -42
- django_cfg/modules/django_llm/llm/client.py +10 -2
- django_cfg/modules/django_tasks.py +54 -21
- django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
- django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
- django_cfg/modules/django_unfold/dashboard.py +14 -13
- django_cfg/modules/django_unfold/models/config.py +1 -1
- django_cfg/registry/core.py +7 -9
- django_cfg/registry/third_party.py +2 -2
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -1
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/RECORD +198 -160
- django_cfg/apps/accounts/admin/activity.py +0 -96
- django_cfg/apps/accounts/admin/group.py +0 -17
- django_cfg/apps/accounts/admin/otp.py +0 -59
- django_cfg/apps/accounts/admin/registration_source.py +0 -97
- django_cfg/apps/accounts/admin/twilio_response.py +0 -227
- django_cfg/apps/accounts/admin/user.py +0 -300
- django_cfg/apps/agents/core/agent.py +0 -281
- django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
- django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
- django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
- django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
- django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
- django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
- django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
- django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
- django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
- django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
- django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
- django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
- django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
- django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
- django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
- django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
- django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
- django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
- django_cfg/apps/payments/config/constance/__init__.py +0 -22
- django_cfg/apps/payments/config/constance/config_service.py +0 -123
- django_cfg/apps/payments/config/constance/fields.py +0 -69
- django_cfg/apps/payments/config/constance/settings.py +0 -160
- django_cfg/apps/payments/services/providers/nowpayments.py +0 -478
- django_cfg/apps/tasks/admin.py +0 -320
- django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
- django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
- django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
- django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
- django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
- django_cfg/apps/tasks/templates/tasks/base.html +0 -96
- django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
- django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
- django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
- django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
- django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
- django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
- django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
- django_cfg/apps/tasks/views.py +0 -461
- django_cfg/management/commands/auto_generate.py +0 -486
- django_cfg/middleware/static_nocache.py +0 -55
- django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
- /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/licenses/LICENSE +0 -0
@@ -23,9 +23,14 @@ from django_cfg.apps.payments.admin_interface.serializers import (
|
|
23
23
|
WebhookActionSerializer,
|
24
24
|
WebhookActionResultSerializer,
|
25
25
|
)
|
26
|
-
from django_cfg.apps.payments.services.core.webhook_service import WebhookService
|
27
26
|
from django_cfg.apps.payments.models import UniversalPayment
|
28
27
|
from django_cfg.modules.django_logger import get_logger
|
28
|
+
from django_cfg.apps.payments.services.integrations.ngrok_service import (
|
29
|
+
get_all_webhook_urls,
|
30
|
+
get_api_base_url,
|
31
|
+
is_ngrok_available
|
32
|
+
)
|
33
|
+
from django_cfg.apps.payments.services.core.webhook_service import WebhookService
|
29
34
|
|
30
35
|
logger = get_logger("admin_webhook_api")
|
31
36
|
|
@@ -41,31 +46,57 @@ class AdminWebhookViewSet(AdminReadOnlyViewSet):
|
|
41
46
|
# No model - this is for webhook configuration data
|
42
47
|
serializer_class = WebhookStatsSerializer
|
43
48
|
|
49
|
+
def __init__(self, **kwargs):
|
50
|
+
"""Initialize with ngrok service."""
|
51
|
+
super().__init__(**kwargs)
|
52
|
+
|
53
|
+
self.get_webhook_urls = get_all_webhook_urls
|
54
|
+
self.get_base_url = get_api_base_url
|
55
|
+
self.is_ngrok_active = is_ngrok_available
|
56
|
+
|
44
57
|
def list(self, request):
|
45
|
-
"""List webhook providers and configurations."""
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
58
|
+
"""List webhook providers and configurations with real ngrok URLs."""
|
59
|
+
# Get real webhook URLs
|
60
|
+
webhook_urls = self.get_webhook_urls()
|
61
|
+
base_url = self.get_base_url()
|
62
|
+
ngrok_active = self.is_ngrok_active()
|
63
|
+
|
64
|
+
# Get real provider data based on actual payments
|
65
|
+
active_providers = UniversalPayment.objects.values('provider').distinct()
|
66
|
+
|
67
|
+
providers_data = []
|
68
|
+
for provider_data in active_providers:
|
69
|
+
provider_name = provider_data['provider']
|
70
|
+
provider_payments = UniversalPayment.objects.filter(provider=provider_name)
|
71
|
+
|
72
|
+
# Calculate real statistics
|
73
|
+
total_payments = provider_payments.count()
|
74
|
+
last_payment = provider_payments.order_by('-created_at').first()
|
75
|
+
|
76
|
+
provider_info = {
|
77
|
+
'name': provider_name,
|
78
|
+
'display_name': provider_name.title(),
|
79
|
+
'enabled': total_payments > 0,
|
80
|
+
'webhook_url': webhook_urls.get(provider_name, f"{base_url}/api/webhooks/{provider_name}/"),
|
53
81
|
'supported_events': ['payment.created', 'payment.completed', 'payment.failed'],
|
54
|
-
'last_ping':
|
55
|
-
'status': 'active'
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
82
|
+
'last_ping': last_payment.created_at if last_payment else None,
|
83
|
+
'status': 'active' if total_payments > 0 else 'inactive',
|
84
|
+
'ngrok_active': ngrok_active,
|
85
|
+
'base_url': base_url
|
86
|
+
}
|
87
|
+
providers_data.append(provider_info)
|
88
|
+
|
89
|
+
# Add ngrok status to response
|
90
|
+
response_data = {
|
91
|
+
'providers': providers_data,
|
92
|
+
'ngrok_status': {
|
93
|
+
'active': ngrok_active,
|
94
|
+
'base_url': base_url,
|
95
|
+
'webhook_urls': webhook_urls
|
65
96
|
}
|
66
|
-
|
97
|
+
}
|
67
98
|
|
68
|
-
serializer = self.get_serializer(
|
99
|
+
serializer = self.get_serializer(response_data)
|
69
100
|
return Response(serializer.data)
|
70
101
|
|
71
102
|
@action(detail=False, methods=['get'])
|
@@ -79,39 +110,34 @@ class AdminWebhookViewSet(AdminReadOnlyViewSet):
|
|
79
110
|
|
80
111
|
# Mock webhook stats based on real payment data
|
81
112
|
stats_data = {
|
82
|
-
'
|
83
|
-
'
|
84
|
-
'
|
113
|
+
'total': total_payments * 2, # Assume 2 events per payment on average
|
114
|
+
'successful': int(total_payments * 1.8), # 90% success rate
|
115
|
+
'failed': int(total_payments * 0.2), # 10% failure rate
|
116
|
+
'pending': 0, # No pending events for now
|
85
117
|
'success_rate': 90.0,
|
86
|
-
'recent_events': recent_payments * 2,
|
87
118
|
'providers': {
|
88
119
|
'nowpayments': {
|
89
120
|
'total': int(total_payments * 0.7),
|
90
121
|
'successful': int(total_payments * 0.65),
|
91
122
|
'failed': int(total_payments * 0.05),
|
123
|
+
'pending': 0,
|
92
124
|
'success_rate': 92.8
|
93
125
|
},
|
94
126
|
'stripe': {
|
95
127
|
'total': int(total_payments * 0.3),
|
96
128
|
'successful': int(total_payments * 0.28),
|
97
129
|
'failed': int(total_payments * 0.02),
|
130
|
+
'pending': 0,
|
98
131
|
'success_rate': 93.3
|
99
132
|
}
|
100
133
|
},
|
101
|
-
'
|
102
|
-
'
|
103
|
-
'
|
104
|
-
'
|
134
|
+
'last_24h': {
|
135
|
+
'total': recent_payments * 2,
|
136
|
+
'successful': int(recent_payments * 1.8),
|
137
|
+
'failed': int(recent_payments * 0.2),
|
105
138
|
},
|
106
|
-
'
|
107
|
-
|
108
|
-
'timestamp': timezone.now() - timedelta(minutes=i*5),
|
109
|
-
'event_type': 'payment.created' if i % 3 == 0 else 'payment.completed',
|
110
|
-
'provider': 'nowpayments' if i % 2 == 0 else 'stripe',
|
111
|
-
'status': 'success' if i % 4 != 0 else 'failed'
|
112
|
-
}
|
113
|
-
for i in range(10)
|
114
|
-
]
|
139
|
+
'avg_response_time': 150.5, # milliseconds
|
140
|
+
'max_response_time': 2500, # milliseconds
|
115
141
|
}
|
116
142
|
|
117
143
|
serializer = self.get_serializer(stats_data)
|
@@ -131,8 +157,17 @@ class AdminWebhookEventViewSet(AdminReadOnlyViewSet):
|
|
131
157
|
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
132
158
|
filterset_fields = ['event_type', 'status', 'provider']
|
133
159
|
search_fields = ['event_type', 'webhook_url']
|
134
|
-
ordering_fields = ['
|
135
|
-
ordering = ['-
|
160
|
+
ordering_fields = ['timestamp', 'event_type', 'status']
|
161
|
+
ordering = ['-timestamp']
|
162
|
+
|
163
|
+
def __init__(self, **kwargs):
|
164
|
+
"""Initialize with webhook and ngrok services."""
|
165
|
+
super().__init__(**kwargs)
|
166
|
+
|
167
|
+
self.webhook_service = WebhookService()
|
168
|
+
self.get_webhook_urls = get_all_webhook_urls
|
169
|
+
self.get_base_url = get_api_base_url
|
170
|
+
self.is_ngrok_active = is_ngrok_available
|
136
171
|
|
137
172
|
def get_queryset(self):
|
138
173
|
"""Get webhook events queryset."""
|
@@ -140,12 +175,12 @@ class AdminWebhookEventViewSet(AdminReadOnlyViewSet):
|
|
140
175
|
# In real implementation, this would return WebhookEvent.objects.all()
|
141
176
|
return UniversalPayment.objects.none()
|
142
177
|
|
143
|
-
def list(self, request):
|
178
|
+
def list(self, request, webhook_pk=None):
|
144
179
|
"""List webhook events with filtering and pagination."""
|
145
180
|
# Get filter parameters
|
146
|
-
event_type = request.
|
147
|
-
status_filter = request.
|
148
|
-
provider = request.
|
181
|
+
event_type = request.GET.get('event_type')
|
182
|
+
status_filter = request.GET.get('status')
|
183
|
+
provider = request.GET.get('provider')
|
149
184
|
|
150
185
|
# Get real payment data to generate realistic mock events
|
151
186
|
payments = UniversalPayment.objects.all()[:50] # Limit for performance
|
@@ -157,23 +192,28 @@ class AdminWebhookEventViewSet(AdminReadOnlyViewSet):
|
|
157
192
|
event_types = ['payment.created', 'payment.completed'] if payment.status == 'completed' else ['payment.created']
|
158
193
|
|
159
194
|
for event_type_name in event_types:
|
195
|
+
# Create payload for the event
|
196
|
+
payload = {
|
197
|
+
'payment_id': str(payment.id),
|
198
|
+
'amount': str(payment.amount_usd),
|
199
|
+
'currency': payment.currency.code if payment.currency else payment.currency_code,
|
200
|
+
'status': payment.status,
|
201
|
+
'timestamp': payment.created_at.isoformat()
|
202
|
+
}
|
203
|
+
|
160
204
|
event = {
|
161
|
-
'id': f"
|
205
|
+
'id': int(str(hash(f"{payment.id}_{event_type_name}_{i}"))[:8], 16),
|
206
|
+
'provider': payment.provider,
|
162
207
|
'event_type': event_type_name,
|
163
|
-
'webhook_url': f'https://example.com/webhook/{payment.id}',
|
164
208
|
'status': 'success' if i % 5 != 0 else 'failed',
|
165
|
-
'
|
166
|
-
'
|
167
|
-
'
|
168
|
-
'
|
169
|
-
'
|
170
|
-
'
|
171
|
-
|
172
|
-
|
173
|
-
'currency': payment.currency,
|
174
|
-
'status': payment.status,
|
175
|
-
'timestamp': payment.created_at.isoformat()
|
176
|
-
}
|
209
|
+
'timestamp': payment.created_at,
|
210
|
+
'payload_size': len(str(payload)),
|
211
|
+
'response_time': 50 + (i % 200),
|
212
|
+
'retry_count': 0 if i % 5 != 0 else 2,
|
213
|
+
'error_message': '' if i % 5 != 0 else 'Connection timeout',
|
214
|
+
'payload_preview': str(payload)[:200],
|
215
|
+
'response_status_code': 200 if i % 5 != 0 else 500,
|
216
|
+
'webhook_url': self.get_webhook_urls().get(payment.provider, f"{self.get_base_url()}/api/webhooks/{payment.provider}/"),
|
177
217
|
}
|
178
218
|
|
179
219
|
# Apply filters
|
@@ -186,12 +226,13 @@ class AdminWebhookEventViewSet(AdminReadOnlyViewSet):
|
|
186
226
|
|
187
227
|
events.append(event)
|
188
228
|
|
189
|
-
# Sort by
|
190
|
-
events
|
229
|
+
# Sort by timestamp descending (only if events exist)
|
230
|
+
if events:
|
231
|
+
events.sort(key=lambda x: x.get('timestamp', timezone.now()), reverse=True)
|
191
232
|
|
192
233
|
# Pagination
|
193
234
|
page_size = 20
|
194
|
-
page = int(request.
|
235
|
+
page = int(request.GET.get('page', 1))
|
195
236
|
start = (page - 1) * page_size
|
196
237
|
end = start + page_size
|
197
238
|
paginated_events = events[start:end]
|
@@ -202,7 +243,12 @@ class AdminWebhookEventViewSet(AdminReadOnlyViewSet):
|
|
202
243
|
'page': page,
|
203
244
|
'per_page': page_size,
|
204
245
|
'has_next': end < len(events),
|
205
|
-
'has_previous': page > 1
|
246
|
+
'has_previous': page > 1,
|
247
|
+
'ngrok_status': {
|
248
|
+
'active': self.is_ngrok_active(),
|
249
|
+
'base_url': self.get_base_url(),
|
250
|
+
'webhook_urls': self.get_webhook_urls()
|
251
|
+
}
|
206
252
|
}
|
207
253
|
|
208
254
|
serializer = self.get_serializer(response_data)
|
@@ -51,7 +51,7 @@ class PaymentDetailView(AdminTemplateViewMixin, LoginRequiredMixin, DetailView):
|
|
51
51
|
|
52
52
|
def get_queryset(self):
|
53
53
|
"""Optimized queryset with related objects."""
|
54
|
-
return UniversalPayment.objects.select_related('user')
|
54
|
+
return UniversalPayment.objects.select_related('user', 'currency', 'network')
|
55
55
|
|
56
56
|
def get_context_data(self, **kwargs):
|
57
57
|
"""Add detail context data."""
|
@@ -59,7 +59,11 @@ class PaymentDetailView(AdminTemplateViewMixin, LoginRequiredMixin, DetailView):
|
|
59
59
|
|
60
60
|
payment = self.get_object()
|
61
61
|
|
62
|
+
# Force refresh from database to get latest data
|
63
|
+
payment.refresh_from_db()
|
64
|
+
|
62
65
|
context.update({
|
66
|
+
'payment': payment,
|
63
67
|
'page_title': f'Payment {payment.internal_payment_id or payment.id}',
|
64
68
|
'page_subtitle': f'Payment details and transaction history',
|
65
69
|
'show_actions': True,
|
@@ -1,42 +1,41 @@
|
|
1
1
|
"""
|
2
2
|
Configuration module for the Universal Payment System v2.0.
|
3
3
|
|
4
|
-
Provides
|
5
|
-
- django-cfg integration (
|
6
|
-
- Constance integration (dynamic config)
|
4
|
+
Provides unified configuration through BaseCfgAutoModule:
|
5
|
+
- django-cfg integration (all configuration)
|
7
6
|
- Configuration utilities and helpers
|
8
7
|
"""
|
9
8
|
|
10
|
-
# Django-cfg integration
|
9
|
+
# Django-cfg integration (BaseCfgAutoModule)
|
11
10
|
from .django_cfg_integration import (
|
11
|
+
PaymentsConfigManager,
|
12
12
|
PaymentsConfigMixin,
|
13
13
|
get_payments_config,
|
14
14
|
is_payments_enabled,
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
from .constance import (
|
19
|
-
get_django_cfg_payments_constance_fields,
|
20
|
-
PaymentConstanceSettings,
|
15
|
+
is_payments_configured,
|
16
|
+
get_config_summary,
|
17
|
+
reset_payments_config_cache,
|
21
18
|
)
|
22
19
|
|
23
20
|
# Configuration helpers
|
24
21
|
from .helpers import (
|
25
22
|
MiddlewareConfigHelper,
|
26
23
|
CacheConfigHelper,
|
24
|
+
RedisConfigHelper,
|
27
25
|
)
|
28
26
|
|
29
27
|
__all__ = [
|
30
|
-
# Django-cfg integration
|
28
|
+
# Django-cfg integration (BaseCfgAutoModule)
|
29
|
+
'PaymentsConfigManager',
|
31
30
|
'PaymentsConfigMixin',
|
32
31
|
'get_payments_config',
|
33
32
|
'is_payments_enabled',
|
34
|
-
|
35
|
-
|
36
|
-
'
|
37
|
-
'PaymentConstanceSettings',
|
33
|
+
'is_payments_configured',
|
34
|
+
'get_config_summary',
|
35
|
+
'reset_payments_config_cache',
|
38
36
|
|
39
37
|
# Configuration helpers
|
40
38
|
'MiddlewareConfigHelper',
|
41
39
|
'CacheConfigHelper',
|
40
|
+
'RedisConfigHelper',
|
42
41
|
]
|
@@ -136,7 +136,7 @@ class PaymentsConfigManager:
|
|
136
136
|
'rate_limiting_enabled': config.rate_limiting_enabled,
|
137
137
|
'usage_tracking_enabled': config.usage_tracking_enabled,
|
138
138
|
'cache_timeouts': config.cache_timeouts,
|
139
|
-
'
|
139
|
+
'enabled_providers': config.get_enabled_providers(),
|
140
140
|
}
|
141
141
|
except Exception as e:
|
142
142
|
return {
|
@@ -144,6 +144,64 @@ class PaymentsConfigManager:
|
|
144
144
|
'error': str(e),
|
145
145
|
'enabled': False,
|
146
146
|
}
|
147
|
+
|
148
|
+
@classmethod
|
149
|
+
def get_provider_api_config(cls, provider: str) -> dict:
|
150
|
+
"""
|
151
|
+
Get provider-specific API configuration from BaseCfgAutoModule.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
provider: Provider name (e.g., 'nowpayments')
|
155
|
+
|
156
|
+
Returns:
|
157
|
+
Dictionary with provider API configuration
|
158
|
+
"""
|
159
|
+
try:
|
160
|
+
config = cls.get_payments_config()
|
161
|
+
return config.get_provider_api_config(provider)
|
162
|
+
except Exception as e:
|
163
|
+
logger.error(f"Failed to get provider config for {provider}: {e}")
|
164
|
+
return {'enabled': False}
|
165
|
+
|
166
|
+
@classmethod
|
167
|
+
def get_all_provider_configs(cls) -> dict:
|
168
|
+
"""
|
169
|
+
Get all provider configurations for registry initialization.
|
170
|
+
|
171
|
+
Returns:
|
172
|
+
Dictionary with all provider configurations
|
173
|
+
"""
|
174
|
+
try:
|
175
|
+
config = cls.get_payments_config()
|
176
|
+
providers = {}
|
177
|
+
|
178
|
+
# Get all enabled providers
|
179
|
+
for provider_name in config.get_enabled_providers():
|
180
|
+
provider_config = config.get_provider_api_config(provider_name)
|
181
|
+
if provider_config.get('enabled', False):
|
182
|
+
providers[provider_name] = provider_config
|
183
|
+
|
184
|
+
return providers
|
185
|
+
except Exception as e:
|
186
|
+
logger.error(f"Failed to get all provider configs: {e}")
|
187
|
+
return {}
|
188
|
+
|
189
|
+
@classmethod
|
190
|
+
def is_provider_enabled(cls, provider: str) -> bool:
|
191
|
+
"""
|
192
|
+
Check if a specific provider is enabled.
|
193
|
+
|
194
|
+
Args:
|
195
|
+
provider: Provider name
|
196
|
+
|
197
|
+
Returns:
|
198
|
+
True if provider is enabled
|
199
|
+
"""
|
200
|
+
try:
|
201
|
+
config = cls.get_payments_config()
|
202
|
+
return config.is_provider_enabled(provider)
|
203
|
+
except Exception:
|
204
|
+
return False
|
147
205
|
|
148
206
|
|
149
207
|
# Legacy compatibility - keep old interface
|
@@ -18,20 +18,11 @@ class MiddlewareConfigHelper(PaymentsConfigMixin):
|
|
18
18
|
|
19
19
|
@classmethod
|
20
20
|
def get_middleware_config(cls) -> Dict[str, Any]:
|
21
|
-
"""Get middleware configuration
|
21
|
+
"""Get middleware configuration from BaseCfgAutoModule."""
|
22
22
|
config = cls.get_payments_config()
|
23
23
|
|
24
|
-
# Get Constance settings for dynamic config
|
25
|
-
try:
|
26
|
-
from .constance import get_payment_config_service
|
27
|
-
config_service = get_payment_config_service()
|
28
|
-
constance_settings = config_service.get_constance_settings()
|
29
|
-
except Exception as e:
|
30
|
-
logger.warning(f"Failed to load Constance settings: {e}")
|
31
|
-
constance_settings = None
|
32
|
-
|
33
24
|
return {
|
34
|
-
#
|
25
|
+
# All settings from BaseCfgAutoModule (django-cfg)
|
35
26
|
'enabled': config.enabled and config.middleware_enabled,
|
36
27
|
'protected_paths': config.protected_paths,
|
37
28
|
'protected_patterns': config.protected_patterns,
|
@@ -41,8 +32,12 @@ class MiddlewareConfigHelper(PaymentsConfigMixin):
|
|
41
32
|
'track_anonymous_usage': config.track_anonymous_usage,
|
42
33
|
'cache_timeouts': config.cache_timeouts,
|
43
34
|
|
44
|
-
#
|
45
|
-
'
|
35
|
+
# Provider API configurations
|
36
|
+
'enabled_providers': config.get_enabled_providers(),
|
37
|
+
'provider_configs': {
|
38
|
+
provider: config.get_provider_api_config(provider)
|
39
|
+
for provider in config.get_enabled_providers()
|
40
|
+
},
|
46
41
|
}
|
47
42
|
|
48
43
|
|