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.
- 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/cleanup_expired_data.py +419 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +297 -225
- 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/management/commands/process_pending_payments.py +357 -0
- django_cfg/apps/payments/management/commands/test_providers.py +434 -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 +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 +153 -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_service/__init__.py +143 -0
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +37 -0
- django_cfg/apps/payments/services/{cache/base.py → cache_service/interfaces.py} +3 -1
- django_cfg/apps/payments/services/cache_service/keys.py +49 -0
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +47 -0
- django_cfg/apps/payments/services/cache_service/simple_cache.py +101 -0
- 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 +371 -465
- 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 +227 -570
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/METADATA +4 -1
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/RECORD +162 -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/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/simple_cache.py +0 -135
- 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.3.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
"""
|
2
|
+
Constance settings integration for Payments app.
|
3
|
+
|
4
|
+
Simplified settings management using Pydantic models and Constance.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, Any, Optional
|
8
|
+
from pydantic import BaseModel, Field
|
9
|
+
from django_cfg.modules.django_logger import get_logger
|
10
|
+
|
11
|
+
logger = get_logger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
class PaymentConstanceSettings(BaseModel):
|
15
|
+
"""
|
16
|
+
Pydantic model for payments Constance settings.
|
17
|
+
|
18
|
+
Provides type-safe access to dynamic settings with validation.
|
19
|
+
"""
|
20
|
+
|
21
|
+
# Core settings
|
22
|
+
enabled: bool = Field(default=True, description="Enable payments system")
|
23
|
+
middleware_enabled: bool = Field(default=True, description="Enable payments middleware")
|
24
|
+
|
25
|
+
# Rate limiting
|
26
|
+
rate_limiting_enabled: bool = Field(default=True, description="Enable rate limiting")
|
27
|
+
anonymous_rate_limit: int = Field(default=60, description="Anonymous user rate limit")
|
28
|
+
authenticated_rate_limit: int = Field(default=300, description="Authenticated user rate limit")
|
29
|
+
|
30
|
+
# Usage tracking
|
31
|
+
usage_tracking_enabled: bool = Field(default=True, description="Enable usage tracking")
|
32
|
+
track_anonymous_usage: bool = Field(default=False, description="Track anonymous usage")
|
33
|
+
|
34
|
+
# Cache timeouts
|
35
|
+
api_key_cache_timeout: int = Field(default=300, description="API key cache timeout")
|
36
|
+
rate_limit_cache_timeout: int = Field(default=3600, description="Rate limit cache timeout")
|
37
|
+
session_cache_timeout: int = Field(default=1800, description="Session cache timeout")
|
38
|
+
default_cache_timeout: int = Field(default=600, description="Default cache timeout")
|
39
|
+
|
40
|
+
# Provider settings
|
41
|
+
nowpayments_api_key: str = Field(default="", description="NowPayments API key")
|
42
|
+
nowpayments_ipn_secret: str = Field(default="", description="NowPayments IPN secret")
|
43
|
+
nowpayments_sandbox_mode: bool = Field(default=True, description="NowPayments sandbox mode")
|
44
|
+
|
45
|
+
# Currency settings
|
46
|
+
auto_update_rates: bool = Field(default=True, description="Auto update currency rates")
|
47
|
+
rate_update_interval_hours: int = Field(default=1, description="Rate update interval")
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
def from_constance(cls) -> 'PaymentConstanceSettings':
|
51
|
+
"""
|
52
|
+
Create instance from Constance settings.
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
PaymentConstanceSettings instance with current Constance values
|
56
|
+
"""
|
57
|
+
try:
|
58
|
+
from constance import config
|
59
|
+
from ..django_cfg_integration import PaymentsConfigManager
|
60
|
+
|
61
|
+
# Get defaults from initialized Pydantic config using PaymentsConfigManager
|
62
|
+
pydantic_config = PaymentsConfigManager.get_payments_config()
|
63
|
+
|
64
|
+
return cls(
|
65
|
+
# Static settings from Pydantic (not in Constance anymore)
|
66
|
+
enabled=pydantic_config.enabled,
|
67
|
+
middleware_enabled=pydantic_config.middleware_enabled,
|
68
|
+
rate_limiting_enabled=pydantic_config.rate_limiting_enabled,
|
69
|
+
anonymous_rate_limit=pydantic_config.default_rate_limits['anonymous'],
|
70
|
+
authenticated_rate_limit=pydantic_config.default_rate_limits['authenticated'],
|
71
|
+
usage_tracking_enabled=pydantic_config.usage_tracking_enabled,
|
72
|
+
|
73
|
+
# Dynamic settings from Constance (only what's actually in Constance)
|
74
|
+
track_anonymous_usage=getattr(config, 'PAYMENTS_TRACK_ANONYMOUS_USAGE', pydantic_config.track_anonymous_usage),
|
75
|
+
|
76
|
+
# Cache timeouts from Pydantic (not in Constance anymore)
|
77
|
+
api_key_cache_timeout=pydantic_config.cache_timeouts['api_key'],
|
78
|
+
rate_limit_cache_timeout=pydantic_config.cache_timeouts['rate_limit'],
|
79
|
+
session_cache_timeout=pydantic_config.cache_timeouts['session'],
|
80
|
+
default_cache_timeout=pydantic_config.cache_timeouts['default'],
|
81
|
+
|
82
|
+
# Provider settings from Constance (sensitive data)
|
83
|
+
nowpayments_api_key=getattr(config, 'PAYMENTS_NOWPAYMENTS_API_KEY', ''),
|
84
|
+
nowpayments_ipn_secret=getattr(config, 'PAYMENTS_NOWPAYMENTS_IPN_SECRET', ''),
|
85
|
+
nowpayments_sandbox_mode=getattr(config, 'PAYMENTS_NOWPAYMENTS_SANDBOX_MODE', True),
|
86
|
+
|
87
|
+
# Currency settings from Pydantic (automatic now)
|
88
|
+
auto_update_rates=True, # Always automatic
|
89
|
+
rate_update_interval_hours=1, # Fixed interval
|
90
|
+
)
|
91
|
+
except ImportError:
|
92
|
+
logger.warning("Constance not available, using default settings")
|
93
|
+
return cls()
|
94
|
+
|
95
|
+
def to_dict(self) -> Dict[str, Any]:
|
96
|
+
"""Convert to dictionary for easy access."""
|
97
|
+
return self.model_dump()
|
98
|
+
|
99
|
+
def get_rate_limits(self) -> Dict[str, int]:
|
100
|
+
"""Get rate limits as dictionary."""
|
101
|
+
return {
|
102
|
+
'anonymous': self.anonymous_rate_limit,
|
103
|
+
'authenticated': self.authenticated_rate_limit,
|
104
|
+
}
|
105
|
+
|
106
|
+
def get_cache_timeouts(self) -> Dict[str, int]:
|
107
|
+
"""Get cache timeouts as dictionary."""
|
108
|
+
return {
|
109
|
+
'api_key': self.api_key_cache_timeout,
|
110
|
+
'rate_limit': self.rate_limit_cache_timeout,
|
111
|
+
'session': self.session_cache_timeout,
|
112
|
+
'default': self.default_cache_timeout,
|
113
|
+
}
|
114
|
+
|
115
|
+
def get_provider_config(self, provider: str) -> Dict[str, Any]:
|
116
|
+
"""Get provider-specific configuration."""
|
117
|
+
if provider.lower() == 'nowpayments':
|
118
|
+
# Provider is enabled if it has API key configured
|
119
|
+
is_enabled = bool(self.nowpayments_api_key and self.nowpayments_api_key.strip())
|
120
|
+
return {
|
121
|
+
'enabled': is_enabled,
|
122
|
+
'api_key': self.nowpayments_api_key,
|
123
|
+
'ipn_secret': self.nowpayments_ipn_secret,
|
124
|
+
'sandbox_mode': self.nowpayments_sandbox_mode,
|
125
|
+
}
|
126
|
+
return {}
|
127
|
+
|
128
|
+
|
129
|
+
def get_payment_settings() -> PaymentConstanceSettings:
|
130
|
+
"""
|
131
|
+
Get current payment settings from Constance.
|
132
|
+
|
133
|
+
Returns:
|
134
|
+
PaymentConstanceSettings instance with current values
|
135
|
+
"""
|
136
|
+
return PaymentConstanceSettings.from_constance()
|
137
|
+
|
138
|
+
|
139
|
+
def is_feature_enabled(feature: str) -> bool:
|
140
|
+
"""
|
141
|
+
Check if a specific feature is enabled.
|
142
|
+
|
143
|
+
Args:
|
144
|
+
feature: Feature name (e.g., 'rate_limiting', 'usage_tracking')
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
True if feature is enabled, False otherwise
|
148
|
+
"""
|
149
|
+
settings = get_payment_settings()
|
150
|
+
|
151
|
+
feature_map = {
|
152
|
+
'payments': settings.enabled,
|
153
|
+
'middleware': settings.middleware_enabled,
|
154
|
+
'rate_limiting': settings.rate_limiting_enabled,
|
155
|
+
'usage_tracking': settings.usage_tracking_enabled,
|
156
|
+
'anonymous_tracking': settings.track_anonymous_usage,
|
157
|
+
'auto_rates': settings.auto_update_rates,
|
158
|
+
}
|
159
|
+
|
160
|
+
return feature_map.get(feature, False)
|
@@ -0,0 +1,202 @@
|
|
1
|
+
"""
|
2
|
+
Django-CFG integration for payments configuration.
|
3
|
+
|
4
|
+
Central place for accessing django-cfg PaymentsConfig with proper error handling
|
5
|
+
and caching. All payments modules should use this for configuration access.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from typing import Optional
|
9
|
+
from django_cfg.core.config import get_current_config
|
10
|
+
from django_cfg.modules.django_logger import get_logger
|
11
|
+
|
12
|
+
logger = get_logger("payments_django_cfg_integration")
|
13
|
+
|
14
|
+
|
15
|
+
class PaymentsConfigManager:
|
16
|
+
"""
|
17
|
+
Central manager for payments configuration access.
|
18
|
+
|
19
|
+
Provides cached, type-safe access to PaymentsConfig from django-cfg
|
20
|
+
with proper error handling and fallbacks.
|
21
|
+
"""
|
22
|
+
|
23
|
+
_payments_config_cache: Optional[any] = None
|
24
|
+
_cache_timestamp: float = 0
|
25
|
+
_cache_ttl: float = 60.0 # Cache for 60 seconds
|
26
|
+
|
27
|
+
@classmethod
|
28
|
+
def get_payments_config(cls, force_refresh: bool = False):
|
29
|
+
"""
|
30
|
+
Get payments configuration from django-cfg.
|
31
|
+
|
32
|
+
Args:
|
33
|
+
force_refresh: Force refresh from django-cfg (ignore cache)
|
34
|
+
|
35
|
+
Returns:
|
36
|
+
PaymentsConfig instance from current django-cfg config
|
37
|
+
|
38
|
+
Raises:
|
39
|
+
ValueError: If PaymentsConfig not found in current config
|
40
|
+
"""
|
41
|
+
import time
|
42
|
+
|
43
|
+
current_time = time.time()
|
44
|
+
|
45
|
+
# Check if cache is valid
|
46
|
+
if (not force_refresh and
|
47
|
+
cls._payments_config_cache is not None and
|
48
|
+
(current_time - cls._cache_timestamp) < cls._cache_ttl):
|
49
|
+
return cls._payments_config_cache
|
50
|
+
|
51
|
+
# Load fresh config
|
52
|
+
try:
|
53
|
+
current_config = get_current_config()
|
54
|
+
if current_config and hasattr(current_config, 'payments') and current_config.payments:
|
55
|
+
cls._payments_config_cache = current_config.payments
|
56
|
+
cls._cache_timestamp = current_time
|
57
|
+
logger.debug("Loaded PaymentsConfig from django-cfg")
|
58
|
+
return cls._payments_config_cache
|
59
|
+
else:
|
60
|
+
error_msg = "PaymentsConfig not found in current django-cfg config"
|
61
|
+
logger.error(error_msg)
|
62
|
+
raise ValueError(error_msg)
|
63
|
+
|
64
|
+
except Exception as e:
|
65
|
+
logger.error(f"Failed to load payments config: {e}")
|
66
|
+
raise
|
67
|
+
|
68
|
+
@classmethod
|
69
|
+
def get_payments_config_safe(cls, force_refresh: bool = False):
|
70
|
+
"""
|
71
|
+
Get payments configuration with fallback to defaults.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
force_refresh: Force refresh from django-cfg (ignore cache)
|
75
|
+
|
76
|
+
Returns:
|
77
|
+
PaymentsConfig instance (from django-cfg or defaults)
|
78
|
+
"""
|
79
|
+
try:
|
80
|
+
return cls.get_payments_config(force_refresh=force_refresh)
|
81
|
+
except Exception as e:
|
82
|
+
logger.warning(f"Using default PaymentsConfig due to error: {e}")
|
83
|
+
from django_cfg.models.payments import PaymentsConfig
|
84
|
+
return PaymentsConfig()
|
85
|
+
|
86
|
+
@classmethod
|
87
|
+
def is_payments_enabled(cls) -> bool:
|
88
|
+
"""
|
89
|
+
Check if payments module is enabled.
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
True if payments is enabled in django-cfg config
|
93
|
+
"""
|
94
|
+
try:
|
95
|
+
config = cls.get_payments_config()
|
96
|
+
return config.enabled
|
97
|
+
except Exception:
|
98
|
+
logger.warning("Failed to check payments enabled status, defaulting to False")
|
99
|
+
return False
|
100
|
+
|
101
|
+
@classmethod
|
102
|
+
def is_payments_configured(cls) -> bool:
|
103
|
+
"""
|
104
|
+
Check if payments is properly configured in django-cfg.
|
105
|
+
|
106
|
+
Returns:
|
107
|
+
True if PaymentsConfig exists in current config
|
108
|
+
"""
|
109
|
+
try:
|
110
|
+
cls.get_payments_config()
|
111
|
+
return True
|
112
|
+
except Exception:
|
113
|
+
return False
|
114
|
+
|
115
|
+
@classmethod
|
116
|
+
def reset_cache(cls):
|
117
|
+
"""Reset configuration cache."""
|
118
|
+
cls._payments_config_cache = None
|
119
|
+
cls._cache_timestamp = 0
|
120
|
+
logger.debug("PaymentsConfig cache reset")
|
121
|
+
|
122
|
+
@classmethod
|
123
|
+
def get_config_summary(cls) -> dict:
|
124
|
+
"""
|
125
|
+
Get summary of current payments configuration.
|
126
|
+
|
127
|
+
Returns:
|
128
|
+
Dictionary with configuration summary
|
129
|
+
"""
|
130
|
+
try:
|
131
|
+
config = cls.get_payments_config()
|
132
|
+
return {
|
133
|
+
'configured': True,
|
134
|
+
'enabled': config.enabled,
|
135
|
+
'middleware_enabled': config.middleware_enabled,
|
136
|
+
'rate_limiting_enabled': config.rate_limiting_enabled,
|
137
|
+
'usage_tracking_enabled': config.usage_tracking_enabled,
|
138
|
+
'cache_timeouts': config.cache_timeouts,
|
139
|
+
'api_prefixes': config.api_prefixes,
|
140
|
+
}
|
141
|
+
except Exception as e:
|
142
|
+
return {
|
143
|
+
'configured': False,
|
144
|
+
'error': str(e),
|
145
|
+
'enabled': False,
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
# Legacy compatibility - keep old interface
|
150
|
+
class PaymentsConfigMixin:
|
151
|
+
"""Legacy mixin for backward compatibility."""
|
152
|
+
|
153
|
+
@classmethod
|
154
|
+
def get_payments_config(cls):
|
155
|
+
"""Get payments configuration from django-cfg."""
|
156
|
+
return PaymentsConfigManager.get_payments_config_safe()
|
157
|
+
|
158
|
+
@classmethod
|
159
|
+
def reset_config_cache(cls):
|
160
|
+
"""Reset configuration cache."""
|
161
|
+
PaymentsConfigManager.reset_cache()
|
162
|
+
|
163
|
+
|
164
|
+
# Public API functions
|
165
|
+
def get_payments_config(safe: bool = True, force_refresh: bool = False):
|
166
|
+
"""
|
167
|
+
Get payments configuration from django-cfg.
|
168
|
+
|
169
|
+
Args:
|
170
|
+
safe: If True, return defaults on error. If False, raise exception.
|
171
|
+
force_refresh: Force refresh from django-cfg (ignore cache)
|
172
|
+
|
173
|
+
Returns:
|
174
|
+
PaymentsConfig instance
|
175
|
+
|
176
|
+
Raises:
|
177
|
+
ValueError: If safe=False and PaymentsConfig not found
|
178
|
+
"""
|
179
|
+
if safe:
|
180
|
+
return PaymentsConfigManager.get_payments_config_safe(force_refresh=force_refresh)
|
181
|
+
else:
|
182
|
+
return PaymentsConfigManager.get_payments_config(force_refresh=force_refresh)
|
183
|
+
|
184
|
+
|
185
|
+
def is_payments_enabled() -> bool:
|
186
|
+
"""Check if payments module is enabled."""
|
187
|
+
return PaymentsConfigManager.is_payments_enabled()
|
188
|
+
|
189
|
+
|
190
|
+
def is_payments_configured() -> bool:
|
191
|
+
"""Check if payments is properly configured in django-cfg."""
|
192
|
+
return PaymentsConfigManager.is_payments_configured()
|
193
|
+
|
194
|
+
|
195
|
+
def get_config_summary() -> dict:
|
196
|
+
"""Get summary of current payments configuration."""
|
197
|
+
return PaymentsConfigManager.get_config_summary()
|
198
|
+
|
199
|
+
|
200
|
+
def reset_payments_config_cache():
|
201
|
+
"""Reset payments configuration cache."""
|
202
|
+
PaymentsConfigManager.reset_cache()
|
@@ -0,0 +1,130 @@
|
|
1
|
+
"""
|
2
|
+
Configuration helpers for the Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Provides specialized helpers for different configuration aspects.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, Any
|
8
|
+
from django.conf import settings
|
9
|
+
|
10
|
+
from .django_cfg_integration import PaymentsConfigMixin
|
11
|
+
from django_cfg.modules.django_logger import get_logger
|
12
|
+
|
13
|
+
logger = get_logger("payments_config_helpers")
|
14
|
+
|
15
|
+
|
16
|
+
class MiddlewareConfigHelper(PaymentsConfigMixin):
|
17
|
+
"""Helper for middleware configuration."""
|
18
|
+
|
19
|
+
@classmethod
|
20
|
+
def get_middleware_config(cls) -> Dict[str, Any]:
|
21
|
+
"""Get middleware configuration combining django-cfg and Constance."""
|
22
|
+
config = cls.get_payments_config()
|
23
|
+
|
24
|
+
# Get Constance settings for dynamic config
|
25
|
+
try:
|
26
|
+
from .constance import get_payment_config_service
|
27
|
+
config_service = get_payment_config_service()
|
28
|
+
constance_settings = config_service.get_constance_settings()
|
29
|
+
except Exception as e:
|
30
|
+
logger.warning(f"Failed to load Constance settings: {e}")
|
31
|
+
constance_settings = None
|
32
|
+
|
33
|
+
return {
|
34
|
+
# Static settings from django-cfg
|
35
|
+
'enabled': config.enabled and config.middleware_enabled,
|
36
|
+
'api_prefixes': config.api_prefixes,
|
37
|
+
'exempt_paths': config.exempt_paths,
|
38
|
+
'rate_limiting_enabled': config.rate_limiting_enabled,
|
39
|
+
'default_rate_limits': config.default_rate_limits,
|
40
|
+
'usage_tracking_enabled': config.usage_tracking_enabled,
|
41
|
+
'track_anonymous_usage': config.track_anonymous_usage,
|
42
|
+
'cache_timeouts': config.cache_timeouts,
|
43
|
+
|
44
|
+
# Dynamic settings from Constance (if available)
|
45
|
+
'constance_settings': constance_settings,
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
class CacheConfigHelper(PaymentsConfigMixin):
|
50
|
+
"""Helper for cache configuration."""
|
51
|
+
|
52
|
+
@classmethod
|
53
|
+
def get_cache_backend_type(cls) -> str:
|
54
|
+
"""Get Django cache backend type."""
|
55
|
+
django_cache = getattr(settings, 'CACHES', {}).get('default', {})
|
56
|
+
backend = django_cache.get('BACKEND', '').lower()
|
57
|
+
|
58
|
+
if 'redis' in backend:
|
59
|
+
return 'redis'
|
60
|
+
elif 'memcached' in backend:
|
61
|
+
return 'memcached'
|
62
|
+
elif 'database' in backend:
|
63
|
+
return 'database'
|
64
|
+
elif 'dummy' in backend:
|
65
|
+
return 'dummy'
|
66
|
+
else:
|
67
|
+
return 'unknown'
|
68
|
+
|
69
|
+
@classmethod
|
70
|
+
def is_cache_enabled(cls) -> bool:
|
71
|
+
"""Check if cache is properly configured (not dummy)."""
|
72
|
+
return cls.get_cache_backend_type() != 'dummy'
|
73
|
+
|
74
|
+
@classmethod
|
75
|
+
def get_cache_timeout(cls, operation: str) -> int:
|
76
|
+
"""Get cache timeout for specific operation."""
|
77
|
+
config = cls.get_payments_config()
|
78
|
+
return config.cache_timeouts.get(operation, config.cache_timeouts['default'])
|
79
|
+
|
80
|
+
|
81
|
+
class RedisConfigHelper(PaymentsConfigMixin):
|
82
|
+
"""Helper for Redis configuration."""
|
83
|
+
|
84
|
+
@classmethod
|
85
|
+
def get_redis_config(cls) -> Dict[str, Any]:
|
86
|
+
"""Get Redis configuration for payments."""
|
87
|
+
# Default Redis settings
|
88
|
+
redis_config = {
|
89
|
+
'host': 'localhost',
|
90
|
+
'port': 6379,
|
91
|
+
'db': 0,
|
92
|
+
'decode_responses': True,
|
93
|
+
'socket_timeout': 5,
|
94
|
+
'socket_connect_timeout': 5,
|
95
|
+
'retry_on_timeout': True,
|
96
|
+
'health_check_interval': 30,
|
97
|
+
}
|
98
|
+
|
99
|
+
# Try to get Redis settings from Django CACHES
|
100
|
+
django_cache = getattr(settings, 'CACHES', {}).get('default', {})
|
101
|
+
if 'redis' in django_cache.get('BACKEND', '').lower():
|
102
|
+
location = django_cache.get('LOCATION', '')
|
103
|
+
if location.startswith('redis://'):
|
104
|
+
# Parse redis://host:port/db format
|
105
|
+
try:
|
106
|
+
# Simple parsing for redis://host:port/db
|
107
|
+
parts = location.replace('redis://', '').split('/')
|
108
|
+
host_port = parts[0].split(':')
|
109
|
+
redis_config['host'] = host_port[0]
|
110
|
+
if len(host_port) > 1:
|
111
|
+
redis_config['port'] = int(host_port[1])
|
112
|
+
if len(parts) > 1:
|
113
|
+
redis_config['db'] = int(parts[1])
|
114
|
+
except (ValueError, IndexError) as e:
|
115
|
+
logger.warning(f"Failed to parse Redis URL {location}: {e}")
|
116
|
+
|
117
|
+
return redis_config
|
118
|
+
|
119
|
+
@classmethod
|
120
|
+
def is_redis_available(cls) -> bool:
|
121
|
+
"""Check if Redis is available and configured."""
|
122
|
+
try:
|
123
|
+
import redis
|
124
|
+
config = cls.get_redis_config()
|
125
|
+
client = redis.Redis(**config)
|
126
|
+
client.ping()
|
127
|
+
return True
|
128
|
+
except Exception as e:
|
129
|
+
logger.debug(f"Redis not available: {e}")
|
130
|
+
return False
|