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.
- 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 -10
- 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 +526 -222
- django_cfg/apps/payments/admin/filters.py +306 -199
- django_cfg/apps/payments/admin/payments_admin.py +465 -70
- 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 +303 -151
- django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
- 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 +342 -152
- django_cfg/apps/payments/middleware/usage_tracking.py +249 -240
- django_cfg/apps/payments/migrations/0001_initial.py +708 -536
- django_cfg/apps/payments/models/__init__.py +13 -18
- 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 +172 -148
- 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 -285
- 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 +346 -467
- django_cfg/apps/payments/services/core/subscription_service.py +425 -481
- 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 +234 -174
- django_cfg/apps/payments/services/providers/nowpayments.py +478 -0
- django_cfg/apps/payments/services/providers/registry.py +367 -301
- 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 +210 -129
- django_cfg/apps/payments/signals/balance_signals.py +174 -0
- django_cfg/apps/payments/signals/payment_signals.py +128 -103
- django_cfg/apps/payments/signals/subscription_signals.py +194 -142
- 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 +45 -48
- django_cfg/apps/payments/urls_admin.py +33 -42
- 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/config.py +1 -1
- django_cfg/core/config.py +40 -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 -492
- django_cfg/modules/django_logger.py +160 -146
- django_cfg/modules/django_unfold/dashboard.py +64 -16
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/utils/smart_defaults.py +222 -571
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/METADATA +4 -1
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/RECORD +153 -185
- 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 -146
- django_cfg/apps/payments/management/commands/currency_stats.py +0 -304
- django_cfg/apps/payments/managers/__init__.py +0 -23
- 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 -306
- django_cfg/apps/payments/managers/payment_manager.py +0 -192
- django_cfg/apps/payments/managers/subscription_manager.py +0 -37
- django_cfg/apps/payments/managers/tariff_manager.py +0 -29
- django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +0 -241
- django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +0 -30
- django_cfg/apps/payments/models/events.py +0 -73
- django_cfg/apps/payments/serializers/__init__.py +0 -57
- 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 -63
- 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 -461
- 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 -76
- django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
- django_cfg/apps/payments/services/providers/cryptapi/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/cryptapi/config.py +0 -8
- django_cfg/apps/payments/services/providers/cryptapi/models.py +0 -192
- django_cfg/apps/payments/services/providers/cryptapi/provider.py +0 -439
- django_cfg/apps/payments/services/providers/cryptomus/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/cryptomus/models.py +0 -176
- django_cfg/apps/payments/services/providers/cryptomus/provider.py +0 -429
- django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +0 -564
- django_cfg/apps/payments/services/providers/models/__init__.py +0 -34
- django_cfg/apps/payments/services/providers/models/currencies.py +0 -190
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/nowpayments/models.py +0 -196
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +0 -380
- django_cfg/apps/payments/services/providers/stripe/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/stripe/models.py +0 -184
- django_cfg/apps/payments/services/providers/stripe/provider.py +0 -109
- django_cfg/apps/payments/services/security/__init__.py +0 -34
- django_cfg/apps/payments/services/security/error_handler.py +0 -635
- django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
- django_cfg/apps/payments/services/security/webhook_validator.py +0 -474
- 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/admin/payments/currency/change_list.html +0 -50
- 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 -43
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
- django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -34
- django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -148
- django_cfg/apps/payments/templates/payments/dashboard.html +0 -258
- django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +0 -35
- django_cfg/apps/payments/templates/payments/payment_create.html +0 -579
- django_cfg/apps/payments/templates/payments/payment_detail.html +0 -373
- django_cfg/apps/payments/templates/payments/payment_list.html +0 -354
- django_cfg/apps/payments/templates/payments/stats.html +0 -261
- django_cfg/apps/payments/templates/payments/test.html +0 -213
- django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
- django_cfg/apps/payments/utils/__init__.py +0 -43
- django_cfg/apps/payments/utils/billing_utils.py +0 -342
- django_cfg/apps/payments/utils/config_utils.py +0 -239
- 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 -63
- 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 -122
- 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 -451
- django_cfg/apps/payments/views/templates/base.py +0 -212
- 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 -158
- django_cfg/apps/payments/views/templates/qr_code.py +0 -174
- django_cfg/apps/payments/views/templates/stats.py +0 -244
- 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 -66
- django_cfg/core/integration.py +0 -160
- 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.31.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
- {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,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
|
-
]
|