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,51 +0,0 @@
1
- """
2
- API key serializers.
3
- """
4
-
5
- from rest_framework import serializers
6
- from ..models import APIKey
7
-
8
-
9
- class APIKeySerializer(serializers.ModelSerializer):
10
- """API key with usage stats."""
11
-
12
- is_valid = serializers.SerializerMethodField()
13
-
14
- class Meta:
15
- model = APIKey
16
- fields = [
17
- 'id', 'name', 'key_value', 'key_prefix', 'usage_count',
18
- 'is_active', 'is_valid', 'last_used', 'expires_at',
19
- 'created_at'
20
- ]
21
- read_only_fields = ['key_value', 'key_prefix', 'usage_count', 'last_used', 'created_at']
22
-
23
- def get_is_valid(self, obj):
24
- """Get validation status."""
25
- return obj.is_valid()
26
-
27
-
28
- class APIKeyCreateSerializer(serializers.ModelSerializer):
29
- """Create API key."""
30
-
31
- class Meta:
32
- model = APIKey
33
- fields = ['name', 'expires_at']
34
-
35
-
36
- class APIKeyListSerializer(serializers.ModelSerializer):
37
- """Simplified API key for lists."""
38
-
39
- is_valid = serializers.SerializerMethodField()
40
-
41
- class Meta:
42
- model = APIKey
43
- fields = [
44
- 'id', 'name', 'key_prefix', 'usage_count', 'is_active', 'is_valid',
45
- 'last_used', 'expires_at', 'created_at'
46
- ]
47
- read_only_fields = ['key_prefix', 'usage_count', 'last_used', 'created_at']
48
-
49
- def get_is_valid(self, obj):
50
- """Get validation status."""
51
- return obj.is_valid()
@@ -1,59 +0,0 @@
1
- """
2
- Balance serializers.
3
- """
4
-
5
- from rest_framework import serializers
6
- from ..models import UserBalance, Transaction
7
-
8
-
9
- class UserBalanceSerializer(serializers.ModelSerializer):
10
- """User balance with computed fields."""
11
-
12
- total_balance = serializers.ReadOnlyField()
13
- pending_payments_count = serializers.SerializerMethodField()
14
-
15
- class Meta:
16
- model = UserBalance
17
- fields = [
18
- 'amount_usd', 'reserved_usd', 'total_balance',
19
- 'total_earned', 'total_spent', 'last_transaction_at',
20
- 'pending_payments_count', 'created_at', 'updated_at'
21
- ]
22
- read_only_fields = [
23
- 'total_earned', 'total_spent', 'last_transaction_at',
24
- 'created_at', 'updated_at'
25
- ]
26
-
27
- def get_pending_payments_count(self, obj):
28
- """Get count of pending payments."""
29
- return obj.user.universal_payments.filter(status='pending').count()
30
-
31
-
32
- class TransactionSerializer(serializers.ModelSerializer):
33
- """Transaction with details."""
34
-
35
- transaction_type_display = serializers.CharField(source='get_transaction_type_display', read_only=True)
36
- is_credit = serializers.ReadOnlyField()
37
- is_debit = serializers.ReadOnlyField()
38
-
39
- class Meta:
40
- model = Transaction
41
- fields = [
42
- 'id', 'amount_usd', 'transaction_type', 'transaction_type_display',
43
- 'description', 'balance_before', 'balance_after',
44
- 'is_credit', 'is_debit', 'reference_id', 'created_at'
45
- ]
46
- read_only_fields = ['id', 'balance_before', 'balance_after', 'created_at']
47
-
48
-
49
- class TransactionListSerializer(serializers.ModelSerializer):
50
- """Simplified transaction for lists."""
51
-
52
- transaction_type_display = serializers.CharField(source='get_transaction_type_display', read_only=True)
53
-
54
- class Meta:
55
- model = Transaction
56
- fields = [
57
- 'id', 'amount_usd', 'transaction_type', 'transaction_type_display',
58
- 'description', 'balance_after', 'created_at'
59
- ]
@@ -1,63 +0,0 @@
1
- """
2
- Currency serializers.
3
- """
4
-
5
- from rest_framework import serializers
6
- from ..models import Currency, Network, ProviderCurrency
7
-
8
-
9
- class CurrencySerializer(serializers.ModelSerializer):
10
- """Currency with type info."""
11
-
12
- currency_type_display = serializers.CharField(source='get_currency_type_display', read_only=True)
13
- is_crypto = serializers.SerializerMethodField()
14
- is_fiat = serializers.SerializerMethodField()
15
-
16
- class Meta:
17
- model = Currency
18
- fields = [
19
- 'id', 'code', 'name', 'currency_type', 'currency_type_display',
20
- 'is_crypto', 'is_fiat', 'usd_rate', 'rate_updated_at'
21
- ]
22
- read_only_fields = ['rate_updated_at']
23
-
24
- def get_is_crypto(self, obj):
25
- """Check if currency is crypto."""
26
- return obj.is_crypto
27
-
28
- def get_is_fiat(self, obj):
29
- """Check if currency is fiat."""
30
- return obj.is_fiat
31
-
32
-
33
- class NetworkSerializer(serializers.ModelSerializer):
34
- """Network information."""
35
-
36
- class Meta:
37
- model = Network
38
- fields = ['id', 'code', 'name']
39
-
40
-
41
- class ProviderCurrencySerializer(serializers.ModelSerializer):
42
- """Provider currency with base currency and network info."""
43
-
44
- base_currency = CurrencySerializer(read_only=True)
45
- network = NetworkSerializer(read_only=True)
46
-
47
- class Meta:
48
- model = ProviderCurrency
49
- fields = [
50
- 'id', 'provider_name', 'provider_currency_code', 'base_currency', 'network',
51
- 'is_enabled', 'available_for_payment', 'available_for_payout',
52
- 'is_popular', 'is_stable', 'min_amount', 'max_amount', 'logo_url'
53
- ]
54
-
55
-
56
- class CurrencyListSerializer(serializers.ModelSerializer):
57
- """Simplified currency for lists."""
58
-
59
- currency_type_display = serializers.CharField(source='get_currency_type_display', read_only=True)
60
-
61
- class Meta:
62
- model = Currency
63
- fields = ['id', 'code', 'name', 'currency_type', 'currency_type_display']
@@ -1,62 +0,0 @@
1
- """
2
- Payment serializers.
3
- """
4
-
5
- from rest_framework import serializers
6
- from ..models import UniversalPayment
7
-
8
-
9
- class UniversalPaymentSerializer(serializers.ModelSerializer):
10
- """Universal payment with status info."""
11
-
12
- status_display = serializers.CharField(source='get_status_display', read_only=True)
13
- provider_display = serializers.CharField(source='get_provider_display', read_only=True)
14
- is_pending = serializers.ReadOnlyField()
15
- is_completed = serializers.ReadOnlyField()
16
- is_failed = serializers.ReadOnlyField()
17
-
18
- class Meta:
19
- model = UniversalPayment
20
- fields = [
21
- 'id', 'internal_payment_id', 'provider_payment_id', 'order_id',
22
- 'amount_usd', 'currency_code', 'actual_amount_usd', 'actual_currency_code',
23
- 'fee_amount_usd', 'provider', 'provider_display', 'status', 'status_display',
24
- 'pay_address', 'pay_amount', 'network', 'description',
25
- 'is_pending', 'is_completed', 'is_failed',
26
- 'expires_at', 'completed_at', 'created_at', 'updated_at'
27
- ]
28
- read_only_fields = [
29
- 'id', 'internal_payment_id', 'provider_payment_id',
30
- 'actual_amount_usd', 'actual_currency_code', 'fee_amount_usd',
31
- 'pay_address', 'pay_amount', 'completed_at', 'processed_at',
32
- 'created_at', 'updated_at'
33
- ]
34
-
35
-
36
- class PaymentCreateSerializer(serializers.ModelSerializer):
37
- """Create payment request."""
38
-
39
- class Meta:
40
- model = UniversalPayment
41
- fields = [
42
- 'amount_usd', 'currency_code', 'provider', 'description', 'order_id'
43
- ]
44
-
45
- def validate_amount_usd(self, value):
46
- """Validate payment amount."""
47
- if value < 1.0:
48
- raise serializers.ValidationError("Minimum payment amount is $1.00")
49
- return value
50
-
51
-
52
- class PaymentListSerializer(serializers.ModelSerializer):
53
- """Simplified payment for lists."""
54
-
55
- status_display = serializers.CharField(source='get_status_display', read_only=True)
56
-
57
- class Meta:
58
- model = UniversalPayment
59
- fields = [
60
- 'id', 'internal_payment_id', 'amount_usd', 'currency_code',
61
- 'provider', 'status', 'status_display', 'description', 'created_at'
62
- ]
@@ -1,71 +0,0 @@
1
- """
2
- Subscription serializers.
3
- """
4
-
5
- from rest_framework import serializers
6
- from ..models import Subscription, EndpointGroup
7
-
8
-
9
- class EndpointGroupSerializer(serializers.ModelSerializer):
10
- """Endpoint group with pricing tiers."""
11
-
12
- class Meta:
13
- model = EndpointGroup
14
- fields = [
15
- 'id', 'name', 'display_name', 'description',
16
- 'basic_price', 'premium_price', 'enterprise_price',
17
- 'basic_limit', 'premium_limit', 'enterprise_limit',
18
- 'is_active', 'require_api_key'
19
- ]
20
-
21
-
22
- class SubscriptionSerializer(serializers.ModelSerializer):
23
- """Subscription with computed fields."""
24
-
25
- endpoint_group_name = serializers.CharField(source='endpoint_group.name', read_only=True)
26
- endpoint_group_display = serializers.CharField(source='endpoint_group.display_name', read_only=True)
27
- status_display = serializers.CharField(source='get_status_display', read_only=True)
28
- tier_display = serializers.CharField(source='get_tier_display', read_only=True)
29
- is_active_subscription = serializers.ReadOnlyField(source='is_active')
30
- is_usage_exceeded = serializers.ReadOnlyField()
31
-
32
- class Meta:
33
- model = Subscription
34
- fields = [
35
- 'id', 'endpoint_group', 'endpoint_group_name', 'endpoint_group_display',
36
- 'tier', 'tier_display', 'status', 'status_display', 'monthly_price',
37
- 'usage_limit', 'usage_current', 'is_active_subscription', 'is_usage_exceeded',
38
- 'last_billed', 'next_billing', 'expires_at', 'created_at'
39
- ]
40
- read_only_fields = [
41
- 'usage_current', 'last_billed', 'next_billing', 'cancelled_at', 'created_at'
42
- ]
43
-
44
-
45
- class SubscriptionCreateSerializer(serializers.Serializer):
46
- """Create subscription request."""
47
-
48
- endpoint_group_id = serializers.IntegerField()
49
- tier = serializers.ChoiceField(choices=Subscription.SubscriptionTier.choices)
50
-
51
- def validate_endpoint_group_id(self, value):
52
- """Validate endpoint group exists."""
53
- try:
54
- endpoint_group = EndpointGroup.objects.get(id=value, is_active=True)
55
- return value
56
- except EndpointGroup.DoesNotExist:
57
- raise serializers.ValidationError("Endpoint group not found or inactive")
58
-
59
-
60
- class SubscriptionListSerializer(serializers.ModelSerializer):
61
- """Simplified subscription for lists."""
62
-
63
- endpoint_group_name = serializers.CharField(source='endpoint_group.name', read_only=True)
64
- status_display = serializers.CharField(source='get_status_display', read_only=True)
65
-
66
- class Meta:
67
- model = Subscription
68
- fields = [
69
- 'id', 'endpoint_group_name', 'tier', 'status', 'status_display',
70
- 'monthly_price', 'usage_current', 'usage_limit', 'expires_at'
71
- ]
@@ -1,56 +0,0 @@
1
- """
2
- Tariff serializers.
3
- """
4
-
5
- from rest_framework import serializers
6
- from ..models import Tariff, TariffEndpointGroup
7
-
8
-
9
- class TariffSerializer(serializers.ModelSerializer):
10
- """Tariff with pricing info."""
11
-
12
- is_free = serializers.SerializerMethodField()
13
- endpoint_groups_count = serializers.SerializerMethodField()
14
-
15
- class Meta:
16
- model = Tariff
17
- fields = [
18
- 'id', 'name', 'display_name', 'description', 'monthly_price',
19
- 'request_limit', 'is_free', 'is_active', 'endpoint_groups_count'
20
- ]
21
-
22
- def get_is_free(self, obj):
23
- """Check if tariff is free."""
24
- return obj.is_free
25
-
26
- def get_endpoint_groups_count(self, obj):
27
- """Get count of enabled endpoint groups."""
28
- return obj.endpoint_groups.filter(is_enabled=True).count()
29
-
30
-
31
- class TariffEndpointGroupSerializer(serializers.ModelSerializer):
32
- """Tariff endpoint group association."""
33
-
34
- tariff_name = serializers.CharField(source='tariff.name', read_only=True)
35
- endpoint_group_name = serializers.CharField(source='endpoint_group.name', read_only=True)
36
-
37
- class Meta:
38
- model = TariffEndpointGroup
39
- fields = [
40
- 'id', 'tariff', 'tariff_name', 'endpoint_group', 'endpoint_group_name',
41
- 'is_enabled'
42
- ]
43
-
44
-
45
- class TariffListSerializer(serializers.ModelSerializer):
46
- """Simplified tariff for lists."""
47
-
48
- is_free = serializers.SerializerMethodField()
49
-
50
- class Meta:
51
- model = Tariff
52
- fields = ['id', 'name', 'display_name', 'monthly_price', 'is_free', 'is_active']
53
-
54
- def get_is_free(self, obj):
55
- """Check if tariff is free."""
56
- return obj.is_free
@@ -1,8 +0,0 @@
1
- """
2
- Billing services for payments module.
3
-
4
- TODO: Implement billing services when needed.
5
- """
6
-
7
- # Placeholder for future billing services
8
- __all__ = []
@@ -1,135 +0,0 @@
1
- """
2
- Simple cache implementation for API keys and rate limiting.
3
- ONLY for API access control - NOT payment data!
4
- """
5
-
6
- from django_cfg.modules.django_logger import get_logger
7
- from typing import Optional, Any
8
- from django.core.cache import cache
9
-
10
- from .base import CacheInterface
11
- from ...utils.config_utils import CacheConfigHelper
12
-
13
- logger = get_logger("simple_cache")
14
-
15
-
16
- class SimpleCache(CacheInterface):
17
- """
18
- Simple cache implementation using Django's cache framework.
19
-
20
- Falls back gracefully when cache is unavailable.
21
- """
22
-
23
- def __init__(self, prefix: str = "payments"):
24
- self.prefix = prefix
25
- # Use config helper to check if cache is enabled
26
- self.enabled = CacheConfigHelper.is_cache_enabled()
27
-
28
- def _make_key(self, key: str) -> str:
29
- """Create prefixed cache key."""
30
- return f"{self.prefix}:{key}"
31
-
32
- def get(self, key: str) -> Optional[Any]:
33
- """Get value from cache."""
34
- if not self.enabled:
35
- return None
36
-
37
- try:
38
- cache_key = self._make_key(key)
39
- return cache.get(cache_key)
40
- except Exception as e:
41
- logger.warning(f"Cache get failed for key {key}: {e}")
42
- return None
43
-
44
- def set(self, key: str, value: Any, timeout: Optional[int] = None) -> bool:
45
- """Set value in cache."""
46
- if not self.enabled:
47
- return False
48
-
49
- try:
50
- cache_key = self._make_key(key)
51
- cache.set(cache_key, value, timeout)
52
- return True
53
- except Exception as e:
54
- logger.warning(f"Cache set failed for key {key}: {e}")
55
- return False
56
-
57
- def delete(self, key: str) -> bool:
58
- """Delete value from cache."""
59
- if not self.enabled:
60
- return False
61
-
62
- try:
63
- cache_key = self._make_key(key)
64
- cache.delete(cache_key)
65
- return True
66
- except Exception as e:
67
- logger.warning(f"Cache delete failed for key {key}: {e}")
68
- return False
69
-
70
- def exists(self, key: str) -> bool:
71
- """Check if key exists in cache."""
72
- if not self.enabled:
73
- return False
74
-
75
- try:
76
- cache_key = self._make_key(key)
77
- return cache.get(cache_key) is not None
78
- except Exception as e:
79
- logger.warning(f"Cache exists check failed for key {key}: {e}")
80
- return False
81
-
82
-
83
- class ApiKeyCache:
84
- """Specialized cache for API key operations."""
85
-
86
- def __init__(self):
87
- self.cache = SimpleCache("api_keys")
88
- # Get timeout from config
89
- self.default_timeout = CacheConfigHelper.get_cache_timeout('api_key')
90
-
91
- def get_api_key_data(self, api_key: str) -> Optional[dict]:
92
- """Get cached API key data."""
93
- return self.cache.get(f"key:{api_key}")
94
-
95
- def cache_api_key_data(self, api_key: str, data: dict) -> bool:
96
- """Cache API key data."""
97
- return self.cache.set(f"key:{api_key}", data, self.default_timeout)
98
-
99
- def invalidate_api_key(self, api_key: str) -> bool:
100
- """Invalidate cached API key."""
101
- return self.cache.delete(f"key:{api_key}")
102
-
103
-
104
- class RateLimitCache:
105
- """Specialized cache for rate limiting."""
106
-
107
- def __init__(self):
108
- self.cache = SimpleCache("rate_limit")
109
-
110
- def get_usage_count(self, user_id: int, endpoint_group: str, window: str = "hour") -> int:
111
- """Get current usage count for rate limiting."""
112
- key = f"usage:{user_id}:{endpoint_group}:{window}"
113
- count = self.cache.get(key)
114
- return count if count is not None else 0
115
-
116
- def increment_usage(self, user_id: int, endpoint_group: str, window: str = "hour", ttl: Optional[int] = None) -> int:
117
- """Increment usage count and return new count."""
118
- key = f"usage:{user_id}:{endpoint_group}:{window}"
119
-
120
- # Get current count
121
- current = self.get_usage_count(user_id, endpoint_group, window)
122
- new_count = current + 1
123
-
124
- # Use config helper for TTL if not provided
125
- if ttl is None:
126
- ttl = CacheConfigHelper.get_cache_timeout('rate_limit')
127
-
128
- # Set new count with TTL
129
- self.cache.set(key, new_count, ttl)
130
- return new_count
131
-
132
- def reset_usage(self, user_id: int, endpoint_group: str, window: str = "hour") -> bool:
133
- """Reset usage count."""
134
- key = f"usage:{user_id}:{endpoint_group}:{window}"
135
- return self.cache.delete(key)