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.
Files changed (246) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/__init__.py +24 -8
  3. django_cfg/apps/accounts/admin/activity_admin.py +146 -0
  4. django_cfg/apps/accounts/admin/filters.py +98 -22
  5. django_cfg/apps/accounts/admin/group_admin.py +86 -0
  6. django_cfg/apps/accounts/admin/inlines.py +42 -13
  7. django_cfg/apps/accounts/admin/otp_admin.py +115 -0
  8. django_cfg/apps/accounts/admin/registration_admin.py +173 -0
  9. django_cfg/apps/accounts/admin/resources.py +123 -19
  10. django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
  11. django_cfg/apps/accounts/admin/user_admin.py +362 -0
  12. django_cfg/apps/agents/admin/__init__.py +17 -4
  13. django_cfg/apps/agents/admin/execution_admin.py +204 -183
  14. django_cfg/apps/agents/admin/registry_admin.py +230 -255
  15. django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
  16. django_cfg/apps/agents/core/__init__.py +1 -1
  17. django_cfg/apps/agents/core/django_agent.py +221 -0
  18. django_cfg/apps/agents/core/exceptions.py +14 -0
  19. django_cfg/apps/agents/core/orchestrator.py +18 -3
  20. django_cfg/apps/knowbase/admin/__init__.py +1 -1
  21. django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
  22. django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
  23. django_cfg/apps/knowbase/admin/document_admin.py +269 -262
  24. django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
  25. django_cfg/apps/knowbase/config/settings.py +21 -4
  26. django_cfg/apps/knowbase/views/chat_views.py +3 -0
  27. django_cfg/apps/leads/admin/__init__.py +3 -1
  28. django_cfg/apps/leads/admin/leads_admin.py +235 -35
  29. django_cfg/apps/maintenance/admin/__init__.py +2 -2
  30. django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
  31. django_cfg/apps/maintenance/admin/log_admin.py +143 -61
  32. django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
  33. django_cfg/apps/maintenance/admin/site_admin.py +213 -352
  34. django_cfg/apps/newsletter/admin/__init__.py +29 -2
  35. django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
  36. django_cfg/apps/payments/admin/__init__.py +18 -27
  37. django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
  38. django_cfg/apps/payments/admin/balance_admin.py +166 -632
  39. django_cfg/apps/payments/admin/currencies_admin.py +235 -607
  40. django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
  41. django_cfg/apps/payments/admin/filters.py +83 -3
  42. django_cfg/apps/payments/admin/networks_admin.py +269 -0
  43. django_cfg/apps/payments/admin/payments_admin.py +183 -460
  44. django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
  45. django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
  46. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +153 -34
  47. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  48. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  49. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  50. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  51. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  52. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  53. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  54. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +43 -17
  55. django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
  56. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  57. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +109 -63
  58. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  59. django_cfg/apps/payments/config/__init__.py +14 -15
  60. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  61. django_cfg/apps/payments/config/helpers.py +8 -13
  62. django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
  63. django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
  64. django_cfg/apps/payments/middleware/api_access.py +32 -6
  65. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  66. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  67. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  68. django_cfg/apps/payments/models/balance.py +12 -0
  69. django_cfg/apps/payments/models/currencies.py +106 -32
  70. django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
  71. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  72. django_cfg/apps/payments/models/payments.py +94 -0
  73. django_cfg/apps/payments/services/core/base.py +4 -4
  74. django_cfg/apps/payments/services/core/currency_service.py +35 -28
  75. django_cfg/apps/payments/services/core/payment_service.py +266 -39
  76. django_cfg/apps/payments/services/providers/__init__.py +3 -0
  77. django_cfg/apps/payments/services/providers/base.py +303 -41
  78. django_cfg/apps/payments/services/providers/models/__init__.py +42 -0
  79. django_cfg/apps/payments/services/providers/models/base.py +145 -0
  80. django_cfg/apps/payments/services/providers/models/providers.py +87 -0
  81. django_cfg/apps/payments/services/providers/models/universal.py +48 -0
  82. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
  83. django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
  84. django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
  85. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
  86. django_cfg/apps/payments/services/providers/nowpayments/provider.py +557 -0
  87. django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
  88. django_cfg/apps/payments/services/providers/registry.py +9 -37
  89. django_cfg/apps/payments/services/providers/sync_service.py +277 -0
  90. django_cfg/apps/payments/services/types/requests.py +19 -7
  91. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  92. django_cfg/apps/payments/static/payments/js/api-client.js +29 -6
  93. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  94. django_cfg/apps/payments/static/payments/js/payment-form.js +98 -32
  95. django_cfg/apps/payments/tasks/__init__.py +39 -0
  96. django_cfg/apps/payments/tasks/types.py +73 -0
  97. django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
  98. django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
  99. django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
  100. django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
  101. django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
  102. django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
  103. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
  104. django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
  105. django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
  106. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  107. django_cfg/apps/payments/urls.py +3 -2
  108. django_cfg/apps/payments/urls_admin.py +1 -1
  109. django_cfg/apps/payments/views/api/currencies.py +8 -5
  110. django_cfg/apps/payments/views/overview/services.py +2 -2
  111. django_cfg/apps/payments/views/serializers/currencies.py +22 -8
  112. django_cfg/apps/support/admin/__init__.py +10 -1
  113. django_cfg/apps/support/admin/support_admin.py +338 -141
  114. django_cfg/apps/tasks/admin/__init__.py +11 -0
  115. django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
  116. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  117. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  118. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  119. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  120. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  121. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  122. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  123. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  124. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  125. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  126. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  127. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  128. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  129. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  130. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  131. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  132. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  133. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  134. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  135. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  136. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  137. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  138. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  139. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  140. django_cfg/apps/tasks/urls.py +2 -2
  141. django_cfg/apps/tasks/urls_admin.py +2 -2
  142. django_cfg/apps/tasks/utils/__init__.py +1 -0
  143. django_cfg/apps/tasks/utils/simulator.py +356 -0
  144. django_cfg/apps/tasks/views/__init__.py +16 -0
  145. django_cfg/apps/tasks/views/api.py +569 -0
  146. django_cfg/apps/tasks/views/dashboard.py +58 -0
  147. django_cfg/config.py +1 -1
  148. django_cfg/core/config.py +10 -5
  149. django_cfg/core/generation.py +1 -1
  150. django_cfg/core/integration/__init__.py +21 -0
  151. django_cfg/management/commands/__init__.py +13 -1
  152. django_cfg/management/commands/migrate_all.py +9 -3
  153. django_cfg/management/commands/migrator.py +11 -6
  154. django_cfg/management/commands/rundramatiq.py +3 -2
  155. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  156. django_cfg/middleware/__init__.py +0 -2
  157. django_cfg/models/api_keys.py +115 -0
  158. django_cfg/models/constance.py +0 -11
  159. django_cfg/models/payments.py +137 -3
  160. django_cfg/modules/django_admin/__init__.py +64 -0
  161. django_cfg/modules/django_admin/decorators/__init__.py +13 -0
  162. django_cfg/modules/django_admin/decorators/actions.py +106 -0
  163. django_cfg/modules/django_admin/decorators/display.py +106 -0
  164. django_cfg/modules/django_admin/mixins/__init__.py +14 -0
  165. django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
  166. django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
  167. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
  168. django_cfg/modules/django_admin/models/__init__.py +20 -0
  169. django_cfg/modules/django_admin/models/action_models.py +33 -0
  170. django_cfg/modules/django_admin/models/badge_models.py +20 -0
  171. django_cfg/modules/django_admin/models/base.py +26 -0
  172. django_cfg/modules/django_admin/models/display_models.py +31 -0
  173. django_cfg/modules/django_admin/utils/badges.py +159 -0
  174. django_cfg/modules/django_admin/utils/displays.py +247 -0
  175. django_cfg/modules/django_currency/__init__.py +2 -2
  176. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  177. django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
  178. django_cfg/modules/django_currency/core/converter.py +12 -12
  179. django_cfg/modules/django_currency/database/__init__.py +2 -2
  180. django_cfg/modules/django_currency/database/database_loader.py +93 -42
  181. django_cfg/modules/django_llm/llm/client.py +10 -2
  182. django_cfg/modules/django_tasks.py +54 -21
  183. django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
  184. django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
  185. django_cfg/modules/django_unfold/dashboard.py +14 -13
  186. django_cfg/modules/django_unfold/models/config.py +1 -1
  187. django_cfg/registry/core.py +7 -9
  188. django_cfg/registry/third_party.py +2 -2
  189. django_cfg/template_archive/django_sample.zip +0 -0
  190. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -1
  191. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/RECORD +198 -160
  192. django_cfg/apps/accounts/admin/activity.py +0 -96
  193. django_cfg/apps/accounts/admin/group.py +0 -17
  194. django_cfg/apps/accounts/admin/otp.py +0 -59
  195. django_cfg/apps/accounts/admin/registration_source.py +0 -97
  196. django_cfg/apps/accounts/admin/twilio_response.py +0 -227
  197. django_cfg/apps/accounts/admin/user.py +0 -300
  198. django_cfg/apps/agents/core/agent.py +0 -281
  199. django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
  200. django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
  201. django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
  202. django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
  203. django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
  204. django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
  205. django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
  206. django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
  207. django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
  208. django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
  209. django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
  210. django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
  211. django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
  212. django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
  213. django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
  214. django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
  215. django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
  216. django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
  217. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  218. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  219. django_cfg/apps/payments/config/constance/fields.py +0 -69
  220. django_cfg/apps/payments/config/constance/settings.py +0 -160
  221. django_cfg/apps/payments/services/providers/nowpayments.py +0 -478
  222. django_cfg/apps/tasks/admin.py +0 -320
  223. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  224. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  225. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  226. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  227. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  228. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  229. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  230. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  231. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  232. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  233. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  234. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  235. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  236. django_cfg/apps/tasks/views.py +0 -461
  237. django_cfg/management/commands/auto_generate.py +0 -486
  238. django_cfg/middleware/static_nocache.py +0 -55
  239. django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
  240. /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
  241. /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
  242. /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
  243. /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
  244. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
  245. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
  246. {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
- # Mock webhook provider data - replace with real configuration
47
- providers_data = [
48
- {
49
- 'name': 'nowpayments',
50
- 'display_name': 'NowPayments',
51
- 'enabled': True,
52
- 'webhook_url': 'https://api.nowpayments.io/v1/webhooks',
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': timezone.now() - timedelta(minutes=5),
55
- 'status': 'active'
56
- },
57
- {
58
- 'name': 'stripe',
59
- 'display_name': 'Stripe',
60
- 'enabled': False,
61
- 'webhook_url': 'https://api.stripe.com/v1/webhooks',
62
- 'supported_events': ['payment_intent.succeeded', 'payment_intent.payment_failed'],
63
- 'last_ping': None,
64
- 'status': 'inactive'
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(providers_data, many=True)
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
- 'total_events': total_payments * 2, # Assume 2 events per payment on average
83
- 'successful_events': int(total_payments * 1.8), # 90% success rate
84
- 'failed_events': int(total_payments * 0.2), # 10% failure rate
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
- 'events_by_type': {
102
- 'payment.created': int(total_payments * 1.0),
103
- 'payment.completed': int(total_payments * 0.8),
104
- 'payment.failed': int(total_payments * 0.2),
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
- 'recent_activity': [
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 = ['created_at', 'event_type', 'status']
135
- ordering = ['-created_at']
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.query_params.get('event_type')
147
- status_filter = request.query_params.get('status')
148
- provider = request.query_params.get('provider')
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"evt_{payment.id}_{event_type_name.split('.')[1]}",
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
- 'provider': 'nowpayments' if i % 2 == 0 else 'stripe',
166
- 'created_at': payment.created_at,
167
- 'response_code': 200 if i % 5 != 0 else 500,
168
- 'response_time': f"{50 + (i % 200)}ms",
169
- 'attempts': 1 if i % 5 != 0 else 3,
170
- 'payload': {
171
- 'payment_id': str(payment.id),
172
- 'amount': str(payment.amount),
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 created_at descending
190
- events.sort(key=lambda x: x['created_at'], reverse=True)
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.query_params.get('page', 1))
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 clean separation between:
5
- - django-cfg integration (static config)
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
- # Constance integration (safe - no Django models)
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
- # Constance integration
36
- 'get_django_cfg_payments_constance_fields',
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
- 'api_prefixes': config.api_prefixes,
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 combining django-cfg and Constance."""
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
- # Static settings from django-cfg
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
- # Dynamic settings from Constance (if available)
45
- 'constance_settings': constance_settings,
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