django-cfg 1.2.29__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.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/api/health/views.py +4 -2
- django_cfg/apps/knowbase/config/settings.py +16 -15
- django_cfg/apps/payments/README.md +326 -0
- django_cfg/apps/payments/admin/__init__.py +20 -9
- django_cfg/apps/payments/admin/api_keys_admin.py +521 -237
- django_cfg/apps/payments/admin/balance_admin.py +592 -297
- django_cfg/apps/payments/admin/currencies_admin.py +600 -108
- django_cfg/apps/payments/admin/filters.py +306 -199
- django_cfg/apps/payments/admin/payments_admin.py +470 -64
- django_cfg/apps/payments/admin/subscriptions_admin.py +578 -128
- django_cfg/apps/payments/admin_interface/__init__.py +18 -0
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +162 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +38 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/loading_spinner.html +16 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/notification.html +27 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/provider_card.html +86 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +39 -0
- django_cfg/apps/payments/admin_interface/templates/payments/currency_converter.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +300 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +303 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_status.html +500 -0
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +594 -0
- django_cfg/apps/payments/admin_interface/views/__init__.py +23 -0
- django_cfg/apps/payments/admin_interface/views/payment_views.py +259 -0
- django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +37 -0
- django_cfg/apps/payments/apps.py +34 -9
- django_cfg/apps/payments/config/__init__.py +28 -51
- django_cfg/apps/payments/config/constance/__init__.py +22 -0
- django_cfg/apps/payments/config/constance/config_service.py +123 -0
- django_cfg/apps/payments/config/constance/fields.py +69 -0
- django_cfg/apps/payments/config/constance/settings.py +160 -0
- django_cfg/apps/payments/config/django_cfg_integration.py +202 -0
- django_cfg/apps/payments/config/helpers.py +130 -0
- django_cfg/apps/payments/management/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/manage_currencies.py +381 -0
- django_cfg/apps/payments/management/commands/manage_providers.py +408 -0
- django_cfg/apps/payments/middleware/__init__.py +3 -1
- django_cfg/apps/payments/middleware/api_access.py +329 -222
- django_cfg/apps/payments/middleware/rate_limiting.py +343 -163
- django_cfg/apps/payments/middleware/usage_tracking.py +250 -238
- django_cfg/apps/payments/migrations/0001_initial.py +708 -536
- django_cfg/apps/payments/models/__init__.py +16 -20
- django_cfg/apps/payments/models/api_keys.py +121 -43
- django_cfg/apps/payments/models/balance.py +150 -115
- django_cfg/apps/payments/models/base.py +68 -15
- django_cfg/apps/payments/models/currencies.py +207 -67
- django_cfg/apps/payments/models/managers/__init__.py +44 -0
- django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
- django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
- django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
- django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
- django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
- django_cfg/apps/payments/models/payments.py +235 -284
- django_cfg/apps/payments/models/subscriptions.py +257 -177
- django_cfg/apps/payments/models/tariffs.py +147 -40
- django_cfg/apps/payments/services/__init__.py +209 -56
- django_cfg/apps/payments/services/cache/__init__.py +6 -6
- django_cfg/apps/payments/services/cache/{simple_cache.py → cache_service.py} +112 -12
- django_cfg/apps/payments/services/core/__init__.py +10 -6
- django_cfg/apps/payments/services/core/balance_service.py +435 -360
- django_cfg/apps/payments/services/core/base.py +166 -0
- django_cfg/apps/payments/services/core/currency_service.py +478 -0
- django_cfg/apps/payments/services/core/payment_service.py +344 -468
- django_cfg/apps/payments/services/core/subscription_service.py +425 -484
- django_cfg/apps/payments/services/core/webhook_service.py +410 -0
- django_cfg/apps/payments/services/integrations/__init__.py +29 -0
- django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
- django_cfg/apps/payments/services/providers/__init__.py +9 -14
- django_cfg/apps/payments/services/providers/base.py +232 -71
- django_cfg/apps/payments/services/providers/nowpayments.py +404 -219
- django_cfg/apps/payments/services/providers/registry.py +429 -80
- django_cfg/apps/payments/services/types/__init__.py +78 -0
- django_cfg/apps/payments/services/types/data.py +177 -0
- django_cfg/apps/payments/services/types/requests.py +150 -0
- django_cfg/apps/payments/services/types/responses.py +156 -0
- django_cfg/apps/payments/services/types/webhooks.py +232 -0
- django_cfg/apps/payments/signals/__init__.py +33 -8
- django_cfg/apps/payments/signals/api_key_signals.py +211 -130
- django_cfg/apps/payments/signals/balance_signals.py +174 -0
- django_cfg/apps/payments/signals/payment_signals.py +129 -98
- django_cfg/apps/payments/signals/subscription_signals.py +195 -143
- django_cfg/apps/payments/static/payments/css/components.css +380 -0
- django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
- django_cfg/apps/payments/static/payments/js/components.js +545 -0
- django_cfg/apps/payments/static/payments/js/utils.js +412 -0
- django_cfg/apps/payments/templatetags/__init__.py +1 -1
- django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
- django_cfg/apps/payments/urls.py +46 -47
- django_cfg/apps/payments/urls_admin.py +49 -0
- django_cfg/apps/payments/views/api/__init__.py +101 -0
- django_cfg/apps/payments/views/api/api_keys.py +387 -0
- django_cfg/apps/payments/views/api/balances.py +381 -0
- django_cfg/apps/payments/views/api/base.py +298 -0
- django_cfg/apps/payments/views/api/currencies.py +402 -0
- django_cfg/apps/payments/views/api/payments.py +415 -0
- django_cfg/apps/payments/views/api/subscriptions.py +475 -0
- django_cfg/apps/payments/views/api/webhooks.py +476 -0
- django_cfg/apps/payments/views/serializers/__init__.py +99 -0
- django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
- django_cfg/apps/payments/views/serializers/balances.py +300 -0
- django_cfg/apps/payments/views/serializers/currencies.py +335 -0
- django_cfg/apps/payments/views/serializers/payments.py +387 -0
- django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
- django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
- django_cfg/apps/tasks/urls.py +0 -2
- django_cfg/apps/tasks/urls_admin.py +14 -0
- django_cfg/apps/urls.py +4 -4
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +75 -4
- django_cfg/core/generation.py +25 -4
- django_cfg/core/integration/README.md +363 -0
- django_cfg/core/integration/__init__.py +47 -0
- django_cfg/core/integration/commands_collector.py +239 -0
- django_cfg/core/integration/display/__init__.py +15 -0
- django_cfg/core/integration/display/base.py +157 -0
- django_cfg/core/integration/display/ngrok.py +164 -0
- django_cfg/core/integration/display/startup.py +815 -0
- django_cfg/core/integration/url_integration.py +123 -0
- django_cfg/core/integration/version_checker.py +160 -0
- django_cfg/management/commands/auto_generate.py +4 -0
- django_cfg/management/commands/check_settings.py +6 -0
- django_cfg/management/commands/clear_constance.py +5 -2
- django_cfg/management/commands/create_token.py +6 -0
- django_cfg/management/commands/list_urls.py +6 -0
- django_cfg/management/commands/migrate_all.py +6 -0
- django_cfg/management/commands/migrator.py +3 -0
- django_cfg/management/commands/rundramatiq.py +6 -0
- django_cfg/management/commands/runserver_ngrok.py +51 -29
- django_cfg/management/commands/script.py +6 -0
- django_cfg/management/commands/show_config.py +12 -2
- django_cfg/management/commands/show_urls.py +4 -0
- django_cfg/management/commands/superuser.py +6 -0
- django_cfg/management/commands/task_clear.py +4 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -0
- django_cfg/management/commands/test_telegram.py +6 -0
- django_cfg/management/commands/test_twilio.py +6 -0
- django_cfg/management/commands/tree.py +6 -0
- django_cfg/management/commands/validate_config.py +155 -149
- django_cfg/models/constance.py +31 -11
- django_cfg/models/payments.py +175 -498
- django_cfg/modules/django_currency/__init__.py +16 -11
- django_cfg/modules/django_currency/clients/__init__.py +4 -4
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
- django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
- django_cfg/modules/django_currency/core/__init__.py +1 -7
- django_cfg/modules/django_currency/core/converter.py +18 -23
- django_cfg/modules/django_currency/core/models.py +122 -11
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +190 -309
- django_cfg/modules/django_logger.py +160 -146
- django_cfg/modules/django_unfold/dashboard.py +65 -12
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/admin/components/action_grid.html +9 -9
- django_cfg/templates/admin/components/metric_card.html +5 -5
- django_cfg/templates/admin/components/status_badge.html +2 -2
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
- django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
- django_cfg/templates/admin/snippets/components/system_health.html +1 -1
- django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
- django_cfg/utils/smart_defaults.py +222 -571
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/METADATA +5 -4
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/RECORD +172 -182
- django_cfg/apps/payments/__init__.py +0 -8
- django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
- django_cfg/apps/payments/config/module.py +0 -70
- django_cfg/apps/payments/config/providers.py +0 -105
- django_cfg/apps/payments/config/settings.py +0 -96
- django_cfg/apps/payments/config/utils.py +0 -52
- django_cfg/apps/payments/decorators.py +0 -291
- django_cfg/apps/payments/management/commands/README.md +0 -178
- django_cfg/apps/payments/management/commands/currency_stats.py +0 -323
- django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
- django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
- django_cfg/apps/payments/managers/__init__.py +0 -22
- django_cfg/apps/payments/managers/api_key_manager.py +0 -35
- django_cfg/apps/payments/managers/balance_manager.py +0 -361
- django_cfg/apps/payments/managers/currency_manager.py +0 -83
- django_cfg/apps/payments/managers/payment_manager.py +0 -44
- django_cfg/apps/payments/managers/subscription_manager.py +0 -37
- django_cfg/apps/payments/managers/tariff_manager.py +0 -29
- django_cfg/apps/payments/models/events.py +0 -73
- django_cfg/apps/payments/serializers/__init__.py +0 -56
- django_cfg/apps/payments/serializers/api_keys.py +0 -51
- django_cfg/apps/payments/serializers/balance.py +0 -59
- django_cfg/apps/payments/serializers/currencies.py +0 -55
- django_cfg/apps/payments/serializers/payments.py +0 -62
- django_cfg/apps/payments/serializers/subscriptions.py +0 -71
- django_cfg/apps/payments/serializers/tariffs.py +0 -56
- django_cfg/apps/payments/services/billing/__init__.py +0 -8
- django_cfg/apps/payments/services/cache/base.py +0 -30
- django_cfg/apps/payments/services/core/fallback_service.py +0 -432
- django_cfg/apps/payments/services/internal_types.py +0 -297
- django_cfg/apps/payments/services/middleware/__init__.py +0 -8
- django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
- django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -222
- django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
- django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
- django_cfg/apps/payments/services/providers/cryptomus.py +0 -311
- django_cfg/apps/payments/services/security/__init__.py +0 -34
- django_cfg/apps/payments/services/security/error_handler.py +0 -637
- django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
- django_cfg/apps/payments/services/security/webhook_validator.py +0 -475
- django_cfg/apps/payments/services/validators/__init__.py +0 -8
- django_cfg/apps/payments/static/payments/css/payments.css +0 -340
- django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
- django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
- django_cfg/apps/payments/static/payments/js/theme.js +0 -86
- django_cfg/apps/payments/tasks/__init__.py +0 -12
- django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
- django_cfg/apps/payments/templates/payments/base.html +0 -182
- django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -36
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
- django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -27
- django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -144
- django_cfg/apps/payments/templates/payments/dashboard.html +0 -346
- django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
- django_cfg/apps/payments/urls_templates.py +0 -52
- django_cfg/apps/payments/utils/__init__.py +0 -45
- django_cfg/apps/payments/utils/billing_utils.py +0 -342
- django_cfg/apps/payments/utils/config_utils.py +0 -245
- django_cfg/apps/payments/utils/middleware_utils.py +0 -228
- django_cfg/apps/payments/utils/validation_utils.py +0 -94
- django_cfg/apps/payments/views/__init__.py +0 -62
- django_cfg/apps/payments/views/api_key_views.py +0 -164
- django_cfg/apps/payments/views/balance_views.py +0 -75
- django_cfg/apps/payments/views/currency_views.py +0 -111
- django_cfg/apps/payments/views/payment_views.py +0 -149
- django_cfg/apps/payments/views/subscription_views.py +0 -135
- django_cfg/apps/payments/views/tariff_views.py +0 -131
- django_cfg/apps/payments/views/templates/__init__.py +0 -25
- django_cfg/apps/payments/views/templates/ajax.py +0 -312
- django_cfg/apps/payments/views/templates/base.py +0 -204
- django_cfg/apps/payments/views/templates/dashboard.py +0 -60
- django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
- django_cfg/apps/payments/views/templates/payment_management.py +0 -164
- django_cfg/apps/payments/views/templates/qr_code.py +0 -174
- django_cfg/apps/payments/views/templates/stats.py +0 -240
- django_cfg/apps/payments/views/templates/utils.py +0 -181
- django_cfg/apps/payments/views/webhook_views.py +0 -266
- django_cfg/apps/payments/viewsets.py +0 -65
- django_cfg/core/integration.py +0 -160
- django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
- django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
- django_cfg/template_archive/.gitignore +0 -1
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/urls.py +0 -33
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -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")
|