django-cfg 1.2.31__py3-none-any.whl → 1.3.1__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 (256) 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/manage_currencies.py +303 -151
  39. django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
  40. django_cfg/apps/payments/middleware/__init__.py +3 -1
  41. django_cfg/apps/payments/middleware/api_access.py +329 -222
  42. django_cfg/apps/payments/middleware/rate_limiting.py +342 -152
  43. django_cfg/apps/payments/middleware/usage_tracking.py +249 -240
  44. django_cfg/apps/payments/migrations/0001_initial.py +708 -536
  45. django_cfg/apps/payments/models/__init__.py +13 -18
  46. django_cfg/apps/payments/models/api_keys.py +121 -43
  47. django_cfg/apps/payments/models/balance.py +150 -115
  48. django_cfg/apps/payments/models/base.py +68 -15
  49. django_cfg/apps/payments/models/currencies.py +172 -148
  50. django_cfg/apps/payments/models/managers/__init__.py +44 -0
  51. django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
  52. django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
  53. django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
  54. django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
  55. django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
  56. django_cfg/apps/payments/models/payments.py +235 -285
  57. django_cfg/apps/payments/models/subscriptions.py +257 -177
  58. django_cfg/apps/payments/models/tariffs.py +147 -40
  59. django_cfg/apps/payments/services/__init__.py +209 -56
  60. django_cfg/apps/payments/services/cache/__init__.py +6 -6
  61. django_cfg/apps/payments/services/cache/{simple_cache.py → cache_service.py} +112 -12
  62. django_cfg/apps/payments/services/core/__init__.py +10 -6
  63. django_cfg/apps/payments/services/core/balance_service.py +435 -360
  64. django_cfg/apps/payments/services/core/base.py +166 -0
  65. django_cfg/apps/payments/services/core/currency_service.py +478 -0
  66. django_cfg/apps/payments/services/core/payment_service.py +346 -467
  67. django_cfg/apps/payments/services/core/subscription_service.py +425 -481
  68. django_cfg/apps/payments/services/core/webhook_service.py +410 -0
  69. django_cfg/apps/payments/services/integrations/__init__.py +29 -0
  70. django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
  71. django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
  72. django_cfg/apps/payments/services/providers/__init__.py +9 -14
  73. django_cfg/apps/payments/services/providers/base.py +234 -174
  74. django_cfg/apps/payments/services/providers/nowpayments.py +478 -0
  75. django_cfg/apps/payments/services/providers/registry.py +367 -301
  76. django_cfg/apps/payments/services/types/__init__.py +78 -0
  77. django_cfg/apps/payments/services/types/data.py +177 -0
  78. django_cfg/apps/payments/services/types/requests.py +150 -0
  79. django_cfg/apps/payments/services/types/responses.py +156 -0
  80. django_cfg/apps/payments/services/types/webhooks.py +232 -0
  81. django_cfg/apps/payments/signals/__init__.py +33 -8
  82. django_cfg/apps/payments/signals/api_key_signals.py +210 -129
  83. django_cfg/apps/payments/signals/balance_signals.py +174 -0
  84. django_cfg/apps/payments/signals/payment_signals.py +128 -103
  85. django_cfg/apps/payments/signals/subscription_signals.py +194 -142
  86. django_cfg/apps/payments/static/payments/css/components.css +380 -0
  87. django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
  88. django_cfg/apps/payments/static/payments/js/components.js +545 -0
  89. django_cfg/apps/payments/static/payments/js/utils.js +412 -0
  90. django_cfg/apps/payments/templatetags/__init__.py +1 -1
  91. django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
  92. django_cfg/apps/payments/urls.py +45 -48
  93. django_cfg/apps/payments/urls_admin.py +33 -42
  94. django_cfg/apps/payments/views/api/__init__.py +101 -0
  95. django_cfg/apps/payments/views/api/api_keys.py +387 -0
  96. django_cfg/apps/payments/views/api/balances.py +381 -0
  97. django_cfg/apps/payments/views/api/base.py +298 -0
  98. django_cfg/apps/payments/views/api/currencies.py +402 -0
  99. django_cfg/apps/payments/views/api/payments.py +415 -0
  100. django_cfg/apps/payments/views/api/subscriptions.py +475 -0
  101. django_cfg/apps/payments/views/api/webhooks.py +476 -0
  102. django_cfg/apps/payments/views/serializers/__init__.py +99 -0
  103. django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
  104. django_cfg/apps/payments/views/serializers/balances.py +300 -0
  105. django_cfg/apps/payments/views/serializers/currencies.py +335 -0
  106. django_cfg/apps/payments/views/serializers/payments.py +387 -0
  107. django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
  108. django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
  109. django_cfg/config.py +1 -1
  110. django_cfg/core/config.py +40 -4
  111. django_cfg/core/generation.py +25 -4
  112. django_cfg/core/integration/README.md +363 -0
  113. django_cfg/core/integration/__init__.py +47 -0
  114. django_cfg/core/integration/commands_collector.py +239 -0
  115. django_cfg/core/integration/display/__init__.py +15 -0
  116. django_cfg/core/integration/display/base.py +157 -0
  117. django_cfg/core/integration/display/ngrok.py +164 -0
  118. django_cfg/core/integration/display/startup.py +815 -0
  119. django_cfg/core/integration/url_integration.py +123 -0
  120. django_cfg/core/integration/version_checker.py +160 -0
  121. django_cfg/management/commands/auto_generate.py +4 -0
  122. django_cfg/management/commands/check_settings.py +6 -0
  123. django_cfg/management/commands/clear_constance.py +5 -2
  124. django_cfg/management/commands/create_token.py +6 -0
  125. django_cfg/management/commands/list_urls.py +6 -0
  126. django_cfg/management/commands/migrate_all.py +6 -0
  127. django_cfg/management/commands/migrator.py +3 -0
  128. django_cfg/management/commands/rundramatiq.py +6 -0
  129. django_cfg/management/commands/runserver_ngrok.py +51 -29
  130. django_cfg/management/commands/script.py +6 -0
  131. django_cfg/management/commands/show_config.py +12 -2
  132. django_cfg/management/commands/show_urls.py +4 -0
  133. django_cfg/management/commands/superuser.py +6 -0
  134. django_cfg/management/commands/task_clear.py +4 -1
  135. django_cfg/management/commands/task_status.py +3 -1
  136. django_cfg/management/commands/test_email.py +3 -0
  137. django_cfg/management/commands/test_telegram.py +6 -0
  138. django_cfg/management/commands/test_twilio.py +6 -0
  139. django_cfg/management/commands/tree.py +6 -0
  140. django_cfg/management/commands/validate_config.py +155 -149
  141. django_cfg/models/constance.py +31 -11
  142. django_cfg/models/payments.py +175 -492
  143. django_cfg/modules/django_logger.py +160 -146
  144. django_cfg/modules/django_unfold/dashboard.py +64 -16
  145. django_cfg/registry/core.py +1 -0
  146. django_cfg/template_archive/django_sample.zip +0 -0
  147. django_cfg/utils/smart_defaults.py +222 -571
  148. django_cfg/utils/toolkit.py +51 -11
  149. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/METADATA +4 -1
  150. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/RECORD +153 -185
  151. django_cfg/apps/payments/__init__.py +0 -8
  152. django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
  153. django_cfg/apps/payments/config/module.py +0 -70
  154. django_cfg/apps/payments/config/providers.py +0 -105
  155. django_cfg/apps/payments/config/settings.py +0 -96
  156. django_cfg/apps/payments/config/utils.py +0 -52
  157. django_cfg/apps/payments/decorators.py +0 -291
  158. django_cfg/apps/payments/management/commands/README.md +0 -146
  159. django_cfg/apps/payments/management/commands/currency_stats.py +0 -304
  160. django_cfg/apps/payments/managers/__init__.py +0 -23
  161. django_cfg/apps/payments/managers/api_key_manager.py +0 -35
  162. django_cfg/apps/payments/managers/balance_manager.py +0 -361
  163. django_cfg/apps/payments/managers/currency_manager.py +0 -306
  164. django_cfg/apps/payments/managers/payment_manager.py +0 -192
  165. django_cfg/apps/payments/managers/subscription_manager.py +0 -37
  166. django_cfg/apps/payments/managers/tariff_manager.py +0 -29
  167. django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +0 -241
  168. django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +0 -30
  169. django_cfg/apps/payments/models/events.py +0 -73
  170. django_cfg/apps/payments/serializers/__init__.py +0 -57
  171. django_cfg/apps/payments/serializers/api_keys.py +0 -51
  172. django_cfg/apps/payments/serializers/balance.py +0 -59
  173. django_cfg/apps/payments/serializers/currencies.py +0 -63
  174. django_cfg/apps/payments/serializers/payments.py +0 -62
  175. django_cfg/apps/payments/serializers/subscriptions.py +0 -71
  176. django_cfg/apps/payments/serializers/tariffs.py +0 -56
  177. django_cfg/apps/payments/services/billing/__init__.py +0 -8
  178. django_cfg/apps/payments/services/cache/base.py +0 -30
  179. django_cfg/apps/payments/services/core/fallback_service.py +0 -432
  180. django_cfg/apps/payments/services/internal_types.py +0 -461
  181. django_cfg/apps/payments/services/middleware/__init__.py +0 -8
  182. django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
  183. django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -76
  184. django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
  185. django_cfg/apps/payments/services/providers/cryptapi/__init__.py +0 -4
  186. django_cfg/apps/payments/services/providers/cryptapi/config.py +0 -8
  187. django_cfg/apps/payments/services/providers/cryptapi/models.py +0 -192
  188. django_cfg/apps/payments/services/providers/cryptapi/provider.py +0 -439
  189. django_cfg/apps/payments/services/providers/cryptomus/__init__.py +0 -4
  190. django_cfg/apps/payments/services/providers/cryptomus/models.py +0 -176
  191. django_cfg/apps/payments/services/providers/cryptomus/provider.py +0 -429
  192. django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +0 -564
  193. django_cfg/apps/payments/services/providers/models/__init__.py +0 -34
  194. django_cfg/apps/payments/services/providers/models/currencies.py +0 -190
  195. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +0 -4
  196. django_cfg/apps/payments/services/providers/nowpayments/models.py +0 -196
  197. django_cfg/apps/payments/services/providers/nowpayments/provider.py +0 -380
  198. django_cfg/apps/payments/services/providers/stripe/__init__.py +0 -4
  199. django_cfg/apps/payments/services/providers/stripe/models.py +0 -184
  200. django_cfg/apps/payments/services/providers/stripe/provider.py +0 -109
  201. django_cfg/apps/payments/services/security/__init__.py +0 -34
  202. django_cfg/apps/payments/services/security/error_handler.py +0 -635
  203. django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
  204. django_cfg/apps/payments/services/security/webhook_validator.py +0 -474
  205. django_cfg/apps/payments/static/payments/css/payments.css +0 -340
  206. django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
  207. django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
  208. django_cfg/apps/payments/static/payments/js/theme.js +0 -86
  209. django_cfg/apps/payments/tasks/__init__.py +0 -12
  210. django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
  211. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +0 -50
  212. django_cfg/apps/payments/templates/payments/base.html +0 -182
  213. django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
  214. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
  215. django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -43
  216. django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
  217. django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -34
  218. django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -148
  219. django_cfg/apps/payments/templates/payments/dashboard.html +0 -258
  220. django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +0 -35
  221. django_cfg/apps/payments/templates/payments/payment_create.html +0 -579
  222. django_cfg/apps/payments/templates/payments/payment_detail.html +0 -373
  223. django_cfg/apps/payments/templates/payments/payment_list.html +0 -354
  224. django_cfg/apps/payments/templates/payments/stats.html +0 -261
  225. django_cfg/apps/payments/templates/payments/test.html +0 -213
  226. django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
  227. django_cfg/apps/payments/utils/__init__.py +0 -43
  228. django_cfg/apps/payments/utils/billing_utils.py +0 -342
  229. django_cfg/apps/payments/utils/config_utils.py +0 -239
  230. django_cfg/apps/payments/utils/middleware_utils.py +0 -228
  231. django_cfg/apps/payments/utils/validation_utils.py +0 -94
  232. django_cfg/apps/payments/views/__init__.py +0 -63
  233. django_cfg/apps/payments/views/api_key_views.py +0 -164
  234. django_cfg/apps/payments/views/balance_views.py +0 -75
  235. django_cfg/apps/payments/views/currency_views.py +0 -122
  236. django_cfg/apps/payments/views/payment_views.py +0 -149
  237. django_cfg/apps/payments/views/subscription_views.py +0 -135
  238. django_cfg/apps/payments/views/tariff_views.py +0 -131
  239. django_cfg/apps/payments/views/templates/__init__.py +0 -25
  240. django_cfg/apps/payments/views/templates/ajax.py +0 -451
  241. django_cfg/apps/payments/views/templates/base.py +0 -212
  242. django_cfg/apps/payments/views/templates/dashboard.py +0 -60
  243. django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
  244. django_cfg/apps/payments/views/templates/payment_management.py +0 -158
  245. django_cfg/apps/payments/views/templates/qr_code.py +0 -174
  246. django_cfg/apps/payments/views/templates/stats.py +0 -244
  247. django_cfg/apps/payments/views/templates/utils.py +0 -181
  248. django_cfg/apps/payments/views/webhook_views.py +0 -266
  249. django_cfg/apps/payments/viewsets.py +0 -66
  250. django_cfg/core/integration.py +0 -160
  251. django_cfg/template_archive/.gitignore +0 -1
  252. django_cfg/template_archive/__init__.py +0 -0
  253. django_cfg/urls.py +0 -33
  254. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
  255. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
  256. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.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
- ]