django-cfg 1.2.31__py3-none-any.whl → 1.3.3__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 (264) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/api/health/views.py +4 -2
  3. django_cfg/apps/knowbase/config/settings.py +16 -15
  4. django_cfg/apps/payments/README.md +326 -0
  5. django_cfg/apps/payments/admin/__init__.py +20 -10
  6. django_cfg/apps/payments/admin/api_keys_admin.py +521 -237
  7. django_cfg/apps/payments/admin/balance_admin.py +592 -297
  8. django_cfg/apps/payments/admin/currencies_admin.py +526 -222
  9. django_cfg/apps/payments/admin/filters.py +306 -199
  10. django_cfg/apps/payments/admin/payments_admin.py +465 -70
  11. django_cfg/apps/payments/admin/subscriptions_admin.py +578 -128
  12. django_cfg/apps/payments/admin_interface/__init__.py +18 -0
  13. django_cfg/apps/payments/admin_interface/templates/payments/base.html +162 -0
  14. django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +38 -0
  15. django_cfg/apps/payments/admin_interface/templates/payments/components/loading_spinner.html +16 -0
  16. django_cfg/apps/payments/admin_interface/templates/payments/components/notification.html +27 -0
  17. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_card.html +86 -0
  18. django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +39 -0
  19. django_cfg/apps/payments/admin_interface/templates/payments/currency_converter.html +382 -0
  20. django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +300 -0
  21. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +303 -0
  22. django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +382 -0
  23. django_cfg/apps/payments/admin_interface/templates/payments/payment_status.html +500 -0
  24. django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +594 -0
  25. django_cfg/apps/payments/admin_interface/views/__init__.py +23 -0
  26. django_cfg/apps/payments/admin_interface/views/payment_views.py +259 -0
  27. django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +37 -0
  28. django_cfg/apps/payments/apps.py +34 -9
  29. django_cfg/apps/payments/config/__init__.py +28 -51
  30. django_cfg/apps/payments/config/constance/__init__.py +22 -0
  31. django_cfg/apps/payments/config/constance/config_service.py +123 -0
  32. django_cfg/apps/payments/config/constance/fields.py +69 -0
  33. django_cfg/apps/payments/config/constance/settings.py +160 -0
  34. django_cfg/apps/payments/config/django_cfg_integration.py +202 -0
  35. django_cfg/apps/payments/config/helpers.py +130 -0
  36. django_cfg/apps/payments/management/__init__.py +1 -3
  37. django_cfg/apps/payments/management/commands/__init__.py +1 -3
  38. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +419 -0
  39. django_cfg/apps/payments/management/commands/currency_stats.py +297 -225
  40. django_cfg/apps/payments/management/commands/manage_currencies.py +303 -151
  41. django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
  42. django_cfg/apps/payments/management/commands/process_pending_payments.py +357 -0
  43. django_cfg/apps/payments/management/commands/test_providers.py +434 -0
  44. django_cfg/apps/payments/middleware/__init__.py +3 -1
  45. django_cfg/apps/payments/middleware/api_access.py +329 -222
  46. django_cfg/apps/payments/middleware/rate_limiting.py +342 -152
  47. django_cfg/apps/payments/middleware/usage_tracking.py +249 -240
  48. django_cfg/apps/payments/migrations/0001_initial.py +708 -536
  49. django_cfg/apps/payments/models/__init__.py +13 -18
  50. django_cfg/apps/payments/models/api_keys.py +121 -43
  51. django_cfg/apps/payments/models/balance.py +153 -115
  52. django_cfg/apps/payments/models/base.py +68 -15
  53. django_cfg/apps/payments/models/currencies.py +172 -148
  54. django_cfg/apps/payments/models/managers/__init__.py +44 -0
  55. django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
  56. django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
  57. django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
  58. django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
  59. django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
  60. django_cfg/apps/payments/models/payments.py +235 -285
  61. django_cfg/apps/payments/models/subscriptions.py +257 -177
  62. django_cfg/apps/payments/models/tariffs.py +147 -40
  63. django_cfg/apps/payments/services/__init__.py +209 -56
  64. django_cfg/apps/payments/services/cache/__init__.py +6 -6
  65. django_cfg/apps/payments/services/cache_service/__init__.py +143 -0
  66. django_cfg/apps/payments/services/cache_service/api_key_cache.py +37 -0
  67. django_cfg/apps/payments/services/{cache/base.py → cache_service/interfaces.py} +3 -1
  68. django_cfg/apps/payments/services/cache_service/keys.py +49 -0
  69. django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +47 -0
  70. django_cfg/apps/payments/services/cache_service/simple_cache.py +101 -0
  71. django_cfg/apps/payments/services/core/__init__.py +10 -6
  72. django_cfg/apps/payments/services/core/balance_service.py +435 -360
  73. django_cfg/apps/payments/services/core/base.py +166 -0
  74. django_cfg/apps/payments/services/core/currency_service.py +478 -0
  75. django_cfg/apps/payments/services/core/payment_service.py +371 -465
  76. django_cfg/apps/payments/services/core/subscription_service.py +425 -481
  77. django_cfg/apps/payments/services/core/webhook_service.py +410 -0
  78. django_cfg/apps/payments/services/integrations/__init__.py +29 -0
  79. django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
  80. django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
  81. django_cfg/apps/payments/services/providers/__init__.py +9 -14
  82. django_cfg/apps/payments/services/providers/base.py +234 -174
  83. django_cfg/apps/payments/services/providers/nowpayments.py +478 -0
  84. django_cfg/apps/payments/services/providers/registry.py +367 -301
  85. django_cfg/apps/payments/services/types/__init__.py +78 -0
  86. django_cfg/apps/payments/services/types/data.py +177 -0
  87. django_cfg/apps/payments/services/types/requests.py +150 -0
  88. django_cfg/apps/payments/services/types/responses.py +156 -0
  89. django_cfg/apps/payments/services/types/webhooks.py +232 -0
  90. django_cfg/apps/payments/signals/__init__.py +33 -8
  91. django_cfg/apps/payments/signals/api_key_signals.py +210 -129
  92. django_cfg/apps/payments/signals/balance_signals.py +174 -0
  93. django_cfg/apps/payments/signals/payment_signals.py +128 -103
  94. django_cfg/apps/payments/signals/subscription_signals.py +194 -142
  95. django_cfg/apps/payments/static/payments/css/components.css +380 -0
  96. django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
  97. django_cfg/apps/payments/static/payments/js/components.js +545 -0
  98. django_cfg/apps/payments/static/payments/js/utils.js +412 -0
  99. django_cfg/apps/payments/templatetags/__init__.py +1 -1
  100. django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
  101. django_cfg/apps/payments/urls.py +45 -48
  102. django_cfg/apps/payments/urls_admin.py +33 -42
  103. django_cfg/apps/payments/views/api/__init__.py +101 -0
  104. django_cfg/apps/payments/views/api/api_keys.py +387 -0
  105. django_cfg/apps/payments/views/api/balances.py +381 -0
  106. django_cfg/apps/payments/views/api/base.py +298 -0
  107. django_cfg/apps/payments/views/api/currencies.py +402 -0
  108. django_cfg/apps/payments/views/api/payments.py +415 -0
  109. django_cfg/apps/payments/views/api/subscriptions.py +475 -0
  110. django_cfg/apps/payments/views/api/webhooks.py +476 -0
  111. django_cfg/apps/payments/views/serializers/__init__.py +99 -0
  112. django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
  113. django_cfg/apps/payments/views/serializers/balances.py +300 -0
  114. django_cfg/apps/payments/views/serializers/currencies.py +335 -0
  115. django_cfg/apps/payments/views/serializers/payments.py +387 -0
  116. django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
  117. django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
  118. django_cfg/config.py +1 -1
  119. django_cfg/core/config.py +40 -4
  120. django_cfg/core/generation.py +25 -4
  121. django_cfg/core/integration/README.md +363 -0
  122. django_cfg/core/integration/__init__.py +47 -0
  123. django_cfg/core/integration/commands_collector.py +239 -0
  124. django_cfg/core/integration/display/__init__.py +15 -0
  125. django_cfg/core/integration/display/base.py +157 -0
  126. django_cfg/core/integration/display/ngrok.py +164 -0
  127. django_cfg/core/integration/display/startup.py +815 -0
  128. django_cfg/core/integration/url_integration.py +123 -0
  129. django_cfg/core/integration/version_checker.py +160 -0
  130. django_cfg/management/commands/auto_generate.py +4 -0
  131. django_cfg/management/commands/check_settings.py +6 -0
  132. django_cfg/management/commands/clear_constance.py +5 -2
  133. django_cfg/management/commands/create_token.py +6 -0
  134. django_cfg/management/commands/list_urls.py +6 -0
  135. django_cfg/management/commands/migrate_all.py +6 -0
  136. django_cfg/management/commands/migrator.py +3 -0
  137. django_cfg/management/commands/rundramatiq.py +6 -0
  138. django_cfg/management/commands/runserver_ngrok.py +51 -29
  139. django_cfg/management/commands/script.py +6 -0
  140. django_cfg/management/commands/show_config.py +12 -2
  141. django_cfg/management/commands/show_urls.py +4 -0
  142. django_cfg/management/commands/superuser.py +6 -0
  143. django_cfg/management/commands/task_clear.py +4 -1
  144. django_cfg/management/commands/task_status.py +3 -1
  145. django_cfg/management/commands/test_email.py +3 -0
  146. django_cfg/management/commands/test_telegram.py +6 -0
  147. django_cfg/management/commands/test_twilio.py +6 -0
  148. django_cfg/management/commands/tree.py +6 -0
  149. django_cfg/management/commands/validate_config.py +155 -149
  150. django_cfg/models/constance.py +31 -11
  151. django_cfg/models/payments.py +175 -492
  152. django_cfg/modules/django_logger.py +160 -146
  153. django_cfg/modules/django_unfold/dashboard.py +64 -16
  154. django_cfg/registry/core.py +1 -0
  155. django_cfg/template_archive/django_sample.zip +0 -0
  156. django_cfg/utils/smart_defaults.py +227 -570
  157. django_cfg/utils/toolkit.py +51 -11
  158. {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/METADATA +4 -1
  159. {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/RECORD +162 -185
  160. django_cfg/apps/payments/__init__.py +0 -8
  161. django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
  162. django_cfg/apps/payments/config/module.py +0 -70
  163. django_cfg/apps/payments/config/providers.py +0 -105
  164. django_cfg/apps/payments/config/settings.py +0 -96
  165. django_cfg/apps/payments/config/utils.py +0 -52
  166. django_cfg/apps/payments/decorators.py +0 -291
  167. django_cfg/apps/payments/management/commands/README.md +0 -146
  168. django_cfg/apps/payments/managers/__init__.py +0 -23
  169. django_cfg/apps/payments/managers/api_key_manager.py +0 -35
  170. django_cfg/apps/payments/managers/balance_manager.py +0 -361
  171. django_cfg/apps/payments/managers/currency_manager.py +0 -306
  172. django_cfg/apps/payments/managers/payment_manager.py +0 -192
  173. django_cfg/apps/payments/managers/subscription_manager.py +0 -37
  174. django_cfg/apps/payments/managers/tariff_manager.py +0 -29
  175. django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +0 -241
  176. django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +0 -30
  177. django_cfg/apps/payments/models/events.py +0 -73
  178. django_cfg/apps/payments/serializers/__init__.py +0 -57
  179. django_cfg/apps/payments/serializers/api_keys.py +0 -51
  180. django_cfg/apps/payments/serializers/balance.py +0 -59
  181. django_cfg/apps/payments/serializers/currencies.py +0 -63
  182. django_cfg/apps/payments/serializers/payments.py +0 -62
  183. django_cfg/apps/payments/serializers/subscriptions.py +0 -71
  184. django_cfg/apps/payments/serializers/tariffs.py +0 -56
  185. django_cfg/apps/payments/services/billing/__init__.py +0 -8
  186. django_cfg/apps/payments/services/cache/simple_cache.py +0 -135
  187. django_cfg/apps/payments/services/core/fallback_service.py +0 -432
  188. django_cfg/apps/payments/services/internal_types.py +0 -461
  189. django_cfg/apps/payments/services/middleware/__init__.py +0 -8
  190. django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
  191. django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -76
  192. django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
  193. django_cfg/apps/payments/services/providers/cryptapi/__init__.py +0 -4
  194. django_cfg/apps/payments/services/providers/cryptapi/config.py +0 -8
  195. django_cfg/apps/payments/services/providers/cryptapi/models.py +0 -192
  196. django_cfg/apps/payments/services/providers/cryptapi/provider.py +0 -439
  197. django_cfg/apps/payments/services/providers/cryptomus/__init__.py +0 -4
  198. django_cfg/apps/payments/services/providers/cryptomus/models.py +0 -176
  199. django_cfg/apps/payments/services/providers/cryptomus/provider.py +0 -429
  200. django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +0 -564
  201. django_cfg/apps/payments/services/providers/models/__init__.py +0 -34
  202. django_cfg/apps/payments/services/providers/models/currencies.py +0 -190
  203. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +0 -4
  204. django_cfg/apps/payments/services/providers/nowpayments/models.py +0 -196
  205. django_cfg/apps/payments/services/providers/nowpayments/provider.py +0 -380
  206. django_cfg/apps/payments/services/providers/stripe/__init__.py +0 -4
  207. django_cfg/apps/payments/services/providers/stripe/models.py +0 -184
  208. django_cfg/apps/payments/services/providers/stripe/provider.py +0 -109
  209. django_cfg/apps/payments/services/security/__init__.py +0 -34
  210. django_cfg/apps/payments/services/security/error_handler.py +0 -635
  211. django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
  212. django_cfg/apps/payments/services/security/webhook_validator.py +0 -474
  213. django_cfg/apps/payments/static/payments/css/payments.css +0 -340
  214. django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
  215. django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
  216. django_cfg/apps/payments/static/payments/js/theme.js +0 -86
  217. django_cfg/apps/payments/tasks/__init__.py +0 -12
  218. django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
  219. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +0 -50
  220. django_cfg/apps/payments/templates/payments/base.html +0 -182
  221. django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
  222. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
  223. django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -43
  224. django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
  225. django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -34
  226. django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -148
  227. django_cfg/apps/payments/templates/payments/dashboard.html +0 -258
  228. django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +0 -35
  229. django_cfg/apps/payments/templates/payments/payment_create.html +0 -579
  230. django_cfg/apps/payments/templates/payments/payment_detail.html +0 -373
  231. django_cfg/apps/payments/templates/payments/payment_list.html +0 -354
  232. django_cfg/apps/payments/templates/payments/stats.html +0 -261
  233. django_cfg/apps/payments/templates/payments/test.html +0 -213
  234. django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
  235. django_cfg/apps/payments/utils/__init__.py +0 -43
  236. django_cfg/apps/payments/utils/billing_utils.py +0 -342
  237. django_cfg/apps/payments/utils/config_utils.py +0 -239
  238. django_cfg/apps/payments/utils/middleware_utils.py +0 -228
  239. django_cfg/apps/payments/utils/validation_utils.py +0 -94
  240. django_cfg/apps/payments/views/__init__.py +0 -63
  241. django_cfg/apps/payments/views/api_key_views.py +0 -164
  242. django_cfg/apps/payments/views/balance_views.py +0 -75
  243. django_cfg/apps/payments/views/currency_views.py +0 -122
  244. django_cfg/apps/payments/views/payment_views.py +0 -149
  245. django_cfg/apps/payments/views/subscription_views.py +0 -135
  246. django_cfg/apps/payments/views/tariff_views.py +0 -131
  247. django_cfg/apps/payments/views/templates/__init__.py +0 -25
  248. django_cfg/apps/payments/views/templates/ajax.py +0 -451
  249. django_cfg/apps/payments/views/templates/base.py +0 -212
  250. django_cfg/apps/payments/views/templates/dashboard.py +0 -60
  251. django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
  252. django_cfg/apps/payments/views/templates/payment_management.py +0 -158
  253. django_cfg/apps/payments/views/templates/qr_code.py +0 -174
  254. django_cfg/apps/payments/views/templates/stats.py +0 -244
  255. django_cfg/apps/payments/views/templates/utils.py +0 -181
  256. django_cfg/apps/payments/views/webhook_views.py +0 -266
  257. django_cfg/apps/payments/viewsets.py +0 -66
  258. django_cfg/core/integration.py +0 -160
  259. django_cfg/template_archive/.gitignore +0 -1
  260. django_cfg/template_archive/__init__.py +0 -0
  261. django_cfg/urls.py +0 -33
  262. {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/WHEEL +0 -0
  263. {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/entry_points.txt +0 -0
  264. {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,192 +0,0 @@
1
- """
2
- Enhanced Payment manager for UniversalPayment model with query optimizations.
3
- """
4
-
5
- from django.db import models
6
- from django.utils import timezone
7
- from datetime import timedelta
8
- from django_cfg.modules.django_logger import get_logger
9
-
10
- logger = get_logger("payment_manager")
11
-
12
-
13
- class PaymentQuerySet(models.QuerySet):
14
- """Custom QuerySet for UniversalPayment with optimizations."""
15
-
16
- def with_user(self):
17
- """Select related user to prevent N+1 queries."""
18
- return self.select_related('user')
19
-
20
- def with_events(self):
21
- """Skip prefetch for events since they use CharField payment_id, not ForeignKey."""
22
- # PaymentEvent uses CharField payment_id, not ForeignKey, so no reverse relation exists
23
- # Events should be fetched separately when needed
24
- return self
25
-
26
- def optimized(self):
27
- """Get optimized queryset for admin and API views."""
28
- return self.select_related('user').with_events()
29
-
30
- def active(self):
31
- """Get active payments (not failed, cancelled, or refunded)."""
32
- return self.exclude(
33
- status__in=['failed', 'cancelled', 'refunded', 'expired']
34
- )
35
-
36
- def completed(self):
37
- """Get only completed payments."""
38
- return self.filter(status='completed')
39
-
40
- def pending(self):
41
- """Get pending payments."""
42
- return self.filter(status='pending')
43
-
44
- def by_provider(self, provider):
45
- """Filter by payment provider."""
46
- return self.filter(provider=provider)
47
-
48
- def recent(self, days=30):
49
- """Get payments from last N days."""
50
- cutoff_date = timezone.now() - timedelta(days=days)
51
- return self.filter(created_at__gte=cutoff_date)
52
-
53
- def by_amount_range(self, min_amount=None, max_amount=None):
54
- """Filter by USD amount range."""
55
- queryset = self
56
- if min_amount is not None:
57
- queryset = queryset.filter(amount_usd__gte=min_amount)
58
- if max_amount is not None:
59
- queryset = queryset.filter(amount_usd__lte=max_amount)
60
- return queryset
61
-
62
- def by_user(self, user):
63
- """Filter by user."""
64
- return self.filter(user=user)
65
-
66
- def expired(self):
67
- """Get expired payments."""
68
- return self.filter(
69
- expires_at__lt=timezone.now(),
70
- status__in=['pending', 'confirming']
71
- )
72
-
73
-
74
- class UniversalPaymentManager(models.Manager):
75
- """Enhanced manager for UniversalPayment with optimization methods."""
76
-
77
- def get_queryset(self):
78
- """Return custom QuerySet."""
79
- return PaymentQuerySet(self.model, using=self._db)
80
-
81
- def with_user(self):
82
- """Get payments with user data preloaded."""
83
- return self.get_queryset().with_user()
84
-
85
- def optimized(self):
86
- """Get optimized queryset for admin views."""
87
- return self.get_queryset().optimized()
88
-
89
- def active(self):
90
- """Get active payments."""
91
- return self.get_queryset().active()
92
-
93
- def completed(self):
94
- """Get completed payments."""
95
- return self.get_queryset().completed()
96
-
97
- def pending(self):
98
- """Get pending payments."""
99
- return self.get_queryset().pending()
100
-
101
- def recent(self, days=30):
102
- """Get recent payments."""
103
- return self.get_queryset().recent(days)
104
-
105
- def by_provider(self, provider):
106
- """Get payments by provider."""
107
- return self.get_queryset().by_provider(provider)
108
-
109
- def create_payment(self, user, amount_usd: float, currency_code: str, provider: str, **kwargs):
110
- """Create a payment with automatic field generation."""
111
- from uuid import uuid4
112
-
113
- # Generate unique internal payment ID if not provided
114
- internal_payment_id = kwargs.pop('internal_payment_id', f"PAY_{uuid4().hex[:8].upper()}")
115
-
116
- payment = self.create(
117
- user=user,
118
- internal_payment_id=internal_payment_id,
119
- amount_usd=amount_usd,
120
- currency_code=currency_code.upper(),
121
- provider=provider,
122
- status=self.model.PaymentStatus.PENDING,
123
- **kwargs
124
- )
125
-
126
- return payment
127
-
128
- def get_pending_payments(self, user=None):
129
- """Get pending payments for user or all users."""
130
- queryset = self.pending()
131
- if user:
132
- queryset = queryset.by_user(user)
133
- return queryset.with_user()
134
-
135
- def get_completed_payments(self, user=None):
136
- """Get completed payments for user or all users."""
137
- queryset = self.completed()
138
- if user:
139
- queryset = queryset.by_user(user)
140
- return queryset.with_user()
141
-
142
- def get_failed_payments(self, user=None):
143
- """Get failed/expired payments for user or all users."""
144
- queryset = self.filter(status__in=[
145
- self.model.PaymentStatus.FAILED,
146
- self.model.PaymentStatus.EXPIRED
147
- ])
148
- if user:
149
- queryset = queryset.by_user(user)
150
- return queryset.with_user()
151
-
152
- def get_user_stats(self, user):
153
- """Get payment statistics for a user."""
154
- user_payments = self.by_user(user)
155
-
156
- return {
157
- 'total_payments': user_payments.count(),
158
- 'completed_payments': user_payments.completed().count(),
159
- 'pending_payments': user_payments.pending().count(),
160
- 'failed_payments': user_payments.filter(status='failed').count(),
161
- 'total_amount_usd': user_payments.completed().aggregate(
162
- total=models.Sum('amount_usd')
163
- )['total'] or 0,
164
- 'recent_payments_30d': user_payments.recent(30).count(),
165
- }
166
-
167
- def get_provider_stats(self, provider=None):
168
- """Get payment statistics by provider."""
169
- if provider:
170
- payments = self.by_provider(provider)
171
- else:
172
- payments = self.all()
173
-
174
- return {
175
- 'total_payments': payments.count(),
176
- 'completed_payments': payments.completed().count(),
177
- 'pending_payments': payments.pending().count(),
178
- 'success_rate': (
179
- payments.completed().count() / max(payments.count(), 1) * 100
180
- ),
181
- 'total_volume_usd': payments.completed().aggregate(
182
- total=models.Sum('amount_usd')
183
- )['total'] or 0,
184
- }
185
-
186
- def mark_expired_payments(self):
187
- """Mark expired payments as expired."""
188
- expired_count = self.expired().update(
189
- status=self.model.PaymentStatus.EXPIRED,
190
- updated_at=timezone.now()
191
- )
192
- return expired_count
@@ -1,37 +0,0 @@
1
- """
2
- Subscription managers.
3
- """
4
-
5
- from django.db import models
6
- from django.utils import timezone
7
-
8
-
9
- class SubscriptionManager(models.Manager):
10
- """Manager for Subscription model."""
11
-
12
- def get_active_subscriptions(self, user=None):
13
- """Get active subscriptions."""
14
- queryset = self.filter(
15
- status='active',
16
- expires_at__gt=timezone.now()
17
- )
18
- if user:
19
- queryset = queryset.filter(user=user)
20
- return queryset
21
-
22
- def get_expired_subscriptions(self, user=None):
23
- """Get expired subscriptions."""
24
- queryset = self.filter(
25
- expires_at__lte=timezone.now()
26
- )
27
- if user:
28
- queryset = queryset.filter(user=user)
29
- return queryset
30
-
31
-
32
- class EndpointGroupManager(models.Manager):
33
- """Manager for EndpointGroup model."""
34
-
35
- def get_active_groups(self):
36
- """Get active endpoint groups."""
37
- return self.filter(is_active=True)
@@ -1,29 +0,0 @@
1
- """
2
- Tariff managers.
3
- """
4
-
5
- from django.db import models
6
-
7
-
8
- class TariffManager(models.Manager):
9
- """Manager for Tariff model."""
10
-
11
- def get_active_tariffs(self):
12
- """Get active tariffs."""
13
- return self.filter(is_active=True).order_by('monthly_price')
14
-
15
- def get_free_tariffs(self):
16
- """Get free tariffs."""
17
- return self.filter(monthly_price=0, is_active=True)
18
-
19
- def get_paid_tariffs(self):
20
- """Get paid tariffs."""
21
- return self.filter(monthly_price__gt=0, is_active=True)
22
-
23
-
24
- class TariffEndpointGroupManager(models.Manager):
25
- """Manager for TariffEndpointGroup model."""
26
-
27
- def get_enabled_for_tariff(self, tariff):
28
- """Get enabled endpoint groups for tariff."""
29
- return self.filter(tariff=tariff, is_enabled=True)
@@ -1,241 +0,0 @@
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
- ]
@@ -1,30 +0,0 @@
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
- ]
@@ -1,73 +0,0 @@
1
- """
2
- Event sourcing models for the universal payments system.
3
- """
4
-
5
- from django.db import models
6
- from .base import UUIDTimestampedModel
7
-
8
-
9
- class PaymentEvent(UUIDTimestampedModel):
10
- """Event sourcing for payment operations - immutable audit trail."""
11
-
12
- class EventType(models.TextChoices):
13
- PAYMENT_CREATED = 'payment_created', 'Payment Created'
14
- WEBHOOK_RECEIVED = 'webhook_received', 'Webhook Received'
15
- WEBHOOK_PROCESSED = 'webhook_processed', 'Webhook Processed'
16
- BALANCE_UPDATED = 'balance_updated', 'Balance Updated'
17
- REFUND_PROCESSED = 'refund_processed', 'Refund Processed'
18
- STATUS_CHANGED = 'status_changed', 'Status Changed'
19
- ERROR_OCCURRED = 'error_occurred', 'Error Occurred'
20
-
21
- # Event identification
22
- payment_id = models.CharField(
23
- max_length=255,
24
- db_index=True,
25
- help_text="Payment identifier"
26
- )
27
- event_type = models.CharField(
28
- max_length=50,
29
- choices=EventType.choices,
30
- db_index=True,
31
- help_text="Type of event"
32
- )
33
- sequence_number = models.PositiveBigIntegerField(
34
- help_text="Sequential number per payment"
35
- )
36
-
37
- # Event data (JSON for flexibility)
38
- event_data = models.JSONField(
39
- help_text="Event data payload"
40
- )
41
-
42
- # Operational metadata
43
- processed_by = models.CharField(
44
- max_length=100,
45
- help_text="Worker/server that processed this event"
46
- )
47
- correlation_id = models.CharField(
48
- max_length=255,
49
- null=True,
50
- blank=True,
51
- help_text="Correlation ID for tracing"
52
- )
53
- idempotency_key = models.CharField(
54
- max_length=255,
55
- unique=True,
56
- help_text="Idempotency key to prevent duplicates"
57
- )
58
-
59
- class Meta:
60
- db_table = 'payment_events'
61
- verbose_name = "Payment Event"
62
- verbose_name_plural = "Payment Events"
63
- indexes = [
64
- models.Index(fields=['payment_id', 'sequence_number']),
65
- models.Index(fields=['event_type', 'created_at']),
66
- models.Index(fields=['idempotency_key']),
67
- models.Index(fields=['correlation_id']),
68
- models.Index(fields=['created_at']),
69
- ]
70
- ordering = ['sequence_number']
71
-
72
- def __str__(self):
73
- return f"Event {self.sequence_number}: {self.event_type} for {self.payment_id}"
@@ -1,57 +0,0 @@
1
- """
2
- DRF serializers for the universal payments system.
3
- """
4
-
5
- from .balance import (
6
- UserBalanceSerializer, TransactionSerializer, TransactionListSerializer
7
- )
8
- from .payments import (
9
- UniversalPaymentSerializer, PaymentCreateSerializer, PaymentListSerializer
10
- )
11
- from .subscriptions import (
12
- SubscriptionSerializer, SubscriptionCreateSerializer, SubscriptionListSerializer,
13
- EndpointGroupSerializer
14
- )
15
- from .api_keys import (
16
- APIKeySerializer, APIKeyCreateSerializer, APIKeyListSerializer
17
- )
18
- from .currencies import (
19
- CurrencySerializer, NetworkSerializer, ProviderCurrencySerializer, CurrencyListSerializer
20
- )
21
- from .tariffs import (
22
- TariffSerializer, TariffEndpointGroupSerializer, TariffListSerializer
23
- )
24
-
25
- __all__ = [
26
- # Balance
27
- 'UserBalanceSerializer',
28
- 'TransactionSerializer',
29
- 'TransactionListSerializer',
30
-
31
- # Payments
32
- 'UniversalPaymentSerializer',
33
- 'PaymentCreateSerializer',
34
- 'PaymentListSerializer',
35
-
36
- # Subscriptions
37
- 'SubscriptionSerializer',
38
- 'SubscriptionCreateSerializer',
39
- 'SubscriptionListSerializer',
40
- 'EndpointGroupSerializer',
41
-
42
- # API Keys
43
- 'APIKeySerializer',
44
- 'APIKeyCreateSerializer',
45
- 'APIKeyListSerializer',
46
-
47
- # Currencies
48
- 'CurrencySerializer',
49
- 'NetworkSerializer',
50
- 'ProviderCurrencySerializer',
51
- 'CurrencyListSerializer',
52
-
53
- # Tariffs
54
- 'TariffSerializer',
55
- 'TariffEndpointGroupSerializer',
56
- 'TariffListSerializer',
57
- ]