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,17 +3,18 @@ Usage Tracking Middleware.
3
3
  Tracks API usage for billing, analytics, and monitoring.
4
4
  """
5
5
 
6
- import logging
6
+ from django_cfg.modules.django_logger import get_logger
7
7
  import json
8
8
  from typing import Optional, Dict, Any
9
9
  from django.http import HttpRequest, HttpResponse
10
10
  from django.utils.deprecation import MiddlewareMixin
11
11
  from django.conf import settings
12
12
  from django.utils import timezone
13
+ from django.core.cache import cache
13
14
  from ..models import APIKey, Subscription, Transaction
14
15
  from ..services import RateLimitCache
15
16
 
16
- logger = logging.getLogger(__name__)
17
+ logger = get_logger("usage_tracking")
17
18
 
18
19
 
19
20
  class UsageTrackingMiddleware(MiddlewareMixin):
@@ -30,7 +31,6 @@ class UsageTrackingMiddleware(MiddlewareMixin):
30
31
 
31
32
  def __init__(self, get_response=None):
32
33
  super().__init__(get_response)
33
- self.redis_service = RedisService()
34
34
 
35
35
  # Enable/disable usage tracking
36
36
  self.enabled = getattr(settings, 'PAYMENTS_USAGE_TRACKING_ENABLED', True)
@@ -236,28 +236,31 @@ class UsageTrackingMiddleware(MiddlewareMixin):
236
236
  date_key = usage_data['start_time'].strftime('%Y-%m-%d')
237
237
  user_id = usage_data['user_id']
238
238
 
239
- # Increment counters
240
- self.redis_service.increment_daily_usage(user_id, date_key)
239
+ # Increment counters using Django cache
240
+ daily_usage_key = f"payments:daily_usage:{user_id}:{date_key}"
241
+ current_usage = cache.get(daily_usage_key, 0)
242
+ cache.set(daily_usage_key, current_usage + 1, timeout=86400) # 24 hours
241
243
 
242
244
  if usage_data.get('subscription_id'):
243
- self.redis_service.increment_subscription_usage(
244
- usage_data['subscription_id'],
245
- date_key
246
- )
245
+ sub_usage_key = f"payments:subscription_usage:{usage_data['subscription_id']}:{date_key}"
246
+ current_sub_usage = cache.get(sub_usage_key, 0)
247
+ cache.set(sub_usage_key, current_sub_usage + 1, timeout=86400) # 24 hours
247
248
 
248
249
  # Store performance metrics
249
250
  if usage_data['response_time_ms'] > 0:
250
- self.redis_service.record_response_time(
251
- usage_data['path'],
252
- usage_data['response_time_ms']
253
- )
251
+ perf_key = f"payments:performance:{usage_data['path'].replace('/', '_')}"
252
+ response_times = cache.get(perf_key, [])
253
+ response_times.append(usage_data['response_time_ms'])
254
+ # Keep only last 100 measurements
255
+ if len(response_times) > 100:
256
+ response_times = response_times[-100:]
257
+ cache.set(perf_key, response_times, timeout=3600) # 1 hour
254
258
 
255
259
  # Store error metrics
256
260
  if usage_data.get('is_error'):
257
- self.redis_service.increment_error_count(
258
- usage_data['path'],
259
- usage_data['status_code']
260
- )
261
+ error_key = f"payments:errors:{usage_data['path'].replace('/', '_')}:{usage_data['status_code']}"
262
+ current_errors = cache.get(error_key, 0)
263
+ cache.set(error_key, current_errors + 1, timeout=3600) # 1 hour
261
264
 
262
265
  except Exception as e:
263
266
  logger.error(f"Error storing usage data in Redis: {e}")
@@ -0,0 +1,241 @@
1
+ # Generated by Django 5.2.6 on 2025-09-24 19:54
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("django_cfg_payments", "0001_initial"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name="Network",
15
+ fields=[
16
+ (
17
+ "id",
18
+ models.BigAutoField(
19
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
20
+ ),
21
+ ),
22
+ ("created_at", models.DateTimeField(auto_now_add=True, db_index=True)),
23
+ ("updated_at", models.DateTimeField(auto_now=True)),
24
+ (
25
+ "code",
26
+ models.CharField(
27
+ help_text="Network code: ethereum, bitcoin, tron, bsc",
28
+ max_length=20,
29
+ unique=True,
30
+ ),
31
+ ),
32
+ (
33
+ "name",
34
+ models.CharField(
35
+ help_text="Network name: Ethereum, Bitcoin, TRON, BSC", max_length=100
36
+ ),
37
+ ),
38
+ ],
39
+ options={
40
+ "verbose_name": "Network",
41
+ "verbose_name_plural": "Networks",
42
+ "db_table": "payment_networks",
43
+ "ordering": ["name"],
44
+ },
45
+ ),
46
+ migrations.CreateModel(
47
+ name="ProviderCurrency",
48
+ fields=[
49
+ (
50
+ "id",
51
+ models.BigAutoField(
52
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
53
+ ),
54
+ ),
55
+ ("created_at", models.DateTimeField(auto_now_add=True, db_index=True)),
56
+ ("updated_at", models.DateTimeField(auto_now=True)),
57
+ (
58
+ "provider_name",
59
+ models.CharField(
60
+ help_text="Provider: nowpayments, stripe, cryptomus", max_length=50
61
+ ),
62
+ ),
63
+ (
64
+ "provider_currency_code",
65
+ models.CharField(
66
+ help_text="Provider code: USDTERC20, USDTBSC, usd", max_length=20
67
+ ),
68
+ ),
69
+ (
70
+ "min_amount",
71
+ models.DecimalField(
72
+ blank=True,
73
+ decimal_places=8,
74
+ help_text="Minimum payment amount",
75
+ max_digits=20,
76
+ null=True,
77
+ ),
78
+ ),
79
+ (
80
+ "max_amount",
81
+ models.DecimalField(
82
+ blank=True,
83
+ decimal_places=8,
84
+ help_text="Maximum payment amount (null = no limit)",
85
+ max_digits=20,
86
+ null=True,
87
+ ),
88
+ ),
89
+ ("is_enabled", models.BooleanField(default=True, help_text="Enabled by provider")),
90
+ (
91
+ "available_for_payment",
92
+ models.BooleanField(default=True, help_text="Can receive payments"),
93
+ ),
94
+ (
95
+ "available_for_payout",
96
+ models.BooleanField(default=True, help_text="Can send payouts"),
97
+ ),
98
+ (
99
+ "is_popular",
100
+ models.BooleanField(default=False, help_text="Popular/recommended by provider"),
101
+ ),
102
+ (
103
+ "is_stable",
104
+ models.BooleanField(default=False, help_text="Stable coin (USDT, USDC, etc.)"),
105
+ ),
106
+ (
107
+ "priority",
108
+ models.IntegerField(
109
+ default=0, help_text="Display priority (higher = shown first)"
110
+ ),
111
+ ),
112
+ (
113
+ "logo_url",
114
+ models.URLField(blank=True, help_text="Currency logo/icon URL from provider"),
115
+ ),
116
+ (
117
+ "metadata",
118
+ models.JSONField(
119
+ blank=True,
120
+ default=dict,
121
+ help_text="All provider-specific data: logo_url, smart_contract, wallet_regex, commission_percent, etc.",
122
+ ),
123
+ ),
124
+ ],
125
+ options={
126
+ "verbose_name": "Provider Currency",
127
+ "verbose_name_plural": "Provider Currencies",
128
+ "db_table": "payment_provider_currencies",
129
+ "ordering": ["-priority", "provider_name", "base_currency__code"],
130
+ },
131
+ ),
132
+ migrations.AlterUniqueTogether(
133
+ name="currencynetwork",
134
+ unique_together=None,
135
+ ),
136
+ migrations.RemoveField(
137
+ model_name="currencynetwork",
138
+ name="currency",
139
+ ),
140
+ migrations.AlterModelOptions(
141
+ name="currency",
142
+ options={
143
+ "ordering": ["currency_type", "code"],
144
+ "verbose_name": "Currency",
145
+ "verbose_name_plural": "Currencies",
146
+ },
147
+ ),
148
+ migrations.RemoveIndex(
149
+ model_name="currency",
150
+ name="payment_cur_code_e2a506_idx",
151
+ ),
152
+ migrations.RemoveIndex(
153
+ model_name="currency",
154
+ name="payment_cur_currenc_6057a9_idx",
155
+ ),
156
+ migrations.RemoveIndex(
157
+ model_name="currency",
158
+ name="payment_cur_is_acti_8d558f_idx",
159
+ ),
160
+ migrations.RemoveField(
161
+ model_name="currency",
162
+ name="decimal_places",
163
+ ),
164
+ migrations.RemoveField(
165
+ model_name="currency",
166
+ name="is_active",
167
+ ),
168
+ migrations.RemoveField(
169
+ model_name="currency",
170
+ name="min_payment_amount",
171
+ ),
172
+ migrations.RemoveField(
173
+ model_name="currency",
174
+ name="rate_updated_at",
175
+ ),
176
+ migrations.RemoveField(
177
+ model_name="currency",
178
+ name="symbol",
179
+ ),
180
+ migrations.RemoveField(
181
+ model_name="currency",
182
+ name="usd_rate",
183
+ ),
184
+ migrations.AlterField(
185
+ model_name="currency",
186
+ name="code",
187
+ field=models.CharField(
188
+ help_text="Clean currency code: BTC, USDT, ETH, USD (NO network suffixes)",
189
+ max_length=10,
190
+ unique=True,
191
+ ),
192
+ ),
193
+ migrations.AlterField(
194
+ model_name="currency",
195
+ name="currency_type",
196
+ field=models.CharField(
197
+ choices=[("fiat", "Fiat Currency"), ("crypto", "Cryptocurrency")],
198
+ help_text="fiat or crypto",
199
+ max_length=10,
200
+ ),
201
+ ),
202
+ migrations.AlterField(
203
+ model_name="currency",
204
+ name="name",
205
+ field=models.CharField(
206
+ help_text="Currency name: Bitcoin, Tether USD, Ethereum", max_length=100
207
+ ),
208
+ ),
209
+ migrations.AddField(
210
+ model_name="providercurrency",
211
+ name="base_currency",
212
+ field=models.ForeignKey(
213
+ help_text="Base currency: BTC, USDT, ETH",
214
+ on_delete=django.db.models.deletion.CASCADE,
215
+ related_name="provider_mappings",
216
+ to="django_cfg_payments.currency",
217
+ ),
218
+ ),
219
+ migrations.AddField(
220
+ model_name="providercurrency",
221
+ name="network",
222
+ field=models.ForeignKey(
223
+ blank=True,
224
+ help_text="Network for crypto (null for fiat)",
225
+ null=True,
226
+ on_delete=django.db.models.deletion.CASCADE,
227
+ related_name="provider_currencies",
228
+ to="django_cfg_payments.network",
229
+ ),
230
+ ),
231
+ migrations.DeleteModel(
232
+ name="CurrencyNetwork",
233
+ ),
234
+ migrations.AlterUniqueTogether(
235
+ name="providercurrency",
236
+ unique_together={
237
+ ("provider_name", "base_currency", "network"),
238
+ ("provider_name", "provider_currency_code"),
239
+ },
240
+ ),
241
+ ]
@@ -0,0 +1,30 @@
1
+ # Generated by Django 5.2.6 on 2025-09-25 06:06
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("django_cfg_payments", "0002_network_providercurrency_and_more"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="currency",
14
+ name="rate_updated_at",
15
+ field=models.DateTimeField(
16
+ blank=True, help_text="When the USD rate was last updated", null=True
17
+ ),
18
+ ),
19
+ migrations.AddField(
20
+ model_name="currency",
21
+ name="usd_rate",
22
+ field=models.DecimalField(
23
+ blank=True,
24
+ decimal_places=8,
25
+ help_text="Cached USD exchange rate (1 CURRENCY = X USD)",
26
+ max_digits=20,
27
+ null=True,
28
+ ),
29
+ ),
30
+ ]
@@ -8,7 +8,7 @@ Django ORM models for the universal payments system.
8
8
  from .base import TimestampedModel
9
9
 
10
10
  # Currency models
11
- from .currencies import Currency, CurrencyNetwork
11
+ from .currencies import Currency, Network, ProviderCurrency
12
12
 
13
13
  # Payment models
14
14
  from .payments import UniversalPayment
@@ -43,7 +43,8 @@ __all__ = [
43
43
 
44
44
  # Currencies
45
45
  'Currency',
46
- 'CurrencyNetwork',
46
+ 'Network',
47
+ 'ProviderCurrency',
47
48
 
48
49
  # Models
49
50
  'UniversalPayment',