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,461 +0,0 @@
1
- """
2
- Internal Service Types - ONLY for inter-service communication.
3
-
4
- DO NOT duplicate Django ORM or DRF! Only for:
5
- 1. Providers -> Services (external API response validation)
6
- 2. Service -> Service (internal operations)
7
- 3. Configuration (settings and parameters)
8
- """
9
-
10
- from pydantic import BaseModel, Field, ConfigDict, computed_field
11
- from decimal import Decimal
12
- from datetime import datetime
13
- from typing import Optional, Dict, Any, List
14
- from enum import Enum
15
- from django_cfg.modules.django_logger import get_logger
16
-
17
- logger = get_logger("internal_types")
18
-
19
-
20
-
21
-
22
- # =============================================================================
23
- # UNIVERSAL CURRENCY MODEL - for provider → base communication
24
- # =============================================================================
25
-
26
- class UniversalCurrency(BaseModel):
27
- """Universal currency model that all providers should return."""
28
- model_config = ConfigDict(validate_assignment=True, extra="allow")
29
-
30
- # Core identification
31
- provider_currency_code: str = Field(..., description="Original provider code: USDTERC20, USDTBSC, BTC")
32
- base_currency_code: str = Field(..., description="Parsed base currency: USDT, BTC")
33
- network_code: Optional[str] = Field(None, description="Parsed network: ethereum, bsc, bitcoin")
34
-
35
- # Display info
36
- name: str = Field(..., description="Human readable name")
37
- currency_type: str = Field(default="crypto", description="fiat or crypto")
38
-
39
- # Provider flags
40
- is_enabled: bool = Field(default=True, description="Available for use")
41
- is_popular: bool = Field(default=False, description="Popular currency")
42
- is_stable: bool = Field(default=False, description="Stablecoin")
43
- priority: int = Field(default=0, description="Display priority")
44
-
45
- # URLs and assets
46
- logo_url: str = Field(default="", description="Logo URL")
47
-
48
- # Limits and availability
49
- available_for_payment: bool = Field(default=True, description="Can receive payments")
50
- available_for_payout: bool = Field(default=True, description="Can send payouts")
51
- min_amount: Optional[float] = Field(None, description="Minimum amount")
52
- max_amount: Optional[float] = Field(None, description="Maximum amount")
53
-
54
- # Raw provider data
55
- raw_data: Dict[str, Any] = Field(default_factory=dict, description="Original provider response")
56
-
57
-
58
- class UniversalCurrenciesResponse(BaseModel):
59
- """Universal response with parsed currencies."""
60
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
61
-
62
- currencies: List[UniversalCurrency] = Field(..., description="Parsed currencies")
63
-
64
-
65
- # =============================================================================
66
- # SYNCHRONIZATION RESULTS - Typed sync operation results
67
- # =============================================================================
68
-
69
- class ProviderSyncResult(BaseModel):
70
- """Result of provider synchronization operation."""
71
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
72
-
73
- # Currencies operations
74
- currencies_created: int = Field(default=0, description="Number of new currencies created")
75
- currencies_updated: int = Field(default=0, description="Number of existing currencies updated")
76
-
77
- # Networks operations
78
- networks_created: int = Field(default=0, description="Number of new networks created")
79
- networks_updated: int = Field(default=0, description="Number of existing networks updated")
80
-
81
- # Provider currencies operations
82
- provider_currencies_created: int = Field(default=0, description="Number of new provider currencies created")
83
- provider_currencies_updated: int = Field(default=0, description="Number of existing provider currencies updated")
84
-
85
- # Error tracking
86
- errors: List[str] = Field(default_factory=list, description="List of errors encountered during sync")
87
-
88
- @property
89
- def total_items_processed(self) -> int:
90
- """Get total number of items processed."""
91
- return (
92
- self.currencies_created + self.currencies_updated +
93
- self.networks_created + self.networks_updated +
94
- self.provider_currencies_created + self.provider_currencies_updated
95
- )
96
-
97
- @property
98
- def success(self) -> bool:
99
- """Check if sync completed without errors."""
100
- return len(self.errors) == 0
101
-
102
- @property
103
- def has_changes(self) -> bool:
104
- """Check if any changes were made."""
105
- return self.total_items_processed > 0
106
-
107
-
108
- # AJAX Response Types
109
- class CurrencyOptionModel(BaseModel):
110
- """Single currency option for UI select dropdown."""
111
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
112
-
113
- provider_currency_code: str = Field(..., description="Provider-specific currency code")
114
- display_name: str = Field(..., description="Human-readable display name")
115
- base_currency_code: str = Field(..., description="Normalized base currency code")
116
- base_currency_name: str = Field(..., description="Base currency full name")
117
- network_code: Optional[str] = Field(None, description="Network code if applicable")
118
- network_name: Optional[str] = Field(None, description="Network full name if applicable")
119
- currency_type: str = Field(..., description="Currency type: crypto or fiat")
120
- is_popular: bool = Field(default=False, description="Is this a popular currency")
121
- is_stable: bool = Field(default=False, description="Is this a stablecoin")
122
- available_for_payment: bool = Field(default=True, description="Available for payments")
123
- available_for_payout: bool = Field(default=True, description="Available for payouts")
124
- min_amount: Optional[str] = Field(None, description="Minimum amount as string")
125
- max_amount: Optional[str] = Field(None, description="Maximum amount as string")
126
- logo_url: Optional[str] = Field(None, description="Currency logo URL")
127
- # Exchange rates
128
- usd_rate: float = Field(default=0.0, description="1 CURRENCY = X USD")
129
- tokens_per_usd: float = Field(default=0.0, description="How many tokens for 1 USD")
130
-
131
-
132
- class ProviderCurrencyOptionsResponse(BaseModel):
133
- """Response for provider currency options API."""
134
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
135
-
136
- success: bool = Field(..., description="API call success status")
137
- provider: str = Field(..., description="Provider name")
138
- currency_options: List[CurrencyOptionModel] = Field(default_factory=list, description="Available currency options")
139
- count: int = Field(..., description="Number of currency options")
140
- error: Optional[str] = Field(None, description="Error message if any")
141
-
142
-
143
- # =============================================================================
144
- # PROVIDERS - External API response validation
145
- # =============================================================================
146
-
147
- class ProviderResponse(BaseModel):
148
- """Validation for any provider response"""
149
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
150
-
151
- success: bool
152
- provider_payment_id: Optional[str] = None
153
- payment_url: Optional[str] = None
154
- pay_amount: Optional[Decimal] = None
155
- pay_currency: Optional[str] = None
156
- pay_address: Optional[str] = None
157
- status: Optional[str] = None
158
- error_message: Optional[str] = None
159
- data: Dict[str, Any] = Field(default_factory=dict)
160
-
161
- # Legacy fields for backward compatibility with tests
162
- amount: Optional[Decimal] = None
163
- currency: Optional[str] = None
164
- payment_id: Optional[str] = None
165
- payment_status: Optional[str] = None
166
- currency_code: Optional[str] = None
167
-
168
-
169
- class PaymentAmountEstimate(BaseModel):
170
- """Universal payment amount estimation response"""
171
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
172
-
173
- currency_from: str = Field(description="Source currency code")
174
- currency_to: str = Field(description="Target currency code")
175
- amount_from: Decimal = Field(gt=0, description="Source amount")
176
- estimated_amount: Decimal = Field(gt=0, description="Estimated target amount")
177
- fee_amount: Optional[Decimal] = Field(None, ge=0, description="Provider fee amount")
178
- exchange_rate: Optional[Decimal] = Field(None, gt=0, description="Exchange rate used")
179
- provider_name: str = Field(description="Provider that made the estimation")
180
- estimated_at: Optional[datetime] = Field(None, description="When estimation was made")
181
-
182
-
183
- class WebhookData(BaseModel):
184
- """Provider webhook validation"""
185
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
186
-
187
- provider_payment_id: str
188
- status: str
189
- pay_amount: Optional[Decimal] = None
190
- pay_currency: Optional[str] = None
191
- actually_paid: Optional[Decimal] = None
192
- order_id: Optional[str] = None
193
- signature: Optional[str] = None
194
- error_message: Optional[str] = None
195
-
196
-
197
- # =============================================================================
198
- # INTER-SERVICE OPERATIONS - Service-to-service typing
199
- # =============================================================================
200
-
201
- class ServiceOperationResult(BaseModel):
202
- """Result of inter-service operation"""
203
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
204
-
205
- success: bool
206
- error_code: Optional[str] = None
207
- error_message: Optional[str] = None
208
- data: Dict[str, Any] = Field(default_factory=dict)
209
-
210
-
211
- class BalanceUpdateRequest(BaseModel):
212
- """Balance update request between services"""
213
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
214
-
215
- user_id: int = Field(gt=0)
216
- amount: Decimal
217
- source: str
218
- reference_id: Optional[str] = None
219
- metadata: Dict[str, Any] = Field(default_factory=dict)
220
-
221
-
222
- class AccessCheckRequest(BaseModel):
223
- """Access check request between services"""
224
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
225
-
226
- user_id: int = Field(gt=0)
227
- endpoint_group: str
228
- use_cache: bool = True
229
-
230
-
231
- class AccessCheckResult(BaseModel):
232
- """Access check result"""
233
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
234
-
235
- allowed: bool
236
- subscription_id: Optional[str] = None
237
- reason: Optional[str] = None
238
- remaining_requests: Optional[int] = None
239
- usage_percentage: Optional[float] = None
240
-
241
-
242
- # =============================================================================
243
- # CONFIGURATION - Service settings
244
- # =============================================================================
245
-
246
- class RedisConfig(BaseModel):
247
- """Redis configuration"""
248
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
249
-
250
- host: str = "localhost"
251
- port: int = 6379
252
- db: int = 0
253
- password: Optional[str] = None
254
- max_connections: int = 10
255
- timeout_seconds: int = 5
256
-
257
-
258
- class ProviderConfig(BaseModel):
259
- """Base provider configuration with automatic sandbox detection"""
260
- model_config = ConfigDict(validate_assignment=True, extra="allow") # Allow extra fields for flexibility
261
-
262
- enabled: bool = True
263
- api_key: str
264
- timeout_seconds: int = Field(default=30, alias='timeout', description="Request timeout in seconds")
265
- max_retries: int = 3
266
-
267
- @computed_field
268
- @property
269
- def sandbox(self) -> bool:
270
- """Get sandbox mode from django-cfg config."""
271
- try:
272
- from django_cfg.core.config import get_current_config
273
- current_config = get_current_config()
274
-
275
- if current_config:
276
- # Check env_mode first
277
- if hasattr(current_config, 'env_mode'):
278
- env_mode = current_config.env_mode
279
- if isinstance(env_mode, str):
280
- return env_mode.lower() in ['development', 'dev', 'test']
281
-
282
- # Fallback to debug flag
283
- if hasattr(current_config, 'debug'):
284
- return current_config.debug
285
-
286
- return True # Default to sandbox for safety
287
- except Exception:
288
- return True
289
-
290
-
291
- # =============================================================================
292
- # CACHE OPERATIONS - Minimal cache typing
293
- # =============================================================================
294
-
295
- class CacheKey(BaseModel):
296
- """Cache key typing"""
297
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
298
-
299
- key: str
300
- ttl_seconds: Optional[int] = None
301
-
302
-
303
- class RateLimitResult(BaseModel):
304
- """Rate limit check result"""
305
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
306
-
307
- allowed: bool
308
- remaining: int
309
- reset_at: datetime
310
- retry_after_seconds: Optional[int] = None
311
-
312
-
313
- # =============================================================================
314
- # SERVICE RESPONSE MODELS - Typed responses for service methods
315
- # =============================================================================
316
-
317
- class PaymentCreationResult(BaseModel):
318
- """Payment creation response"""
319
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
320
-
321
- success: bool
322
- payment_id: Optional[str] = None
323
- provider_payment_id: Optional[str] = None
324
- payment_url: Optional[str] = None
325
- error: Optional[str] = None
326
-
327
-
328
- class WebhookProcessingResult(BaseModel):
329
- """Webhook processing response"""
330
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
331
-
332
- success: bool
333
- payment_id: Optional[str] = None
334
- status_updated: bool = False
335
- balance_updated: bool = False
336
- error: Optional[str] = None
337
-
338
-
339
- class PaymentStatusResult(BaseModel):
340
- """Payment status response"""
341
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
342
-
343
- payment_id: str
344
- status: str
345
- amount_usd: Decimal
346
- currency_code: str
347
- provider: str
348
- provider_payment_id: Optional[str] = None
349
- created_at: datetime
350
- updated_at: datetime
351
-
352
-
353
- class UserBalanceResult(BaseModel):
354
- """User balance response"""
355
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
356
-
357
- id: str
358
- user_id: int
359
- available_balance: Decimal
360
- total_balance: Decimal
361
- reserved_balance: Decimal
362
- last_updated: datetime
363
- created_at: datetime
364
-
365
-
366
- class TransferResult(BaseModel):
367
- """Funds transfer response"""
368
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
369
-
370
- success: bool
371
- transaction_id: Optional[str] = None
372
- from_user_id: int
373
- to_user_id: int
374
- amount: Decimal
375
- error: Optional[str] = None
376
- error_code: Optional[str] = None
377
-
378
-
379
- class TransactionInfo(BaseModel):
380
- """Transaction information"""
381
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
382
-
383
- id: str
384
- user_id: int
385
- transaction_type: str
386
- amount: Decimal
387
- balance_after: Decimal
388
- source: str
389
- reference_id: Optional[str] = None
390
- description: Optional[str] = None
391
- created_at: datetime
392
-
393
-
394
- class EndpointGroupInfo(BaseModel):
395
- """Endpoint group information"""
396
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
397
-
398
- id: str
399
- name: str
400
- display_name: str
401
-
402
-
403
- class SubscriptionInfo(BaseModel):
404
- """Subscription information"""
405
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
406
-
407
- id: str
408
- endpoint_group: EndpointGroupInfo
409
- status: str
410
- tier: str
411
- monthly_price: Decimal
412
- usage_current: int
413
- usage_limit: int
414
- usage_percentage: float
415
- remaining_requests: int
416
- expires_at: datetime
417
- next_billing: Optional[datetime] = None
418
- created_at: datetime
419
-
420
-
421
- class SubscriptionAnalytics(BaseModel):
422
- """Subscription analytics response"""
423
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
424
-
425
- period: Dict[str, Any] = Field(default_factory=dict)
426
- total_revenue: Decimal
427
- active_subscriptions: int
428
- new_subscriptions: int
429
- churned_subscriptions: int
430
- error: Optional[str] = None
431
-
432
-
433
- # =============================================================================
434
- # ADDITIONAL RESPONSE MODELS - Missing Pydantic models
435
- # =============================================================================
436
-
437
- class PaymentHistoryItem(BaseModel):
438
- """Single payment item for history lists"""
439
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
440
-
441
- id: str
442
- user_id: int
443
- amount: Decimal
444
- currency: str
445
- status: str
446
- provider: str
447
- provider_payment_id: Optional[str] = None
448
- created_at: datetime
449
- updated_at: datetime
450
- metadata: Dict[str, Any] = Field(default_factory=dict)
451
-
452
-
453
- class ProviderInfo(BaseModel):
454
- """Payment provider information"""
455
- model_config = ConfigDict(validate_assignment=True, extra="forbid")
456
-
457
- name: str
458
- display_name: str
459
- supported_currencies: list[str] = Field(default_factory=list)
460
- is_active: bool
461
- features: Dict[str, Any] = Field(default_factory=dict)
@@ -1,8 +0,0 @@
1
- """
2
- Service layer middleware for payments.
3
-
4
- TODO: Implement service middleware when needed.
5
- """
6
-
7
- # Placeholder for future service middleware
8
- __all__ = []
@@ -1,22 +0,0 @@
1
- """
2
- Payment system monitoring services.
3
-
4
- Provides health monitoring, alerting, and fallback mechanisms
5
- for payment providers and system components.
6
- """
7
-
8
- from .provider_health import (
9
- ProviderHealthMonitor,
10
- ProviderHealthCheck,
11
- ProviderHealthSummary,
12
- HealthStatus,
13
- get_health_monitor
14
- )
15
-
16
- __all__ = [
17
- 'ProviderHealthMonitor',
18
- 'ProviderHealthCheck',
19
- 'ProviderHealthSummary',
20
- 'HealthStatus',
21
- 'get_health_monitor'
22
- ]
@@ -1,76 +0,0 @@
1
- """
2
- Provider API monitoring schemas.
3
-
4
- Re-exports provider-specific monitoring models from their dedicated folders.
5
- Universal monitoring models and utilities.
6
- """
7
-
8
- # Re-export provider-specific health check models
9
- from ..providers.cryptapi.models import CryptAPIInfoResponse
10
- from ..providers.nowpayments.models import NowPaymentsStatusResponse
11
- from ..providers.cryptomus.models import CryptomusErrorResponse
12
- from ..providers.stripe.models import StripeHealthErrorResponse
13
-
14
- # Universal monitoring models - defined here
15
- from pydantic import BaseModel, Field
16
- from typing import Dict, Any, Optional
17
- from enum import Enum
18
-
19
-
20
- class APIHealthStatus(str, Enum):
21
- """API health status enumeration."""
22
- HEALTHY = "healthy"
23
- DEGRADED = "degraded"
24
- UNHEALTHY = "unhealthy"
25
- UNKNOWN = "unknown"
26
-
27
-
28
- class GenericAPIHealthResponse(BaseModel):
29
- """Generic API health check response."""
30
- status: APIHealthStatus = Field(description="API health status")
31
- response_time_ms: float = Field(description="Response time in milliseconds")
32
- error_message: Optional[str] = Field(None, description="Error message if unhealthy")
33
- metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
34
-
35
-
36
- class ProviderHealthResponse(BaseModel):
37
- """Provider health check response wrapper."""
38
- provider_name: str = Field(description="Provider name")
39
- api_health: GenericAPIHealthResponse = Field(description="API health details")
40
- checked_at: str = Field(description="Check timestamp")
41
-
42
-
43
- def parse_provider_response(provider_name: str, response_data: Dict[str, Any]) -> ProviderHealthResponse:
44
- """Parse provider API response into standardized health format."""
45
- # Simple implementation - can be enhanced per provider
46
- status = APIHealthStatus.HEALTHY if response_data.get('success', False) else APIHealthStatus.UNHEALTHY
47
-
48
- api_health = GenericAPIHealthResponse(
49
- status=status,
50
- response_time_ms=response_data.get('response_time', 0.0),
51
- error_message=response_data.get('error_message'),
52
- metadata=response_data.get('metadata', {})
53
- )
54
-
55
- return ProviderHealthResponse(
56
- provider_name=provider_name,
57
- api_health=api_health,
58
- checked_at=response_data.get('timestamp', '')
59
- )
60
-
61
-
62
- # Backward compatibility exports
63
- __all__ = [
64
- # Provider-specific models
65
- 'CryptAPIInfoResponse',
66
- 'NowPaymentsStatusResponse',
67
- 'CryptomusErrorResponse',
68
- 'StripeHealthErrorResponse',
69
-
70
- # Universal models
71
- 'GenericAPIHealthResponse',
72
- 'ProviderHealthResponse',
73
-
74
- # Utility functions
75
- 'parse_provider_response',
76
- ]