django-cfg 1.2.23__py3-none-any.whl → 1.2.27__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/knowbase/tasks/archive_tasks.py +6 -6
- django_cfg/apps/knowbase/tasks/document_processing.py +3 -3
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +2 -2
- django_cfg/apps/knowbase/tasks/maintenance.py +3 -3
- django_cfg/apps/payments/config/__init__.py +15 -37
- django_cfg/apps/payments/config/module.py +30 -122
- django_cfg/apps/payments/config/providers.py +28 -16
- django_cfg/apps/payments/config/settings.py +53 -93
- django_cfg/apps/payments/config/utils.py +10 -156
- django_cfg/apps/payments/management/__init__.py +3 -0
- django_cfg/apps/payments/management/commands/README.md +178 -0
- django_cfg/apps/payments/management/commands/__init__.py +3 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +323 -0
- django_cfg/apps/payments/management/commands/populate_currencies.py +246 -0
- django_cfg/apps/payments/management/commands/update_currencies.py +336 -0
- django_cfg/apps/payments/managers/currency_manager.py +65 -14
- django_cfg/apps/payments/middleware/api_access.py +33 -0
- django_cfg/apps/payments/migrations/0001_initial.py +94 -1
- django_cfg/apps/payments/models/payments.py +110 -0
- django_cfg/apps/payments/services/__init__.py +7 -1
- django_cfg/apps/payments/services/core/balance_service.py +14 -16
- django_cfg/apps/payments/services/core/fallback_service.py +432 -0
- django_cfg/apps/payments/services/core/payment_service.py +212 -29
- django_cfg/apps/payments/services/core/subscription_service.py +15 -17
- django_cfg/apps/payments/services/internal_types.py +31 -0
- django_cfg/apps/payments/services/monitoring/__init__.py +22 -0
- django_cfg/apps/payments/services/monitoring/api_schemas.py +222 -0
- django_cfg/apps/payments/services/monitoring/provider_health.py +372 -0
- django_cfg/apps/payments/services/providers/__init__.py +3 -0
- django_cfg/apps/payments/services/providers/cryptapi.py +14 -3
- django_cfg/apps/payments/services/providers/cryptomus.py +310 -0
- django_cfg/apps/payments/services/providers/registry.py +4 -0
- django_cfg/apps/payments/services/security/__init__.py +34 -0
- django_cfg/apps/payments/services/security/error_handler.py +637 -0
- django_cfg/apps/payments/services/security/payment_notifications.py +342 -0
- django_cfg/apps/payments/services/security/webhook_validator.py +475 -0
- django_cfg/apps/payments/signals/api_key_signals.py +10 -0
- django_cfg/apps/payments/signals/payment_signals.py +3 -2
- django_cfg/apps/payments/tasks/__init__.py +12 -0
- django_cfg/apps/payments/tasks/webhook_processing.py +177 -0
- django_cfg/apps/payments/utils/__init__.py +7 -4
- django_cfg/apps/payments/utils/billing_utils.py +342 -0
- django_cfg/apps/payments/utils/config_utils.py +2 -0
- django_cfg/apps/payments/views/payment_views.py +40 -2
- django_cfg/apps/payments/views/webhook_views.py +266 -0
- django_cfg/apps/payments/viewsets.py +65 -0
- django_cfg/cli/README.md +2 -2
- django_cfg/cli/commands/create_project.py +1 -1
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/cli/main.py +1 -1
- django_cfg/cli/utils.py +5 -5
- django_cfg/core/config.py +18 -4
- django_cfg/models/payments.py +547 -0
- django_cfg/models/tasks.py +51 -2
- django_cfg/modules/base.py +11 -5
- django_cfg/modules/django_currency/README.md +104 -269
- django_cfg/modules/django_currency/__init__.py +99 -41
- django_cfg/modules/django_currency/clients/__init__.py +11 -0
- django_cfg/modules/django_currency/clients/coingecko_client.py +257 -0
- django_cfg/modules/django_currency/clients/yfinance_client.py +246 -0
- django_cfg/modules/django_currency/core/__init__.py +42 -0
- django_cfg/modules/django_currency/core/converter.py +169 -0
- django_cfg/modules/django_currency/core/exceptions.py +28 -0
- django_cfg/modules/django_currency/core/models.py +54 -0
- django_cfg/modules/django_currency/database/__init__.py +25 -0
- django_cfg/modules/django_currency/database/database_loader.py +507 -0
- django_cfg/modules/django_currency/utils/__init__.py +9 -0
- django_cfg/modules/django_currency/utils/cache.py +92 -0
- django_cfg/registry/core.py +10 -0
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/METADATA +10 -6
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/RECORD +77 -51
- django_cfg/apps/agents/examples/__init__.py +0 -3
- django_cfg/apps/agents/examples/simple_example.py +0 -161
- django_cfg/apps/knowbase/examples/__init__.py +0 -3
- django_cfg/apps/knowbase/examples/external_data_usage.py +0 -191
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +0 -199
- django_cfg/modules/django_currency/cache.py +0 -430
- django_cfg/modules/django_currency/converter.py +0 -324
- django_cfg/modules/django_currency/service.py +0 -277
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/licenses/LICENSE +0 -0
django_cfg/__init__.py
CHANGED
@@ -23,7 +23,7 @@ User = get_user_model()
|
|
23
23
|
|
24
24
|
|
25
25
|
@dramatiq.actor(
|
26
|
-
queue_name="
|
26
|
+
queue_name="knowbase",
|
27
27
|
max_retries=3,
|
28
28
|
min_backoff=1000, # 1 second
|
29
29
|
max_backoff=30000, # 30 seconds
|
@@ -96,7 +96,7 @@ def process_archive_task(archive_id: str, user_id: str) -> bool:
|
|
96
96
|
|
97
97
|
|
98
98
|
@dramatiq.actor(
|
99
|
-
queue_name="
|
99
|
+
queue_name="knowbase",
|
100
100
|
max_retries=2,
|
101
101
|
min_backoff=2000, # 2 seconds
|
102
102
|
max_backoff=60000, # 60 seconds
|
@@ -154,7 +154,7 @@ def vectorize_archive_items_task(archive_id: str, user_id: str) -> int:
|
|
154
154
|
|
155
155
|
|
156
156
|
@dramatiq.actor(
|
157
|
-
queue_name="
|
157
|
+
queue_name="knowbase",
|
158
158
|
max_retries=1,
|
159
159
|
priority=2
|
160
160
|
)
|
@@ -193,7 +193,7 @@ def cleanup_failed_archives_task(days_old: int = 7) -> int:
|
|
193
193
|
|
194
194
|
|
195
195
|
@dramatiq.actor(
|
196
|
-
queue_name="
|
196
|
+
queue_name="knowbase",
|
197
197
|
max_retries=1,
|
198
198
|
priority=1
|
199
199
|
)
|
@@ -239,7 +239,7 @@ def generate_archive_statistics_task(user_id: str) -> Dict[str, Any]:
|
|
239
239
|
|
240
240
|
|
241
241
|
@dramatiq.actor(
|
242
|
-
queue_name="
|
242
|
+
queue_name="knowbase",
|
243
243
|
max_retries=1,
|
244
244
|
priority=1
|
245
245
|
)
|
@@ -297,7 +297,7 @@ def archive_health_check_task() -> Dict[str, Any]:
|
|
297
297
|
|
298
298
|
# Test task for development
|
299
299
|
@dramatiq.actor(
|
300
|
-
queue_name="
|
300
|
+
queue_name="knowbase",
|
301
301
|
max_retries=0,
|
302
302
|
priority=1
|
303
303
|
)
|
@@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
|
|
20
20
|
|
21
21
|
|
22
22
|
@dramatiq.actor(
|
23
|
-
queue_name="
|
23
|
+
queue_name="knowbase",
|
24
24
|
max_retries=3,
|
25
25
|
min_backoff=1000, # 1 second
|
26
26
|
max_backoff=30000, # 30 seconds
|
@@ -239,7 +239,7 @@ def generate_embeddings_batch(
|
|
239
239
|
|
240
240
|
|
241
241
|
@dramatiq.actor(
|
242
|
-
queue_name="
|
242
|
+
queue_name="knowbase",
|
243
243
|
max_retries=2,
|
244
244
|
priority=7 # Higher priority for reprocessing
|
245
245
|
)
|
@@ -291,7 +291,7 @@ def reprocess_document_chunks(
|
|
291
291
|
|
292
292
|
|
293
293
|
@dramatiq.actor(
|
294
|
-
queue_name="
|
294
|
+
queue_name="knowbase",
|
295
295
|
max_retries=2,
|
296
296
|
priority=4
|
297
297
|
)
|
@@ -16,7 +16,7 @@ logger = logging.getLogger(__name__)
|
|
16
16
|
|
17
17
|
|
18
18
|
@dramatiq.actor(
|
19
|
-
queue_name="
|
19
|
+
queue_name="knowbase",
|
20
20
|
max_retries=3,
|
21
21
|
min_backoff=1000, # 1 second
|
22
22
|
max_backoff=30000, # 30 seconds
|
@@ -158,7 +158,7 @@ def process_external_data_async(
|
|
158
158
|
|
159
159
|
|
160
160
|
@dramatiq.actor(
|
161
|
-
queue_name="
|
161
|
+
queue_name="knowbase",
|
162
162
|
max_retries=2,
|
163
163
|
min_backoff=5000, # 5 seconds
|
164
164
|
max_backoff=60000, # 60 seconds
|
@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
|
|
18
18
|
|
19
19
|
|
20
20
|
@dramatiq.actor(
|
21
|
-
queue_name="
|
21
|
+
queue_name="knowbase",
|
22
22
|
max_retries=1,
|
23
23
|
priority=2
|
24
24
|
)
|
@@ -72,7 +72,7 @@ def cleanup_old_embeddings(days_old: int = 90) -> Dict[str, Any]:
|
|
72
72
|
|
73
73
|
|
74
74
|
@dramatiq.actor(
|
75
|
-
queue_name="
|
75
|
+
queue_name="knowbase",
|
76
76
|
max_retries=1,
|
77
77
|
priority=1
|
78
78
|
)
|
@@ -119,7 +119,7 @@ def optimize_vector_indexes() -> Dict[str, Any]:
|
|
119
119
|
|
120
120
|
|
121
121
|
@dramatiq.actor(
|
122
|
-
queue_name="
|
122
|
+
queue_name="knowbase",
|
123
123
|
max_retries=1,
|
124
124
|
priority=1
|
125
125
|
)
|
@@ -5,25 +5,27 @@ Modular configuration system for the payments module.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
# Core configuration classes
|
8
|
-
from .settings import
|
9
|
-
|
8
|
+
from .settings import PaymentsSettings
|
9
|
+
|
10
|
+
# Import unified settings from models.payments
|
11
|
+
from django_cfg.models.payments import (
|
10
12
|
SecuritySettings,
|
11
13
|
RateLimitSettings,
|
12
|
-
|
13
|
-
|
14
|
-
NotificationSettings
|
14
|
+
NotificationSettings,
|
15
|
+
SubscriptionSettings
|
15
16
|
)
|
16
17
|
|
17
|
-
# Provider configurations
|
18
|
-
from .
|
18
|
+
# Provider configurations - import from models.payments
|
19
|
+
from django_cfg.models.payments import (
|
19
20
|
PaymentProviderConfig,
|
20
21
|
NowPaymentsConfig,
|
21
22
|
StripeConfig,
|
22
|
-
CryptAPIConfig
|
23
|
-
get_provider_config_class,
|
24
|
-
PROVIDER_CONFIGS
|
23
|
+
CryptAPIConfig
|
25
24
|
)
|
26
25
|
|
26
|
+
# Local provider configs (additional to models.payments)
|
27
|
+
from .providers import CryptomusConfig
|
28
|
+
|
27
29
|
# Configuration module
|
28
30
|
from .module import PaymentsCfgModule
|
29
31
|
|
@@ -31,18 +33,7 @@ from .module import PaymentsCfgModule
|
|
31
33
|
from .utils import (
|
32
34
|
get_payments_config,
|
33
35
|
get_provider_config,
|
34
|
-
|
35
|
-
get_stripe_config,
|
36
|
-
is_payments_enabled,
|
37
|
-
is_feature_enabled,
|
38
|
-
get_enabled_providers,
|
39
|
-
get_provider_settings,
|
40
|
-
validate_provider_config,
|
41
|
-
get_rate_limit_settings,
|
42
|
-
get_cache_settings,
|
43
|
-
get_billing_settings,
|
44
|
-
reset_config_cache,
|
45
|
-
reload_config
|
36
|
+
is_payments_enabled
|
46
37
|
)
|
47
38
|
|
48
39
|
# Backwards compatibility exports
|
@@ -53,17 +44,15 @@ __all__ = [
|
|
53
44
|
'PaymentsSettings',
|
54
45
|
'SecuritySettings',
|
55
46
|
'RateLimitSettings',
|
56
|
-
'BillingSettings',
|
57
|
-
'CacheSettings',
|
58
47
|
'NotificationSettings',
|
48
|
+
'SubscriptionSettings',
|
59
49
|
|
60
50
|
# Provider configurations
|
61
51
|
'PaymentProviderConfig',
|
62
52
|
'NowPaymentsConfig',
|
63
53
|
'StripeConfig',
|
64
54
|
'CryptAPIConfig',
|
65
|
-
'
|
66
|
-
'PROVIDER_CONFIGS',
|
55
|
+
'CryptomusConfig',
|
67
56
|
|
68
57
|
# Configuration module
|
69
58
|
'PaymentsCfgModule',
|
@@ -72,16 +61,5 @@ __all__ = [
|
|
72
61
|
# Utility functions
|
73
62
|
'get_payments_config',
|
74
63
|
'get_provider_config',
|
75
|
-
'get_nowpayments_config',
|
76
|
-
'get_stripe_config',
|
77
64
|
'is_payments_enabled',
|
78
|
-
'is_feature_enabled',
|
79
|
-
'get_enabled_providers',
|
80
|
-
'get_provider_settings',
|
81
|
-
'validate_provider_config',
|
82
|
-
'get_rate_limit_settings',
|
83
|
-
'get_cache_settings',
|
84
|
-
'get_billing_settings',
|
85
|
-
'reset_config_cache',
|
86
|
-
'reload_config',
|
87
65
|
]
|
@@ -5,12 +5,10 @@ Handles loading and managing payment configurations from project settings.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
from typing import Optional
|
8
|
-
from pydantic import SecretStr
|
9
8
|
import logging
|
10
9
|
|
11
10
|
from django_cfg.modules.base import BaseCfgModule
|
12
11
|
from .settings import PaymentsSettings
|
13
|
-
from .providers import NowPaymentsConfig, StripeConfig, CryptAPIConfig, get_provider_config_class
|
14
12
|
|
15
13
|
logger = logging.getLogger(__name__)
|
16
14
|
|
@@ -39,124 +37,34 @@ class PaymentsCfgModule(BaseCfgModule):
|
|
39
37
|
|
40
38
|
def load_from_project_config(self, config) -> PaymentsSettings:
|
41
39
|
"""Load payments configuration from main project config."""
|
42
|
-
# Get base settings
|
43
|
-
settings_dict = {}
|
44
40
|
|
45
|
-
# Load from
|
46
|
-
if hasattr(config, '
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
return PaymentsSettings(**settings_dict)
|
77
|
-
|
78
|
-
def _has_provider_config(self, config, provider_name: str) -> bool:
|
79
|
-
"""Check if provider configuration exists."""
|
80
|
-
return (
|
81
|
-
hasattr(config, 'api_keys') and
|
82
|
-
hasattr(config.api_keys, provider_name)
|
83
|
-
)
|
84
|
-
|
85
|
-
def _get_provider_config(self, config, provider_name: str) -> Optional[object]:
|
86
|
-
"""Get provider configuration."""
|
87
|
-
try:
|
88
|
-
if provider_name == 'nowpayments':
|
89
|
-
return self._load_nowpayments_config(config)
|
90
|
-
elif provider_name == 'stripe':
|
91
|
-
return self._load_stripe_config(config)
|
92
|
-
elif provider_name == 'cryptapi':
|
93
|
-
return self._load_cryptapi_config(config)
|
94
|
-
else:
|
95
|
-
logger.warning(f"Unknown provider: {provider_name}")
|
96
|
-
return None
|
97
|
-
except Exception as e:
|
98
|
-
logger.error(f"Error loading {provider_name} config: {e}")
|
99
|
-
return None
|
100
|
-
|
101
|
-
def _load_nowpayments_config(self, config) -> Optional[NowPaymentsConfig]:
|
102
|
-
"""Load NowPayments configuration."""
|
103
|
-
nowpayments_config = config.api_keys.nowpayments
|
104
|
-
if not hasattr(nowpayments_config, 'api_key'):
|
105
|
-
return None
|
106
|
-
|
107
|
-
return NowPaymentsConfig(
|
108
|
-
api_key=SecretStr(nowpayments_config.api_key),
|
109
|
-
public_key=SecretStr(nowpayments_config.public_key) if hasattr(nowpayments_config, 'public_key') else None,
|
110
|
-
sandbox=getattr(config, 'debug', True),
|
111
|
-
callback_url=self._build_callback_url(config, 'nowpayments'),
|
112
|
-
success_url=self._build_success_url(config),
|
113
|
-
cancel_url=self._build_cancel_url(config)
|
114
|
-
)
|
115
|
-
|
116
|
-
def _load_stripe_config(self, config) -> Optional[StripeConfig]:
|
117
|
-
"""Load Stripe configuration."""
|
118
|
-
stripe_config = config.api_keys.stripe
|
119
|
-
if not hasattr(stripe_config, 'secret_key'):
|
120
|
-
return None
|
121
|
-
|
122
|
-
return StripeConfig(
|
123
|
-
api_key=SecretStr(stripe_config.secret_key),
|
124
|
-
publishable_key=SecretStr(stripe_config.publishable_key) if hasattr(stripe_config, 'publishable_key') else None,
|
125
|
-
webhook_secret=SecretStr(stripe_config.webhook_secret) if hasattr(stripe_config, 'webhook_secret') else None,
|
126
|
-
sandbox=getattr(config, 'debug', True)
|
127
|
-
)
|
128
|
-
|
129
|
-
def _load_cryptapi_config(self, config) -> Optional[CryptAPIConfig]:
|
130
|
-
"""Load CryptAPI configuration."""
|
131
|
-
cryptapi_config = config.api_keys.cryptapi
|
132
|
-
if not hasattr(cryptapi_config, 'own_address'):
|
133
|
-
return None
|
134
|
-
|
135
|
-
return CryptAPIConfig(
|
136
|
-
api_key=SecretStr('dummy'), # CryptAPI doesn't require API key
|
137
|
-
own_address=cryptapi_config.own_address,
|
138
|
-
callback_url=self._build_callback_url(config, 'cryptapi'),
|
139
|
-
convert_payments=getattr(cryptapi_config, 'convert_payments', True),
|
140
|
-
multi_token=getattr(cryptapi_config, 'multi_token', True),
|
141
|
-
priority=getattr(cryptapi_config, 'priority', 'default'),
|
142
|
-
sandbox=getattr(config, 'debug', True)
|
143
|
-
)
|
144
|
-
|
145
|
-
|
146
|
-
def _build_callback_url(self, config, provider: str) -> Optional[str]:
|
147
|
-
"""Build webhook callback URL for provider."""
|
148
|
-
if hasattr(config, 'api_url') and config.api_url:
|
149
|
-
return f"{config.api_url}/api/payments/webhook/{provider}/"
|
150
|
-
return None
|
151
|
-
|
152
|
-
def _build_success_url(self, config) -> Optional[str]:
|
153
|
-
"""Build payment success URL."""
|
154
|
-
if hasattr(config, 'site_url') and config.site_url:
|
155
|
-
return f"{config.site_url}/payments/success/"
|
156
|
-
return None
|
157
|
-
|
158
|
-
def _build_cancel_url(self, config) -> Optional[str]:
|
159
|
-
"""Build payment cancel URL."""
|
160
|
-
if hasattr(config, 'site_url') and config.site_url:
|
161
|
-
return f"{config.site_url}/payments/cancel/"
|
162
|
-
return None
|
41
|
+
# Load from new PaymentsConfig if available
|
42
|
+
if hasattr(config, 'payments') and config.payments:
|
43
|
+
# Convert List[PaymentProviderConfig] to Dict[str, PaymentProviderConfig]
|
44
|
+
providers = {}
|
45
|
+
for provider in config.payments.providers:
|
46
|
+
providers[provider.name] = provider
|
47
|
+
|
48
|
+
return PaymentsSettings(
|
49
|
+
enabled=config.payments.enabled,
|
50
|
+
debug_mode=getattr(config, 'debug', False),
|
51
|
+
providers=providers,
|
52
|
+
security=config.payments.security,
|
53
|
+
rate_limits=config.payments.rate_limits,
|
54
|
+
notifications=config.payments.notifications,
|
55
|
+
subscriptions=config.payments.subscriptions,
|
56
|
+
enable_crypto_payments=config.payments.enable_crypto_payments,
|
57
|
+
enable_fiat_payments=config.payments.enable_fiat_payments,
|
58
|
+
enable_subscription_system=config.payments.enable_subscription_system,
|
59
|
+
enable_balance_system=config.payments.enable_balance_system,
|
60
|
+
enable_api_key_system=config.payments.enable_api_key_system,
|
61
|
+
enable_webhook_processing=config.payments.enable_webhook_processing,
|
62
|
+
enable_billing_utils=config.payments.enable_billing_utils
|
63
|
+
)
|
64
|
+
else:
|
65
|
+
# Fallback: Return default settings if no PaymentsConfig found
|
66
|
+
logger.warning("No PaymentsConfig found, using default settings")
|
67
|
+
return PaymentsSettings(
|
68
|
+
enabled=False,
|
69
|
+
debug_mode=getattr(config, 'debug', False)
|
70
|
+
)
|
@@ -7,23 +7,13 @@ Defines configuration classes for different payment providers.
|
|
7
7
|
from typing import Dict, Any, Optional
|
8
8
|
from pydantic import BaseModel, Field, SecretStr
|
9
9
|
|
10
|
+
# Import the base PaymentProviderConfig from models.payments
|
11
|
+
from django_cfg.models.payments import PaymentProviderConfig as BasePaymentProviderConfig
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
api_key: SecretStr = Field(description="Provider API key")
|
16
|
-
timeout: int = Field(default=30, description="Request timeout in seconds")
|
17
|
-
max_retries: int = Field(default=3, description="Maximum retry attempts")
|
18
|
-
|
19
|
-
def get_config_dict(self) -> Dict[str, Any]:
|
20
|
-
"""Get configuration as dictionary for provider initialization."""
|
21
|
-
return {
|
22
|
-
'api_key': self.api_key.get_secret_value(),
|
23
|
-
'sandbox': self.sandbox,
|
24
|
-
'timeout': self.timeout,
|
25
|
-
'max_retries': self.max_retries
|
26
|
-
}
|
13
|
+
|
14
|
+
class PaymentProviderConfig(BasePaymentProviderConfig):
|
15
|
+
"""Extended base configuration for payment providers."""
|
16
|
+
pass
|
27
17
|
|
28
18
|
|
29
19
|
class NowPaymentsConfig(PaymentProviderConfig):
|
@@ -80,11 +70,33 @@ class CryptAPIConfig(PaymentProviderConfig):
|
|
80
70
|
return config
|
81
71
|
|
82
72
|
|
73
|
+
class CryptomusConfig(PaymentProviderConfig):
|
74
|
+
"""Cryptomus provider configuration."""
|
75
|
+
merchant_uuid: str = Field(description="Cryptomus merchant UUID")
|
76
|
+
callback_url: Optional[str] = Field(default=None, description="Webhook callback URL")
|
77
|
+
success_url: Optional[str] = Field(default=None, description="Payment success URL")
|
78
|
+
fail_url: Optional[str] = Field(default=None, description="Payment fail URL")
|
79
|
+
network: Optional[str] = Field(default=None, description="Default network for payments")
|
80
|
+
|
81
|
+
def get_config_dict(self) -> Dict[str, Any]:
|
82
|
+
"""Get configuration as dictionary for provider initialization."""
|
83
|
+
config = super().get_config_dict()
|
84
|
+
config.update({
|
85
|
+
'merchant_uuid': self.merchant_uuid,
|
86
|
+
'callback_url': self.callback_url,
|
87
|
+
'success_url': self.success_url,
|
88
|
+
'fail_url': self.fail_url,
|
89
|
+
'network': self.network,
|
90
|
+
})
|
91
|
+
return config
|
92
|
+
|
93
|
+
|
83
94
|
# Provider registry for easy access
|
84
95
|
PROVIDER_CONFIGS = {
|
85
96
|
'nowpayments': NowPaymentsConfig,
|
86
97
|
'stripe': StripeConfig,
|
87
98
|
'cryptapi': CryptAPIConfig,
|
99
|
+
'cryptomus': CryptomusConfig,
|
88
100
|
}
|
89
101
|
|
90
102
|
|
@@ -1,83 +1,49 @@
|
|
1
1
|
"""
|
2
2
|
Universal payments module settings.
|
3
3
|
|
4
|
-
Core settings for the payments system
|
4
|
+
Core settings for the payments system - now using unified models from django_cfg.models.payments.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from typing import Dict
|
7
|
+
from typing import Dict, List
|
8
8
|
from pydantic import BaseModel, Field
|
9
9
|
|
10
|
-
from .
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
auto_create_api_keys: bool = Field(default=True, description="Auto-create API keys for new users")
|
19
|
-
|
20
|
-
|
21
|
-
class RateLimitSettings(BaseModel):
|
22
|
-
"""Rate limiting settings."""
|
23
|
-
default_rate_limit_per_hour: int = Field(default=1000, description="Default API rate limit per hour")
|
24
|
-
default_rate_limit_per_day: int = Field(default=10000, description="Default API rate limit per day")
|
25
|
-
burst_limit_multiplier: float = Field(default=2.0, description="Burst limit multiplier")
|
26
|
-
sliding_window_size: int = Field(default=3600, description="Sliding window size in seconds")
|
27
|
-
|
28
|
-
|
29
|
-
class BillingSettings(BaseModel):
|
30
|
-
"""Billing and subscription settings."""
|
31
|
-
auto_bill_subscriptions: bool = Field(default=True, description="Automatically bill subscriptions")
|
32
|
-
billing_grace_period_hours: int = Field(default=24, description="Grace period for failed billing")
|
33
|
-
retry_failed_payments: bool = Field(default=True, description="Retry failed payments")
|
34
|
-
max_payment_retries: int = Field(default=3, description="Maximum payment retry attempts")
|
35
|
-
min_payment_amount_usd: float = Field(default=1.0, description="Minimum payment amount in USD")
|
36
|
-
max_payment_amount_usd: float = Field(default=50000.0, description="Maximum payment amount in USD")
|
37
|
-
|
38
|
-
|
39
|
-
class CacheSettings(BaseModel):
|
40
|
-
"""Cache timeout settings."""
|
41
|
-
cache_timeout_access_check: int = Field(default=60, description="Cache timeout for access checks (seconds)")
|
42
|
-
cache_timeout_user_balance: int = Field(default=300, description="Cache timeout for user balance (seconds)")
|
43
|
-
cache_timeout_subscriptions: int = Field(default=600, description="Cache timeout for subscriptions (seconds)")
|
44
|
-
cache_timeout_provider_status: int = Field(default=1800, description="Cache timeout for provider status (seconds)")
|
45
|
-
cache_timeout_currency_rates: int = Field(default=3600, description="Cache timeout for currency rates (seconds)")
|
46
|
-
|
47
|
-
|
48
|
-
class NotificationSettings(BaseModel):
|
49
|
-
"""Notification settings."""
|
50
|
-
send_payment_confirmations: bool = Field(default=True, description="Send payment confirmation emails")
|
51
|
-
send_subscription_renewals: bool = Field(default=True, description="Send subscription renewal notifications")
|
52
|
-
send_balance_alerts: bool = Field(default=True, description="Send low balance alerts")
|
53
|
-
send_api_key_alerts: bool = Field(default=True, description="Send API key security alerts")
|
54
|
-
webhook_timeout: int = Field(default=30, description="Webhook timeout in seconds")
|
10
|
+
# Import unified types from models/payments.py
|
11
|
+
from django_cfg.models.payments import (
|
12
|
+
PaymentProviderConfig,
|
13
|
+
SecuritySettings,
|
14
|
+
RateLimitSettings,
|
15
|
+
NotificationSettings,
|
16
|
+
SubscriptionSettings
|
17
|
+
)
|
55
18
|
|
56
19
|
|
57
20
|
class PaymentsSettings(BaseModel):
|
58
|
-
"""Universal payments module settings."""
|
21
|
+
"""Universal payments module settings - unified with PaymentsConfig."""
|
59
22
|
|
60
23
|
# General settings
|
61
24
|
enabled: bool = Field(default=True, description="Enable payments module")
|
62
25
|
debug_mode: bool = Field(default=False, description="Enable debug mode for payments")
|
63
26
|
|
64
|
-
# Component settings
|
27
|
+
# Component settings - using unified models
|
65
28
|
security: SecuritySettings = Field(default_factory=SecuritySettings)
|
66
29
|
rate_limits: RateLimitSettings = Field(default_factory=RateLimitSettings)
|
67
|
-
billing: BillingSettings = Field(default_factory=BillingSettings)
|
68
|
-
cache: CacheSettings = Field(default_factory=CacheSettings)
|
69
30
|
notifications: NotificationSettings = Field(default_factory=NotificationSettings)
|
31
|
+
subscriptions: SubscriptionSettings = Field(default_factory=SubscriptionSettings)
|
70
32
|
|
71
|
-
# Provider configurations
|
72
|
-
providers: Dict[str, PaymentProviderConfig] = Field(
|
33
|
+
# Provider configurations - now accepts List instead of Dict
|
34
|
+
providers: Dict[str, PaymentProviderConfig] = Field(
|
35
|
+
default_factory=dict,
|
36
|
+
description="Payment provider configurations (Dict for backwards compatibility)"
|
37
|
+
)
|
73
38
|
|
74
|
-
# Feature flags
|
39
|
+
# Feature flags - copied from PaymentsConfig for consistency
|
75
40
|
enable_crypto_payments: bool = Field(default=True, description="Enable cryptocurrency payments")
|
76
41
|
enable_fiat_payments: bool = Field(default=True, description="Enable fiat currency payments")
|
77
42
|
enable_subscription_system: bool = Field(default=True, description="Enable subscription system")
|
78
43
|
enable_balance_system: bool = Field(default=True, description="Enable user balance system")
|
79
44
|
enable_api_key_system: bool = Field(default=True, description="Enable API key system")
|
80
45
|
enable_webhook_processing: bool = Field(default=True, description="Enable webhook processing")
|
46
|
+
enable_billing_utils: bool = Field(default=True, description="Enable billing utility functions")
|
81
47
|
|
82
48
|
# Backwards compatibility properties
|
83
49
|
@property
|
@@ -86,51 +52,45 @@ class PaymentsSettings(BaseModel):
|
|
86
52
|
return self.security.auto_create_api_keys
|
87
53
|
|
88
54
|
@property
|
89
|
-
def
|
90
|
-
"""Backwards compatibility for
|
91
|
-
return self.security.
|
55
|
+
def require_api_key(self) -> bool:
|
56
|
+
"""Backwards compatibility for require_api_key."""
|
57
|
+
return self.security.require_api_key
|
92
58
|
|
93
59
|
@property
|
94
|
-
def
|
95
|
-
"""Backwards compatibility for
|
96
|
-
return self.
|
97
|
-
|
98
|
-
@property
|
99
|
-
def default_rate_limit_per_day(self) -> int:
|
100
|
-
"""Backwards compatibility for default_rate_limit_per_day."""
|
101
|
-
return self.rate_limits.default_rate_limit_per_day
|
102
|
-
|
103
|
-
@property
|
104
|
-
def api_key_length(self) -> int:
|
105
|
-
"""Backwards compatibility for api_key_length."""
|
106
|
-
return self.security.api_key_length
|
107
|
-
|
108
|
-
@property
|
109
|
-
def api_key_prefix(self) -> str:
|
110
|
-
"""Backwards compatibility for api_key_prefix."""
|
111
|
-
return self.security.api_key_prefix
|
60
|
+
def min_balance_threshold(self) -> float:
|
61
|
+
"""Backwards compatibility for min_balance_threshold."""
|
62
|
+
return float(self.security.min_balance_threshold)
|
112
63
|
|
113
64
|
@property
|
114
|
-
def
|
115
|
-
"""Backwards compatibility for
|
116
|
-
return self.
|
65
|
+
def requests_per_hour(self) -> int:
|
66
|
+
"""Backwards compatibility for requests_per_hour."""
|
67
|
+
return self.rate_limits.requests_per_hour
|
117
68
|
|
118
69
|
@property
|
119
|
-
def
|
120
|
-
"""Backwards compatibility for
|
121
|
-
return self.
|
70
|
+
def webhook_timeout(self) -> int:
|
71
|
+
"""Backwards compatibility for webhook_timeout."""
|
72
|
+
return self.notifications.webhook_timeout
|
122
73
|
|
123
|
-
|
124
|
-
def
|
125
|
-
"""
|
126
|
-
|
74
|
+
# Utility methods
|
75
|
+
def is_provider_enabled(self, provider_name: str) -> bool:
|
76
|
+
"""Check if a specific provider is enabled."""
|
77
|
+
provider = self.providers.get(provider_name)
|
78
|
+
return provider and provider.enabled if provider else False
|
127
79
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
return self.cache.cache_timeout_user_balance
|
80
|
+
def get_enabled_providers(self) -> List[str]:
|
81
|
+
"""Get list of enabled provider names."""
|
82
|
+
return [name for name, config in self.providers.items() if config.enabled]
|
132
83
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
84
|
+
def get_provider_config(self, provider_name: str) -> PaymentProviderConfig:
|
85
|
+
"""Get configuration for a specific provider."""
|
86
|
+
return self.providers.get(provider_name)
|
87
|
+
|
88
|
+
|
89
|
+
__all__ = [
|
90
|
+
'PaymentsSettings',
|
91
|
+
'SecuritySettings',
|
92
|
+
'RateLimitSettings',
|
93
|
+
'NotificationSettings',
|
94
|
+
'SubscriptionSettings',
|
95
|
+
'PaymentProviderConfig'
|
96
|
+
]
|