django-cfg 1.2.29__py3-none-any.whl → 1.2.31__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 (126) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/payments/admin/__init__.py +3 -2
  3. django_cfg/apps/payments/admin/balance_admin.py +18 -18
  4. django_cfg/apps/payments/admin/currencies_admin.py +319 -131
  5. django_cfg/apps/payments/admin/payments_admin.py +15 -4
  6. django_cfg/apps/payments/config/module.py +2 -2
  7. django_cfg/apps/payments/config/utils.py +2 -2
  8. django_cfg/apps/payments/decorators.py +2 -2
  9. django_cfg/apps/payments/management/commands/README.md +95 -127
  10. django_cfg/apps/payments/management/commands/currency_stats.py +5 -24
  11. django_cfg/apps/payments/management/commands/manage_currencies.py +229 -0
  12. django_cfg/apps/payments/management/commands/manage_providers.py +235 -0
  13. django_cfg/apps/payments/managers/__init__.py +3 -2
  14. django_cfg/apps/payments/managers/balance_manager.py +2 -2
  15. django_cfg/apps/payments/managers/currency_manager.py +272 -49
  16. django_cfg/apps/payments/managers/payment_manager.py +161 -13
  17. django_cfg/apps/payments/middleware/api_access.py +2 -2
  18. django_cfg/apps/payments/middleware/rate_limiting.py +8 -18
  19. django_cfg/apps/payments/middleware/usage_tracking.py +20 -17
  20. django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +241 -0
  21. django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +30 -0
  22. django_cfg/apps/payments/models/__init__.py +3 -2
  23. django_cfg/apps/payments/models/currencies.py +187 -71
  24. django_cfg/apps/payments/models/payments.py +3 -2
  25. django_cfg/apps/payments/serializers/__init__.py +3 -2
  26. django_cfg/apps/payments/serializers/currencies.py +20 -12
  27. django_cfg/apps/payments/services/cache/simple_cache.py +2 -2
  28. django_cfg/apps/payments/services/core/balance_service.py +2 -2
  29. django_cfg/apps/payments/services/core/fallback_service.py +2 -2
  30. django_cfg/apps/payments/services/core/payment_service.py +3 -6
  31. django_cfg/apps/payments/services/core/subscription_service.py +4 -7
  32. django_cfg/apps/payments/services/internal_types.py +171 -7
  33. django_cfg/apps/payments/services/monitoring/api_schemas.py +58 -204
  34. django_cfg/apps/payments/services/monitoring/provider_health.py +2 -2
  35. django_cfg/apps/payments/services/providers/base.py +144 -43
  36. django_cfg/apps/payments/services/providers/cryptapi/__init__.py +4 -0
  37. django_cfg/apps/payments/services/providers/cryptapi/config.py +8 -0
  38. django_cfg/apps/payments/services/providers/cryptapi/models.py +192 -0
  39. django_cfg/apps/payments/services/providers/cryptapi/provider.py +439 -0
  40. django_cfg/apps/payments/services/providers/cryptomus/__init__.py +4 -0
  41. django_cfg/apps/payments/services/providers/cryptomus/models.py +176 -0
  42. django_cfg/apps/payments/services/providers/cryptomus/provider.py +429 -0
  43. django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +564 -0
  44. django_cfg/apps/payments/services/providers/models/__init__.py +34 -0
  45. django_cfg/apps/payments/services/providers/models/currencies.py +190 -0
  46. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -0
  47. django_cfg/apps/payments/services/providers/nowpayments/models.py +196 -0
  48. django_cfg/apps/payments/services/providers/nowpayments/provider.py +380 -0
  49. django_cfg/apps/payments/services/providers/registry.py +294 -11
  50. django_cfg/apps/payments/services/providers/stripe/__init__.py +4 -0
  51. django_cfg/apps/payments/services/providers/stripe/models.py +184 -0
  52. django_cfg/apps/payments/services/providers/stripe/provider.py +109 -0
  53. django_cfg/apps/payments/services/security/error_handler.py +6 -8
  54. django_cfg/apps/payments/services/security/payment_notifications.py +2 -2
  55. django_cfg/apps/payments/services/security/webhook_validator.py +3 -4
  56. django_cfg/apps/payments/signals/api_key_signals.py +2 -2
  57. django_cfg/apps/payments/signals/payment_signals.py +11 -5
  58. django_cfg/apps/payments/signals/subscription_signals.py +2 -2
  59. django_cfg/apps/payments/tasks/webhook_processing.py +2 -2
  60. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +50 -0
  61. django_cfg/apps/payments/templates/payments/base.html +4 -4
  62. django_cfg/apps/payments/templates/payments/components/payment_card.html +6 -6
  63. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +4 -4
  64. django_cfg/apps/payments/templates/payments/components/progress_bar.html +14 -7
  65. django_cfg/apps/payments/templates/payments/components/provider_stats.html +2 -2
  66. django_cfg/apps/payments/templates/payments/components/status_badge.html +8 -1
  67. django_cfg/apps/payments/templates/payments/components/status_overview.html +34 -30
  68. django_cfg/apps/payments/templates/payments/dashboard.html +202 -290
  69. django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +35 -0
  70. django_cfg/apps/payments/templates/payments/payment_create.html +579 -0
  71. django_cfg/apps/payments/templates/payments/payment_detail.html +373 -0
  72. django_cfg/apps/payments/templates/payments/payment_list.html +354 -0
  73. django_cfg/apps/payments/templates/payments/stats.html +261 -0
  74. django_cfg/apps/payments/templates/payments/test.html +213 -0
  75. django_cfg/apps/payments/urls.py +3 -1
  76. django_cfg/apps/payments/{urls_templates.py → urls_admin.py} +6 -0
  77. django_cfg/apps/payments/utils/__init__.py +1 -3
  78. django_cfg/apps/payments/utils/billing_utils.py +2 -2
  79. django_cfg/apps/payments/utils/config_utils.py +2 -8
  80. django_cfg/apps/payments/utils/validation_utils.py +2 -2
  81. django_cfg/apps/payments/views/__init__.py +3 -2
  82. django_cfg/apps/payments/views/currency_views.py +31 -20
  83. django_cfg/apps/payments/views/payment_views.py +2 -2
  84. django_cfg/apps/payments/views/templates/ajax.py +141 -2
  85. django_cfg/apps/payments/views/templates/base.py +21 -13
  86. django_cfg/apps/payments/views/templates/payment_detail.py +1 -1
  87. django_cfg/apps/payments/views/templates/payment_management.py +34 -40
  88. django_cfg/apps/payments/views/templates/stats.py +8 -4
  89. django_cfg/apps/payments/views/webhook_views.py +2 -2
  90. django_cfg/apps/payments/viewsets.py +3 -2
  91. django_cfg/apps/tasks/urls.py +0 -2
  92. django_cfg/apps/tasks/urls_admin.py +14 -0
  93. django_cfg/apps/urls.py +4 -4
  94. django_cfg/core/config.py +35 -0
  95. django_cfg/models/payments.py +2 -8
  96. django_cfg/modules/django_currency/__init__.py +16 -11
  97. django_cfg/modules/django_currency/clients/__init__.py +4 -4
  98. django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
  99. django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
  100. django_cfg/modules/django_currency/core/__init__.py +1 -7
  101. django_cfg/modules/django_currency/core/converter.py +18 -23
  102. django_cfg/modules/django_currency/core/models.py +122 -11
  103. django_cfg/modules/django_currency/database/__init__.py +4 -4
  104. django_cfg/modules/django_currency/database/database_loader.py +190 -309
  105. django_cfg/modules/django_unfold/dashboard.py +7 -2
  106. django_cfg/template_archive/django_sample.zip +0 -0
  107. django_cfg/templates/admin/components/action_grid.html +9 -9
  108. django_cfg/templates/admin/components/metric_card.html +5 -5
  109. django_cfg/templates/admin/components/status_badge.html +2 -2
  110. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
  111. django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
  112. django_cfg/templates/admin/snippets/components/system_health.html +1 -1
  113. django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
  114. {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/METADATA +2 -4
  115. {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/RECORD +118 -96
  116. django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
  117. django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
  118. django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
  119. django_cfg/apps/payments/services/providers/cryptomus.py +0 -311
  120. django_cfg/apps/payments/services/providers/nowpayments.py +0 -293
  121. django_cfg/apps/payments/services/validators/__init__.py +0 -8
  122. django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
  123. django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
  124. {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/WHEEL +0 -0
  125. {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/entry_points.txt +0 -0
  126. {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/licenses/LICENSE +0 -0
@@ -3,14 +3,14 @@ Payment System Notification Service
3
3
  Uses existing django_telegram and django_email modules for admin notifications.
4
4
  """
5
5
 
6
- import logging
6
+ from django_cfg.modules.django_logger import get_logger
7
7
  from typing import Dict, Any, Optional
8
8
  from django.utils import timezone
9
9
  from django_cfg.modules.django_telegram import DjangoTelegram
10
10
  from django_cfg.modules.django_email import DjangoEmailService
11
11
  from django_cfg.core.config import get_current_config
12
12
 
13
- logger = logging.getLogger(__name__)
13
+ logger = get_logger("payment_notifications")
14
14
  config = get_current_config()
15
15
 
16
16
 
@@ -6,7 +6,7 @@ Critical Foundation Security Component.
6
6
  import json
7
7
  import hmac
8
8
  import hashlib
9
- import logging
9
+ from django_cfg.modules.django_logger import get_logger
10
10
  import time
11
11
  from typing import Dict, Any, Optional, Tuple
12
12
  from datetime import datetime, timedelta
@@ -16,8 +16,9 @@ from django.conf import settings
16
16
 
17
17
  from django_cfg.apps.payments.config import get_payments_config
18
18
  from django_cfg.apps.payments.models.events import PaymentEvent
19
+ from ...models.payments import UniversalPayment
19
20
 
20
- logger = logging.getLogger(__name__)
21
+ logger = get_logger("webhook_validator")
21
22
 
22
23
 
23
24
  class WebhookValidator:
@@ -400,8 +401,6 @@ class WebhookValidator:
400
401
 
401
402
  CRITICAL: Prevents webhooks for unknown addresses.
402
403
  """
403
- from ..models.payments import UniversalPayment
404
-
405
404
  try:
406
405
  # Check if address exists in our payments
407
406
  return UniversalPayment.objects.filter(
@@ -10,12 +10,12 @@ from django.dispatch import receiver
10
10
  from django.contrib.auth import get_user_model
11
11
  from django.db import transaction
12
12
  from django.utils import timezone
13
- import logging
13
+ from django_cfg.modules.django_logger import get_logger
14
14
 
15
15
  from ..models import APIKey
16
16
 
17
17
  User = get_user_model()
18
- logger = logging.getLogger(__name__)
18
+ logger = get_logger("api_key_signals")
19
19
 
20
20
 
21
21
  @receiver(post_save, sender=User)
@@ -8,13 +8,13 @@ from django.db.models.signals import post_save, pre_save
8
8
  from django.dispatch import receiver
9
9
  from django.db import transaction
10
10
  from django.utils import timezone
11
- import logging
11
+ from django_cfg.modules.django_logger import get_logger
12
12
 
13
13
  from ..models import UniversalPayment, UserBalance, Transaction
14
14
  from ..services.cache import SimpleCache
15
- from django_cfg.core.redis import RedisService
15
+ from django.core.cache import cache
16
16
 
17
- logger = logging.getLogger(__name__)
17
+ logger = get_logger("payment_signals")
18
18
 
19
19
 
20
20
  @receiver(pre_save, sender=UniversalPayment)
@@ -92,8 +92,14 @@ def _process_completed_payment(payment: UniversalPayment):
92
92
 
93
93
  # Clear Redis cache for user
94
94
  try:
95
- redis_service = RedisService()
96
- redis_service.invalidate_user_cache(payment.user.id)
95
+ # Invalidate user cache using Django cache
96
+ user_cache_pattern = f"payments:user:{payment.user.id}:*"
97
+ # Note: Django cache doesn't support pattern deletion, so we clear specific keys
98
+ cache.delete_many([
99
+ f"payments:user:{payment.user.id}:balance",
100
+ f"payments:user:{payment.user.id}:api_keys",
101
+ f"payments:user:{payment.user.id}:subscriptions"
102
+ ])
97
103
  except Exception as e:
98
104
  logger.warning(f"Failed to clear Redis cache for user {payment.user.id}: {e}")
99
105
 
@@ -9,12 +9,12 @@ from django.dispatch import receiver
9
9
  from django.db import transaction
10
10
  from django.utils import timezone
11
11
  from datetime import timedelta
12
- import logging
12
+ from django_cfg.modules.django_logger import get_logger
13
13
 
14
14
  from ..models import Subscription, EndpointGroup, UserBalance, Transaction
15
15
  from ..services.cache import SimpleCache
16
16
 
17
- logger = logging.getLogger(__name__)
17
+ logger = get_logger("subscription_signals")
18
18
 
19
19
 
20
20
  @receiver(pre_save, sender=Subscription)
@@ -5,7 +5,7 @@ Simple webhook processing with fallback to sync processing.
5
5
  Uses existing Dramatiq configuration and graceful degradation.
6
6
  """
7
7
 
8
- import logging
8
+ from django_cfg.modules.django_logger import get_logger
9
9
  from typing import Dict, Any, Optional
10
10
  from django.db import transaction
11
11
  from django.utils import timezone
@@ -16,7 +16,7 @@ import dramatiq
16
16
  from ..services.core.payment_service import PaymentService
17
17
  from ..models.events import PaymentEvent
18
18
 
19
- logger = logging.getLogger(__name__)
19
+ logger = get_logger("webhook_processing")
20
20
 
21
21
 
22
22
  @dramatiq.actor(
@@ -0,0 +1,50 @@
1
+ {% extends "admin/change_list.html" %}
2
+ {% load static %}
3
+
4
+ {% block result_list %}
5
+ <!-- Currency Statistics Dashboard - Unfold Semantic Colors -->
6
+ <div class="bg-white border border-base-200 dark:bg-base-900 dark:border-base-700 p-4 rounded-default mb-4">
7
+ <h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark mb-3">📊 Currency Overview</h3>
8
+
9
+ <div class="grid grid-cols-4 gap-4 mb-4">
10
+ <div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
11
+ <p class="text-2xl font-bold text-primary-600 dark:text-primary-400">{{ total_currencies }}</p>
12
+ <p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">Total Currencies</p>
13
+ </div>
14
+ <div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
15
+ <p class="text-2xl font-bold text-success-600 dark:text-success-400">{{ enabled_provider_currencies }}</p>
16
+ <p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">Provider Mappings</p>
17
+ </div>
18
+ <div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
19
+ <p class="text-2xl font-bold text-warning-600 dark:text-warning-400">{{ currencies_with_rates }}</p>
20
+ <p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">With USD Rates</p>
21
+ </div>
22
+ <div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
23
+ <p class="text-2xl font-bold text-info-600 dark:text-info-400">{{ rate_coverage|floatformat:1 }}%</p>
24
+ <p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">Rate Coverage</p>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="grid grid-cols-2 gap-4">
29
+ <div class="bg-base-50 dark:bg-base-800 p-3 rounded-default">
30
+ <h4 class="font-semibold text-font-important-light dark:text-font-important-dark mb-2">Currency Types</h4>
31
+ <ul class="text-sm space-y-1 text-font-default-light dark:text-font-default-dark">
32
+ <li>💵 Fiat: <span class="font-medium text-primary-600 dark:text-primary-400">{{ fiat_count }}</span></li>
33
+ <li>₿ Crypto: <span class="font-medium text-warning-600 dark:text-warning-400">{{ crypto_count }}</span></li>
34
+ </ul>
35
+ </div>
36
+ <div class="bg-base-50 dark:bg-base-800 p-3 rounded-default">
37
+ <h4 class="font-semibold text-font-important-light dark:text-font-important-dark mb-2">🚀 Top Supported</h4>
38
+ <ul class="text-sm space-y-1 text-font-default-light dark:text-font-default-dark">
39
+ {% for currency in top_currencies %}
40
+ <li><span class="font-semibold text-primary-600 dark:text-primary-400">{{ currency.code }}:</span> {{ currency.provider_count }} providers</li>
41
+ {% empty %}
42
+ <li class="text-font-subtle-light dark:text-font-subtle-dark">No provider data available</li>
43
+ {% endfor %}
44
+ </ul>
45
+ </div>
46
+ </div>
47
+ </div>
48
+
49
+ {{ block.super }}
50
+ {% endblock %}
@@ -80,18 +80,18 @@
80
80
  <div class="flex items-center space-x-3">
81
81
  {% block header_actions %}
82
82
  <a href="{% url 'payments_dashboard:list' %}"
83
- class="inline-flex items-center px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 transition-colors duration-200">
83
+ class="inline-flex items-center px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-200">
84
84
  <span class="material-icons text-sm mr-2">history</span>
85
85
  Payment History
86
86
  </a>
87
87
  <a href="{% url 'payments_dashboard:create' %}"
88
- class="inline-flex items-center px-3 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-md text-sm font-medium transition-colors duration-200">
88
+ class="inline-flex items-center px-3 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md text-sm font-medium transition-colors duration-200">
89
89
  <span class="material-icons text-sm mr-2">add</span>
90
90
  New Payment
91
91
  </a>
92
92
  <button id="theme-toggle"
93
- class="group inline-flex items-center justify-center px-3 py-2 rounded-md bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-600 transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2">
94
- <span class="material-icons text-gray-600 dark:text-yellow-400 group-hover:text-primary-600 dark:group-hover:text-yellow-300 transition-colors duration-200">light_mode</span>
93
+ class="group inline-flex items-center justify-center px-3 py-2 rounded-md bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
94
+ <span class="material-icons text-gray-600 dark:text-yellow-400 group-hover:text-blue-600 dark:group-hover:text-yellow-300 transition-colors duration-200">light_mode</span>
95
95
  </button>
96
96
  {% endblock %}
97
97
  </div>
@@ -2,7 +2,7 @@
2
2
  {% load humanize %}
3
3
 
4
4
  <!-- Payment Card Component -->
5
- <div class="payment-card bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6 {% if compact %}compact{% endif %}"
5
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6"
6
6
  data-payment-id="{{ payment.id }}">
7
7
 
8
8
  <!-- Header -->
@@ -76,20 +76,20 @@
76
76
  <!-- Actions -->
77
77
  {% if show_actions %}
78
78
  <div class="payment-actions mt-4 flex space-x-2">
79
- <button class="btn btn-outline btn-sm flex-1"
79
+ <button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200"
80
80
  onclick="showPaymentDetails('{{ payment.id }}')">
81
81
  <span class="material-icons text-sm mr-1">visibility</span>
82
82
  View Details
83
83
  </button>
84
84
  {% if payment|can_cancel_payment %}
85
- <button class="btn btn-danger btn-sm"
85
+ <button class="px-3 py-1.5 text-xs bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 rounded-md transition-colors duration-200"
86
86
  onclick="cancelPayment('{{ payment.id }}')">
87
87
  <span class="material-icons text-sm mr-1">cancel</span>
88
88
  Cancel
89
89
  </button>
90
90
  {% endif %}
91
91
  {% if payment|is_crypto_payment and payment.pay_address %}
92
- <button class="btn btn-primary btn-sm"
92
+ <button class="px-3 py-1.5 text-xs bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 rounded-md transition-colors duration-200"
93
93
  onclick="showQRCode('{{ payment.id }}')">
94
94
  <span class="material-icons text-sm mr-1">qr_code</span>
95
95
  QR Code
@@ -134,11 +134,11 @@
134
134
 
135
135
  {% if show_actions %}
136
136
  <div class="flex space-x-2">
137
- <button class="flex-1 btn btn-outline btn-sm" onclick="showPaymentDetails('{{ payment.id }}')">
137
+ <button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200" onclick="showPaymentDetails('{{ payment.id }}')">
138
138
  Details
139
139
  </button>
140
140
  {% if payment|can_cancel_payment %}
141
- <button class="btn btn-danger btn-sm" onclick="cancelPayment('{{ payment.id }}')">
141
+ <button class="px-3 py-1.5 text-xs bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 rounded-md transition-colors duration-200" onclick="cancelPayment('{{ payment.id }}')">
142
142
  Cancel
143
143
  </button>
144
144
  {% endif %}
@@ -1,9 +1,9 @@
1
1
  {% load payments_tags %}
2
2
 
3
3
  <!-- Payment QR Code Component -->
4
- <div class="qr-code-container">
4
+ <div class="flex flex-col items-center space-y-2 p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
5
5
  {% if qr_data %}
6
- <div class="qr-code" id="qr-code-{{ payment.id }}">
6
+ <div class="w-32 h-32 bg-gray-100 dark:bg-gray-700 rounded flex items-center justify-center" id="qr-code-{{ payment.id }}">
7
7
  <!-- QR code will be generated here by JavaScript -->
8
8
  <span class="material-icons text-gray-400 text-4xl">qr_code</span>
9
9
  </div>
@@ -23,13 +23,13 @@
23
23
 
24
24
  <!-- Action Buttons -->
25
25
  <div class="flex space-x-2 pt-2">
26
- <button class="btn btn-outline btn-sm flex-1"
26
+ <button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200"
27
27
  onclick="copyToClipboard('{{ payment.pay_address }}', 'Address copied!')">
28
28
  <span class="material-icons text-sm mr-1">content_copy</span>
29
29
  Copy Address
30
30
  </button>
31
31
  {% if payment.pay_amount %}
32
- <button class="btn btn-outline btn-sm flex-1"
32
+ <button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200"
33
33
  onclick="copyToClipboard('{{ payment.pay_amount }}', 'Amount copied!')">
34
34
  <span class="material-icons text-sm mr-1">content_copy</span>
35
35
  Copy Amount
@@ -1,12 +1,15 @@
1
1
  {% load payments_tags %}
2
2
 
3
3
  <!-- Payment Progress Bar Component -->
4
- <div class="payment-progress-container">
4
+ <div>
5
5
  <!-- Progress Steps (Hidden on mobile) -->
6
- <div class="progress-steps hidden md:flex">
6
+ <div class="hidden md:flex justify-between items-center mb-4">
7
7
  {% for step in payment|payment_progress_steps %}
8
- <div class="progress-step {% if step.completed %}completed{% endif %} {% if step.active %}active{% endif %}">
9
- <div class="step-icon {% if step.completed %}completed{% elif step.active %}active{% endif %}">
8
+ <div class="flex flex-col items-center text-center">
9
+ <div class="w-8 h-8 flex items-center justify-center rounded-full border-2 mb-2
10
+ {% if step.completed %}border-green-500 bg-green-500 text-white
11
+ {% elif step.active %}border-blue-500 bg-blue-500 text-white
12
+ {% else %}border-gray-300 dark:border-gray-600{% endif %}">
10
13
  {% if step.completed %}
11
14
  <span class="material-icons text-sm">check</span>
12
15
  {% elif step.active %}
@@ -15,14 +18,18 @@
15
18
  <div class="w-3 h-3 bg-gray-300 rounded-full"></div>
16
19
  {% endif %}
17
20
  </div>
18
- <div class="step-label">{{ step.label }}</div>
21
+ <div class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ step.label }}</div>
19
22
  </div>
20
23
  {% endfor %}
21
24
  </div>
22
25
 
23
26
  <!-- Progress Bar -->
24
- <div class="progress-bar mt-4 md:mt-0">
25
- <div class="progress-fill {% if payment.status == 'completed' %}success{% elif payment.status == 'failed' %}danger{% elif payment.status == 'pending' %}warning{% endif %}"
27
+ <div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 mt-4 md:mt-0">
28
+ <div class="h-2 rounded-full transition-all duration-500 ease-out
29
+ {% if payment.status == 'completed' %}bg-green-600
30
+ {% elif payment.status == 'failed' %}bg-red-600
31
+ {% elif payment.status == 'pending' %}bg-yellow-600
32
+ {% else %}bg-blue-600{% endif %}"
26
33
  style="width: {{ payment|payment_progress_percentage }}%"
27
34
  data-percentage="{{ payment|payment_progress_percentage }}">
28
35
  </div>
@@ -1,11 +1,11 @@
1
1
  {% load payments_tags %}
2
2
 
3
3
  <!-- Provider Statistics Component -->
4
- <div class="provider-stats space-y-4">
4
+ <div class="space-y-4">
5
5
  {% for stat in provider_stats %}
6
6
  <div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
7
7
  <div class="flex items-center space-x-3">
8
- <div class="provider-icon {{ stat.provider }}">
8
+ <div class="w-6 h-6 rounded {% if stat.provider == 'nowpayments' %}bg-orange-500{% elif stat.provider == 'cryptapi' %}bg-blue-500{% elif stat.provider == 'cryptomus' %}bg-purple-500{% elif stat.provider == 'stripe' %}bg-indigo-500{% else %}bg-gray-500{% endif %} flex items-center justify-center">
9
9
  <span class="material-icons text-white text-sm">{{ stat.provider|payment_method_icon }}</span>
10
10
  </div>
11
11
  <div>
@@ -1,7 +1,14 @@
1
1
  {% load payments_tags %}
2
2
 
3
3
  <!-- Payment Status Badge Component -->
4
- <span class="payment-status-badge payment-status-{{ payment.status|lower }} inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium"
4
+ <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
5
+ {% if payment.status == 'pending' %}bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200
6
+ {% elif payment.status == 'confirming' %}bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
7
+ {% elif payment.status == 'confirmed' or payment.status == 'completed' %}bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200
8
+ {% elif payment.status == 'failed' %}bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200
9
+ {% elif payment.status == 'expired' or payment.status == 'cancelled' %}bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200
10
+ {% elif payment.status == 'refunded' %}bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200
11
+ {% else %}bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200{% endif %}"
5
12
  data-status="{{ payment.status }}">
6
13
  {% if payment.status == 'pending' %}
7
14
  <span class="material-icons text-sm mr-1 animate-pulse">pending</span>
@@ -1,11 +1,13 @@
1
1
  {% load payments_tags %}
2
2
 
3
3
  <!-- Status Overview Cards -->
4
- {% get_payment_stats as stats %}
4
+ {% if not payment_stats %}
5
+ {% get_payment_stats as payment_stats %}
6
+ {% endif %}
5
7
 
6
- <div class="status-overview">
7
- <!-- Total Payments -->
8
- <div class="status-card">
8
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
9
+ <!-- Total Payments -->
10
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
9
11
  <div class="flex items-center">
10
12
  <div class="flex-shrink-0">
11
13
  <span class="material-icons text-blue-600 dark:text-blue-400 text-3xl">payments</span>
@@ -13,14 +15,14 @@
13
15
  <div class="ml-4">
14
16
  <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Total Payments</p>
15
17
  <p class="text-2xl font-bold text-gray-900 dark:text-white">
16
- {{ stats.total_payments_count|default:0 }}
18
+ {{ payment_payment_stats.total_payments_count|default:0 }}
17
19
  </p>
18
20
  </div>
19
21
  </div>
20
22
  </div>
21
23
 
22
24
  <!-- Pending Payments -->
23
- <div class="status-card">
25
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
24
26
  <div class="flex items-center">
25
27
  <div class="flex-shrink-0">
26
28
  <span class="material-icons text-yellow-600 dark:text-yellow-400 text-3xl">pending</span>
@@ -28,11 +30,11 @@
28
30
  <div class="ml-4">
29
31
  <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Pending</p>
30
32
  <p class="text-2xl font-bold text-gray-900 dark:text-white">
31
- {{ stats.pending_payments_count|default:0 }}
33
+ {{ payment_payment_stats.pending_payments_count|default:0 }}
32
34
  </p>
33
- {% if stats.confirming_payments_count %}
35
+ {% if payment_payment_stats.confirming_payments_count %}
34
36
  <p class="text-xs text-gray-500 dark:text-gray-400">
35
- +{{ stats.confirming_payments_count }} confirming
37
+ +{{ payment_payment_stats.confirming_payments_count }} confirming
36
38
  </p>
37
39
  {% endif %}
38
40
  </div>
@@ -40,7 +42,7 @@
40
42
  </div>
41
43
 
42
44
  <!-- Completed Payments -->
43
- <div class="status-card">
45
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
44
46
  <div class="flex items-center">
45
47
  <div class="flex-shrink-0">
46
48
  <span class="material-icons text-green-600 dark:text-green-400 text-3xl">check_circle</span>
@@ -48,11 +50,11 @@
48
50
  <div class="ml-4">
49
51
  <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Completed</p>
50
52
  <p class="text-2xl font-bold text-gray-900 dark:text-white">
51
- {{ stats.completed_payments_count|default:0 }}
53
+ {{ payment_stats.completed_payments_count|default:0 }}
52
54
  </p>
53
- {% if stats.total_payments_count > 0 %}
55
+ {% if payment_stats.total_payments_count > 0 %}
54
56
  <p class="text-xs text-green-600 dark:text-green-400">
55
- {{ stats.completed_payments_count|floatformat:0 }}/{{ stats.total_payments_count }} success
57
+ {{ payment_stats.completed_payments_count|floatformat:0 }}/{{ payment_stats.total_payments_count }} success
56
58
  </p>
57
59
  {% endif %}
58
60
  </div>
@@ -60,7 +62,7 @@
60
62
  </div>
61
63
 
62
64
  <!-- Total Volume -->
63
- <div class="status-card">
65
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
64
66
  <div class="flex items-center">
65
67
  <div class="flex-shrink-0">
66
68
  <span class="material-icons text-purple-600 dark:text-purple-400 text-3xl">account_balance</span>
@@ -68,11 +70,11 @@
68
70
  <div class="ml-4">
69
71
  <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Total Volume</p>
70
72
  <p class="text-2xl font-bold text-gray-900 dark:text-white">
71
- ${{ stats.total_volume|floatformat:2|default:"0.00" }}
73
+ ${{ payment_stats.total_volume|floatformat:2|default:"0.00" }}
72
74
  </p>
73
- {% if stats.failed_payments_count %}
75
+ {% if payment_stats.failed_payments_count %}
74
76
  <p class="text-xs text-red-500 dark:text-red-400">
75
- {{ stats.failed_payments_count }} failed
77
+ {{ payment_stats.failed_payments_count }} failed
76
78
  </p>
77
79
  {% endif %}
78
80
  </div>
@@ -86,24 +88,25 @@
86
88
  <div class="flex items-center space-x-4">
87
89
  <span class="text-sm font-medium text-gray-700 dark:text-gray-300">Quick Actions:</span>
88
90
  <div class="flex space-x-2">
89
- <button class="btn btn-primary btn-sm" onclick="createNewPayment()">
90
- <span class="material-icons text-sm mr-1">add</span>
91
- New Payment
92
- </button>
93
- <button class="btn btn-outline btn-sm" onclick="refreshPayments()">
94
- <span class="material-icons text-sm mr-1">refresh</span>
95
- Refresh
96
- </button>
97
- <button class="btn btn-outline btn-sm" onclick="exportPayments()">
98
- <span class="material-icons text-sm mr-1">download</span>
99
- Export
100
- </button>
91
+ <button class="px-3 py-1.5 text-xs bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 rounded-md transition-colors duration-200" onclick="createNewPayment()">
92
+ <span class="material-icons text-sm mr-1">add</span>
93
+ New Payment
94
+ </button>
95
+ <button class="px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200" onclick="refreshPayments()">
96
+ <span class="material-icons text-sm mr-1">refresh</span>
97
+ Refresh
98
+ </button>
99
+ <button class="px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200" onclick="exportPayments()">
100
+ <span class="material-icons text-sm mr-1">download</span>
101
+ Export
102
+ </button>
101
103
  </div>
102
104
  </div>
103
105
 
104
106
  <!-- Live Status Indicator -->
105
107
  <div class="flex items-center space-x-2">
106
- <div class="payment-live-indicator">
108
+ <div class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
109
+ <div class="w-2 h-2 bg-green-500 rounded-full mr-2 animate-pulse"></div>
107
110
  Live Updates
108
111
  </div>
109
112
  <span class="text-xs text-gray-500 dark:text-gray-400">
@@ -142,3 +145,4 @@ function updateStatsLastUpdate() {
142
145
  }
143
146
  }
144
147
  </script>
148
+