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
@@ -0,0 +1,78 @@
1
+ """
2
+ Pydantic types for the Universal Payment System v2.0.
3
+
4
+ Type-safe models for inter-service communication following data typing requirements.
5
+ Uses Pydantic 2 for service layer validation and business logic.
6
+ """
7
+
8
+ # Request types
9
+ from .requests import (
10
+ PaymentCreateRequest,
11
+ PaymentStatusRequest,
12
+ BalanceUpdateRequest,
13
+ SubscriptionCreateRequest,
14
+ SubscriptionUpdateRequest,
15
+ CurrencyConversionRequest,
16
+ WebhookValidationRequest,
17
+ )
18
+
19
+ # Response types
20
+ from .responses import (
21
+ PaymentResult,
22
+ ProviderResponse,
23
+ BalanceResult,
24
+ SubscriptionResult,
25
+ CurrencyConversionResult,
26
+ ServiceOperationResult,
27
+ )
28
+
29
+ # Data types
30
+ from .data import (
31
+ PaymentData,
32
+ BalanceData,
33
+ SubscriptionData,
34
+ TransactionData,
35
+ CurrencyData,
36
+ ProviderData,
37
+ )
38
+
39
+ # Webhook types
40
+ from .webhooks import (
41
+ WebhookData,
42
+ NowPaymentsWebhook,
43
+ WebhookProcessingResult,
44
+ WebhookSignature,
45
+ )
46
+
47
+ __all__ = [
48
+ # Request types
49
+ 'PaymentCreateRequest',
50
+ 'PaymentStatusRequest',
51
+ 'BalanceUpdateRequest',
52
+ 'SubscriptionCreateRequest',
53
+ 'SubscriptionUpdateRequest',
54
+ 'CurrencyConversionRequest',
55
+ 'WebhookValidationRequest',
56
+
57
+ # Response types
58
+ 'PaymentResult',
59
+ 'ProviderResponse',
60
+ 'BalanceResult',
61
+ 'SubscriptionResult',
62
+ 'CurrencyConversionResult',
63
+ 'ServiceOperationResult',
64
+
65
+ # Data types
66
+ 'PaymentData',
67
+ 'BalanceData',
68
+ 'SubscriptionData',
69
+ 'TransactionData',
70
+ 'CurrencyData',
71
+ 'ProviderData',
72
+
73
+ # Webhook types
74
+ 'WebhookData',
75
+ 'NowPaymentsWebhook',
76
+ 'WebhookProcessingResult',
77
+ 'WebhookSignature',
78
+ ]
@@ -0,0 +1,177 @@
1
+ """
2
+ Data types for the Universal Payment System v2.0.
3
+
4
+ Pydantic models for internal data representation and transfer.
5
+ """
6
+
7
+ from decimal import Decimal
8
+ from typing import Optional, Dict, Any, List, Literal
9
+ from pydantic import BaseModel, Field, ConfigDict
10
+ from datetime import datetime
11
+
12
+
13
+ class PaymentData(BaseModel):
14
+ """Internal payment data representation."""
15
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
16
+
17
+ id: str = Field(description="Payment ID")
18
+ user_id: int = Field(description="User ID")
19
+ amount_usd: float = Field(description="Amount in USD")
20
+ crypto_amount: Optional[Decimal] = Field(None, description="Cryptocurrency amount")
21
+ currency_code: str = Field(description="Cryptocurrency code")
22
+ provider: str = Field(description="Payment provider")
23
+ status: str = Field(description="Payment status")
24
+ provider_payment_id: Optional[str] = Field(None, description="Provider payment ID")
25
+ payment_url: Optional[str] = Field(None, description="Payment URL")
26
+ qr_code_url: Optional[str] = Field(None, description="QR code URL")
27
+ wallet_address: Optional[str] = Field(None, description="Wallet address")
28
+ callback_url: Optional[str] = Field(None, description="Success callback URL")
29
+ cancel_url: Optional[str] = Field(None, description="Cancel URL")
30
+ description: Optional[str] = Field(None, description="Payment description")
31
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
32
+ created_at: datetime = Field(description="Creation timestamp")
33
+ updated_at: datetime = Field(description="Last update timestamp")
34
+ expires_at: Optional[datetime] = Field(None, description="Payment expiration")
35
+ completed_at: Optional[datetime] = Field(None, description="Completion timestamp")
36
+
37
+
38
+ class BalanceData(BaseModel):
39
+ """Internal balance data representation."""
40
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
41
+
42
+ user_id: int = Field(description="User ID")
43
+ balance_usd: float = Field(description="Balance in USD")
44
+ created_at: datetime = Field(description="Creation timestamp")
45
+ updated_at: datetime = Field(description="Last update timestamp")
46
+
47
+
48
+ class TransactionData(BaseModel):
49
+ """Internal transaction data representation."""
50
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
51
+
52
+ id: str = Field(description="Transaction ID")
53
+ user_id: int = Field(description="User ID")
54
+ amount: float = Field(description="Transaction amount")
55
+ transaction_type: str = Field(description="Transaction type")
56
+ description: Optional[str] = Field(None, description="Transaction description")
57
+ payment_id: Optional[str] = Field(None, description="Related payment ID")
58
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
59
+ created_at: datetime = Field(description="Creation timestamp")
60
+
61
+
62
+ class SubscriptionData(BaseModel):
63
+ """Internal subscription data representation."""
64
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
65
+
66
+ id: str = Field(description="Subscription ID")
67
+ user_id: int = Field(description="User ID")
68
+ tier: str = Field(description="Subscription tier")
69
+ status: str = Field(description="Subscription status")
70
+ requests_per_hour: int = Field(description="Requests per hour limit")
71
+ requests_per_day: int = Field(description="Requests per day limit")
72
+ total_requests: int = Field(default=0, description="Total requests made")
73
+ monthly_cost_usd: float = Field(description="Monthly cost in USD")
74
+ auto_renew: bool = Field(default=False, description="Auto-renewal enabled")
75
+ created_at: datetime = Field(description="Creation timestamp")
76
+ updated_at: datetime = Field(description="Last update timestamp")
77
+ expires_at: Optional[datetime] = Field(None, description="Subscription expiration")
78
+ last_request_at: Optional[datetime] = Field(None, description="Last request timestamp")
79
+ endpoint_groups: List[str] = Field(default_factory=list, description="Allowed endpoint groups")
80
+
81
+
82
+ class CurrencyData(BaseModel):
83
+ """Internal currency data representation."""
84
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
85
+
86
+ code: str = Field(description="Currency code")
87
+ name: str = Field(description="Currency name")
88
+ currency_type: str = Field(description="Currency type (fiat/crypto)")
89
+ symbol: Optional[str] = Field(None, description="Currency symbol")
90
+ decimal_places: int = Field(default=8, description="Decimal places")
91
+ is_enabled: bool = Field(default=True, description="Currency enabled status")
92
+ min_amount: Optional[Decimal] = Field(None, description="Minimum amount")
93
+ max_amount: Optional[Decimal] = Field(None, description="Maximum amount")
94
+ network_fee: Optional[Decimal] = Field(None, description="Network fee")
95
+ created_at: datetime = Field(description="Creation timestamp")
96
+ updated_at: datetime = Field(description="Last update timestamp")
97
+
98
+
99
+ class ProviderData(BaseModel):
100
+ """Internal provider data representation."""
101
+ model_config = ConfigDict(validate_assignment=True)
102
+
103
+ name: str = Field(description="Provider name")
104
+ display_name: str = Field(description="Provider display name")
105
+ is_enabled: bool = Field(default=True, description="Provider enabled status")
106
+ api_url: str = Field(description="Provider API URL")
107
+ supported_currencies: List[str] = Field(default_factory=list, description="Supported currencies")
108
+ min_amount_usd: float = Field(default=1.0, description="Minimum amount in USD")
109
+ max_amount_usd: float = Field(default=50000.0, description="Maximum amount in USD")
110
+ fee_percentage: float = Field(default=0.0, description="Provider fee percentage")
111
+ confirmation_blocks: Dict[str, int] = Field(default_factory=dict, description="Confirmation blocks per currency")
112
+ webhook_url: Optional[str] = Field(None, description="Webhook URL")
113
+ is_healthy: bool = Field(default=True, description="Provider health status")
114
+ last_health_check: Optional[datetime] = Field(None, description="Last health check")
115
+ response_time_ms: Optional[int] = Field(None, description="Average response time")
116
+
117
+
118
+ class APIKeyData(BaseModel):
119
+ """Internal API key data representation."""
120
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
121
+
122
+ id: str = Field(description="API key ID")
123
+ user_id: int = Field(description="User ID")
124
+ name: str = Field(description="API key name")
125
+ key_prefix: str = Field(description="Key prefix for display")
126
+ is_active: bool = Field(default=True, description="API key active status")
127
+ total_requests: int = Field(default=0, description="Total requests made")
128
+ allowed_ips: Optional[str] = Field(None, description="Allowed IP addresses")
129
+ created_at: datetime = Field(description="Creation timestamp")
130
+ updated_at: datetime = Field(description="Last update timestamp")
131
+ expires_at: Optional[datetime] = Field(None, description="Expiration timestamp")
132
+ last_used_at: Optional[datetime] = Field(None, description="Last used timestamp")
133
+
134
+
135
+ class NetworkData(BaseModel):
136
+ """Internal network data representation."""
137
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
138
+
139
+ code: str = Field(description="Network code")
140
+ name: str = Field(description="Network name")
141
+ currency_code: str = Field(description="Base currency code")
142
+ is_testnet: bool = Field(default=False, description="Is testnet")
143
+ confirmation_blocks: int = Field(default=1, description="Required confirmation blocks")
144
+ block_time_seconds: int = Field(default=600, description="Average block time")
145
+ is_enabled: bool = Field(default=True, description="Network enabled status")
146
+
147
+
148
+ class TariffData(BaseModel):
149
+ """Internal tariff data representation."""
150
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
151
+
152
+ id: str = Field(description="Tariff ID")
153
+ name: str = Field(description="Tariff name")
154
+ tier: str = Field(description="Subscription tier")
155
+ monthly_price_usd: float = Field(description="Monthly price in USD")
156
+ yearly_price_usd: Optional[float] = Field(None, description="Yearly price in USD")
157
+ requests_per_hour: int = Field(description="Requests per hour limit")
158
+ requests_per_day: int = Field(description="Requests per day limit")
159
+ features: List[str] = Field(default_factory=list, description="Included features")
160
+ is_active: bool = Field(default=True, description="Tariff active status")
161
+ sort_order: int = Field(default=0, description="Display sort order")
162
+ created_at: datetime = Field(description="Creation timestamp")
163
+ updated_at: datetime = Field(description="Last update timestamp")
164
+
165
+
166
+ class EndpointGroupData(BaseModel):
167
+ """Internal endpoint group data representation."""
168
+ model_config = ConfigDict(validate_assignment=True, from_attributes=True)
169
+
170
+ code: str = Field(description="Endpoint group code")
171
+ name: str = Field(description="Endpoint group name")
172
+ description: Optional[str] = Field(None, description="Group description")
173
+ rate_limit_per_hour: Optional[int] = Field(None, description="Rate limit per hour")
174
+ is_enabled: bool = Field(default=True, description="Group enabled status")
175
+ endpoints: List[str] = Field(default_factory=list, description="Included endpoints")
176
+ created_at: datetime = Field(description="Creation timestamp")
177
+ updated_at: datetime = Field(description="Last update timestamp")
@@ -0,0 +1,150 @@
1
+ """
2
+ Request types for the Universal Payment System v2.0.
3
+
4
+ Pydantic models for validating incoming service requests.
5
+ """
6
+
7
+ from decimal import Decimal
8
+ from typing import Optional, Dict, Any, Literal
9
+ from pydantic import BaseModel, Field, ConfigDict, field_validator
10
+ from datetime import datetime
11
+
12
+
13
+ class PaymentCreateRequest(BaseModel):
14
+ """
15
+ Type-safe payment creation request.
16
+
17
+ Used for validating payment creation across all service layers.
18
+ """
19
+ model_config = ConfigDict(
20
+ validate_assignment=True,
21
+ extra="forbid",
22
+ str_strip_whitespace=True
23
+ )
24
+
25
+ user_id: int = Field(gt=0, description="User ID")
26
+ amount_usd: float = Field(gt=1.0, le=50000.0, description="Amount in USD")
27
+ currency_code: Literal['BTC', 'ETH', 'LTC', 'XMR', 'USDT', 'USDC', 'ADA', 'DOT'] = Field(
28
+ description="Cryptocurrency code"
29
+ )
30
+ provider: Literal['nowpayments'] = Field(default='nowpayments', description="Payment provider")
31
+ callback_url: Optional[str] = Field(None, description="Success callback URL")
32
+ cancel_url: Optional[str] = Field(None, description="Cancellation URL")
33
+ description: Optional[str] = Field(None, max_length=500, description="Payment description")
34
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
35
+
36
+ @field_validator('currency_code')
37
+ @classmethod
38
+ def validate_currency(cls, v: str) -> str:
39
+ """Validate currency is supported."""
40
+ supported = ['BTC', 'ETH', 'LTC', 'XMR', 'USDT', 'USDC', 'ADA', 'DOT']
41
+ if v.upper() not in supported:
42
+ raise ValueError(f"Currency {v} not supported. Supported: {', '.join(supported)}")
43
+ return v.upper()
44
+
45
+ @field_validator('callback_url', 'cancel_url')
46
+ @classmethod
47
+ def validate_urls(cls, v: Optional[str]) -> Optional[str]:
48
+ """Validate URLs if provided."""
49
+ if v and not v.startswith(('http://', 'https://')):
50
+ raise ValueError("URLs must start with http:// or https://")
51
+ return v
52
+
53
+
54
+ class PaymentStatusRequest(BaseModel):
55
+ """Request for checking payment status."""
56
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
57
+
58
+ payment_id: str = Field(description="Payment ID to check")
59
+ user_id: Optional[int] = Field(None, description="User ID for authorization")
60
+ force_provider_check: bool = Field(default=False, description="Force check with provider")
61
+
62
+
63
+ class BalanceUpdateRequest(BaseModel):
64
+ """Request for updating user balance."""
65
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
66
+
67
+ user_id: int = Field(gt=0, description="User ID")
68
+ amount: float = Field(description="Amount to add/subtract (positive=add, negative=subtract)")
69
+ transaction_type: Literal['deposit', 'withdrawal', 'payment', 'refund', 'fee', 'bonus', 'adjustment'] = Field(
70
+ description="Type of transaction"
71
+ )
72
+ description: Optional[str] = Field(None, description="Transaction description")
73
+ payment_id: Optional[str] = Field(None, description="Related payment ID")
74
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
75
+
76
+ @field_validator('amount')
77
+ @classmethod
78
+ def validate_amount(cls, v: float) -> float:
79
+ """Validate amount is not zero."""
80
+ if v == 0:
81
+ raise ValueError("Amount cannot be zero")
82
+ return v
83
+
84
+
85
+ class SubscriptionCreateRequest(BaseModel):
86
+ """Request for creating subscription."""
87
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
88
+
89
+ user_id: int = Field(gt=0, description="User ID")
90
+ tier: Literal['free', 'basic', 'pro', 'enterprise'] = Field(description="Subscription tier")
91
+ duration_days: int = Field(default=30, gt=0, le=365, description="Subscription duration in days")
92
+ auto_renew: bool = Field(default=False, description="Enable auto-renewal")
93
+ endpoint_groups: list[str] = Field(default_factory=list, description="Endpoint group codes")
94
+
95
+
96
+ class SubscriptionUpdateRequest(BaseModel):
97
+ """Request for updating subscription."""
98
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
99
+
100
+ subscription_id: int = Field(gt=0, description="Subscription ID")
101
+ tier: Optional[Literal['free', 'basic', 'pro', 'enterprise']] = Field(None, description="New subscription tier")
102
+ duration_days: Optional[int] = Field(None, gt=0, le=365, description="New duration in days")
103
+ auto_renew: Optional[bool] = Field(None, description="Enable/disable auto-renewal")
104
+ endpoint_groups: Optional[list[str]] = Field(None, description="New endpoint group codes")
105
+
106
+
107
+ class CurrencyConversionRequest(BaseModel):
108
+ """Request for currency conversion."""
109
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
110
+
111
+ amount: float = Field(gt=0, description="Amount to convert")
112
+ from_currency: str = Field(min_length=3, max_length=10, description="Source currency code")
113
+ to_currency: str = Field(min_length=3, max_length=10, description="Target currency code")
114
+
115
+ @field_validator('from_currency', 'to_currency')
116
+ @classmethod
117
+ def validate_currency_codes(cls, v: str) -> str:
118
+ """Normalize currency codes."""
119
+ return v.upper().strip()
120
+
121
+
122
+ class APIKeyCreateRequest(BaseModel):
123
+ """Request for creating API key."""
124
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
125
+
126
+ user_id: int = Field(gt=0, description="User ID")
127
+ name: str = Field(min_length=1, max_length=100, description="API key name")
128
+ expires_in_days: Optional[int] = Field(None, gt=0, le=365, description="Days until expiration")
129
+ allowed_ips: Optional[str] = Field(None, description="Comma-separated allowed IP addresses")
130
+
131
+
132
+ class WebhookValidationRequest(BaseModel):
133
+ """Request for webhook validation."""
134
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
135
+
136
+ provider: str = Field(description="Provider name")
137
+ payload: Dict[str, Any] = Field(description="Webhook payload")
138
+ signature: Optional[str] = Field(None, description="Webhook signature")
139
+ headers: Dict[str, str] = Field(default_factory=dict, description="Request headers")
140
+ timestamp: Optional[str] = Field(None, description="Request timestamp")
141
+ request_id: Optional[str] = Field(None, description="Request ID for tracking")
142
+
143
+
144
+ class ProviderHealthCheckRequest(BaseModel):
145
+ """Request for provider health check."""
146
+ model_config = ConfigDict(validate_assignment=True, extra="forbid")
147
+
148
+ provider: str = Field(description="Provider name to check")
149
+ include_rates: bool = Field(default=False, description="Include currency rates in check")
150
+ timeout: int = Field(default=30, gt=0, le=300, description="Timeout in seconds")
@@ -0,0 +1,156 @@
1
+ """
2
+ Response types for the Universal Payment System v2.0.
3
+
4
+ Pydantic models for service layer responses and results.
5
+ """
6
+
7
+ from decimal import Decimal
8
+ from typing import Optional, Dict, Any, List, Literal
9
+ from pydantic import BaseModel, Field, ConfigDict
10
+ from datetime import datetime
11
+
12
+
13
+ class ServiceOperationResult(BaseModel):
14
+ """
15
+ Base result type for all service operations.
16
+
17
+ Provides consistent success/error handling across services.
18
+ """
19
+ model_config = ConfigDict(validate_assignment=True)
20
+
21
+ success: bool = Field(description="Operation success status")
22
+ message: Optional[str] = Field(None, description="Human-readable message")
23
+ error_code: Optional[str] = Field(None, description="Machine-readable error code")
24
+ data: Optional[Dict[str, Any]] = Field(None, description="Additional result data")
25
+ timestamp: datetime = Field(default_factory=datetime.utcnow, description="Operation timestamp")
26
+
27
+
28
+ class PaymentResult(ServiceOperationResult):
29
+ """Result of payment operations."""
30
+
31
+ payment_id: Optional[str] = Field(None, description="Payment ID")
32
+ status: Optional[str] = Field(None, description="Payment status")
33
+ amount_usd: Optional[float] = Field(None, description="Payment amount in USD")
34
+ crypto_amount: Optional[Decimal] = Field(None, description="Crypto amount")
35
+ currency_code: Optional[str] = Field(None, description="Cryptocurrency code")
36
+ provider_payment_id: Optional[str] = Field(None, description="Provider payment ID")
37
+ payment_url: Optional[str] = Field(None, description="Payment URL")
38
+ qr_code_url: Optional[str] = Field(None, description="QR code URL")
39
+ wallet_address: Optional[str] = Field(None, description="Wallet address")
40
+ expires_at: Optional[datetime] = Field(None, description="Payment expiration")
41
+
42
+
43
+ class ProviderResponse(BaseModel):
44
+ """Response from payment provider."""
45
+ model_config = ConfigDict(validate_assignment=True)
46
+
47
+ provider: str = Field(description="Provider name")
48
+ success: bool = Field(description="Provider operation success")
49
+ provider_payment_id: Optional[str] = Field(None, description="Provider payment ID")
50
+ status: Optional[str] = Field(None, description="Provider status")
51
+ amount: Optional[Decimal] = Field(None, description="Amount from provider")
52
+ currency: Optional[str] = Field(None, description="Currency from provider")
53
+ payment_url: Optional[str] = Field(None, description="Payment URL")
54
+ wallet_address: Optional[str] = Field(None, description="Wallet address")
55
+ qr_code_url: Optional[str] = Field(None, description="QR code URL")
56
+ expires_at: Optional[datetime] = Field(None, description="Payment expiration")
57
+ error_message: Optional[str] = Field(None, description="Error message")
58
+ raw_response: Dict[str, Any] = Field(default_factory=dict, description="Raw provider response")
59
+
60
+
61
+ class BalanceResult(ServiceOperationResult):
62
+ """Result of balance operations."""
63
+
64
+ user_id: Optional[int] = Field(None, description="User ID")
65
+ balance_usd: Optional[float] = Field(None, description="Current balance in USD")
66
+ transaction_id: Optional[str] = Field(None, description="Transaction ID")
67
+ transaction_amount: Optional[float] = Field(None, description="Transaction amount")
68
+ transaction_type: Optional[str] = Field(None, description="Transaction type")
69
+
70
+
71
+ class SubscriptionResult(ServiceOperationResult):
72
+ """Result of subscription operations."""
73
+
74
+ subscription_id: Optional[str] = Field(None, description="Subscription ID")
75
+ user_id: Optional[int] = Field(None, description="User ID")
76
+ tier: Optional[str] = Field(None, description="Subscription tier")
77
+ status: Optional[str] = Field(None, description="Subscription status")
78
+ expires_at: Optional[datetime] = Field(None, description="Subscription expiration")
79
+ requests_remaining: Optional[int] = Field(None, description="Requests remaining today")
80
+
81
+
82
+ class CurrencyConversionResult(ServiceOperationResult):
83
+ """Result of currency conversion."""
84
+
85
+ amount: Optional[float] = Field(None, description="Original amount")
86
+ from_currency: Optional[str] = Field(None, description="Source currency")
87
+ to_currency: Optional[str] = Field(None, description="Target currency")
88
+ converted_amount: Optional[float] = Field(None, description="Converted amount")
89
+ exchange_rate: Optional[float] = Field(None, description="Exchange rate used")
90
+ rate_timestamp: Optional[datetime] = Field(None, description="Rate timestamp")
91
+
92
+
93
+ class APIKeyResult(ServiceOperationResult):
94
+ """Result of API key operations."""
95
+
96
+ api_key_id: Optional[str] = Field(None, description="API key ID")
97
+ key_value: Optional[str] = Field(None, description="API key value (only on creation)")
98
+ name: Optional[str] = Field(None, description="API key name")
99
+ is_active: Optional[bool] = Field(None, description="API key active status")
100
+ expires_at: Optional[datetime] = Field(None, description="API key expiration")
101
+ total_requests: Optional[int] = Field(None, description="Total requests made")
102
+
103
+
104
+ class WebhookProcessingResult(ServiceOperationResult):
105
+ """Result of webhook processing."""
106
+
107
+ webhook_id: Optional[str] = Field(None, description="Webhook ID")
108
+ provider: Optional[str] = Field(None, description="Provider name")
109
+ payment_id: Optional[str] = Field(None, description="Related payment ID")
110
+ processed: bool = Field(default=False, description="Whether webhook was processed")
111
+ actions_taken: List[str] = Field(default_factory=list, description="Actions taken during processing")
112
+
113
+
114
+ class ProviderHealthResult(ServiceOperationResult):
115
+ """Result of provider health check."""
116
+
117
+ provider: str = Field(description="Provider name")
118
+ is_healthy: bool = Field(description="Provider health status")
119
+ response_time_ms: Optional[int] = Field(None, description="Response time in milliseconds")
120
+ api_status: Optional[str] = Field(None, description="API status")
121
+ rates_available: Optional[bool] = Field(None, description="Currency rates availability")
122
+ last_successful_call: Optional[datetime] = Field(None, description="Last successful API call")
123
+ error_details: Optional[str] = Field(None, description="Error details if unhealthy")
124
+
125
+
126
+ class ServiceStats(BaseModel):
127
+ """Service statistics."""
128
+ model_config = ConfigDict(validate_assignment=True)
129
+
130
+ service_name: str = Field(description="Service name")
131
+ total_operations: int = Field(default=0, description="Total operations")
132
+ successful_operations: int = Field(default=0, description="Successful operations")
133
+ failed_operations: int = Field(default=0, description="Failed operations")
134
+ success_rate: float = Field(default=0.0, description="Success rate percentage")
135
+ avg_response_time_ms: Optional[float] = Field(None, description="Average response time")
136
+ last_operation: Optional[datetime] = Field(None, description="Last operation timestamp")
137
+ uptime_seconds: Optional[int] = Field(None, description="Service uptime in seconds")
138
+
139
+
140
+ class BatchOperationResult(ServiceOperationResult):
141
+ """Result of batch operations."""
142
+
143
+ total_items: int = Field(description="Total items processed")
144
+ successful_items: int = Field(description="Successfully processed items")
145
+ failed_items: int = Field(description="Failed items")
146
+ results: List[ServiceOperationResult] = Field(default_factory=list, description="Individual results")
147
+ processing_time_ms: Optional[int] = Field(None, description="Total processing time")
148
+
149
+
150
+ class CacheOperationResult(ServiceOperationResult):
151
+ """Result of cache operations."""
152
+
153
+ cache_key: Optional[str] = Field(None, description="Cache key")
154
+ cache_hit: Optional[bool] = Field(None, description="Whether cache was hit")
155
+ ttl_seconds: Optional[int] = Field(None, description="TTL in seconds")
156
+ data_size_bytes: Optional[int] = Field(None, description="Data size in bytes")