django-cfg 1.2.22__py3-none-any.whl → 1.2.25__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/knowbase/tasks/archive_tasks.py +6 -6
  3. django_cfg/apps/knowbase/tasks/document_processing.py +3 -3
  4. django_cfg/apps/knowbase/tasks/external_data_tasks.py +2 -2
  5. django_cfg/apps/knowbase/tasks/maintenance.py +3 -3
  6. django_cfg/apps/payments/admin/__init__.py +23 -0
  7. django_cfg/apps/payments/admin/api_keys_admin.py +347 -0
  8. django_cfg/apps/payments/admin/balance_admin.py +434 -0
  9. django_cfg/apps/payments/admin/currencies_admin.py +186 -0
  10. django_cfg/apps/payments/admin/filters.py +259 -0
  11. django_cfg/apps/payments/admin/payments_admin.py +142 -0
  12. django_cfg/apps/payments/admin/subscriptions_admin.py +227 -0
  13. django_cfg/apps/payments/admin/tariffs_admin.py +199 -0
  14. django_cfg/apps/payments/config/__init__.py +65 -0
  15. django_cfg/apps/payments/config/module.py +70 -0
  16. django_cfg/apps/payments/config/providers.py +115 -0
  17. django_cfg/apps/payments/config/settings.py +96 -0
  18. django_cfg/apps/payments/config/utils.py +52 -0
  19. django_cfg/apps/payments/decorators.py +291 -0
  20. django_cfg/apps/payments/management/__init__.py +3 -0
  21. django_cfg/apps/payments/management/commands/README.md +178 -0
  22. django_cfg/apps/payments/management/commands/__init__.py +3 -0
  23. django_cfg/apps/payments/management/commands/currency_stats.py +323 -0
  24. django_cfg/apps/payments/management/commands/populate_currencies.py +246 -0
  25. django_cfg/apps/payments/management/commands/update_currencies.py +336 -0
  26. django_cfg/apps/payments/managers/currency_manager.py +65 -14
  27. django_cfg/apps/payments/middleware/api_access.py +294 -0
  28. django_cfg/apps/payments/middleware/rate_limiting.py +216 -0
  29. django_cfg/apps/payments/middleware/usage_tracking.py +296 -0
  30. django_cfg/apps/payments/migrations/0001_initial.py +125 -11
  31. django_cfg/apps/payments/models/__init__.py +18 -0
  32. django_cfg/apps/payments/models/api_keys.py +2 -2
  33. django_cfg/apps/payments/models/balance.py +2 -2
  34. django_cfg/apps/payments/models/base.py +16 -0
  35. django_cfg/apps/payments/models/events.py +2 -2
  36. django_cfg/apps/payments/models/payments.py +112 -2
  37. django_cfg/apps/payments/models/subscriptions.py +2 -2
  38. django_cfg/apps/payments/services/__init__.py +64 -7
  39. django_cfg/apps/payments/services/billing/__init__.py +8 -0
  40. django_cfg/apps/payments/services/cache/__init__.py +15 -0
  41. django_cfg/apps/payments/services/cache/base.py +30 -0
  42. django_cfg/apps/payments/services/cache/simple_cache.py +135 -0
  43. django_cfg/apps/payments/services/core/__init__.py +17 -0
  44. django_cfg/apps/payments/services/core/balance_service.py +447 -0
  45. django_cfg/apps/payments/services/core/fallback_service.py +432 -0
  46. django_cfg/apps/payments/services/core/payment_service.py +576 -0
  47. django_cfg/apps/payments/services/core/subscription_service.py +614 -0
  48. django_cfg/apps/payments/services/internal_types.py +297 -0
  49. django_cfg/apps/payments/services/middleware/__init__.py +8 -0
  50. django_cfg/apps/payments/services/monitoring/__init__.py +22 -0
  51. django_cfg/apps/payments/services/monitoring/api_schemas.py +222 -0
  52. django_cfg/apps/payments/services/monitoring/provider_health.py +372 -0
  53. django_cfg/apps/payments/services/providers/__init__.py +22 -0
  54. django_cfg/apps/payments/services/providers/base.py +137 -0
  55. django_cfg/apps/payments/services/providers/cryptapi.py +273 -0
  56. django_cfg/apps/payments/services/providers/cryptomus.py +310 -0
  57. django_cfg/apps/payments/services/providers/nowpayments.py +293 -0
  58. django_cfg/apps/payments/services/providers/registry.py +103 -0
  59. django_cfg/apps/payments/services/security/__init__.py +34 -0
  60. django_cfg/apps/payments/services/security/error_handler.py +637 -0
  61. django_cfg/apps/payments/services/security/payment_notifications.py +342 -0
  62. django_cfg/apps/payments/services/security/webhook_validator.py +475 -0
  63. django_cfg/apps/payments/services/validators/__init__.py +8 -0
  64. django_cfg/apps/payments/signals/__init__.py +13 -0
  65. django_cfg/apps/payments/signals/api_key_signals.py +160 -0
  66. django_cfg/apps/payments/signals/payment_signals.py +128 -0
  67. django_cfg/apps/payments/signals/subscription_signals.py +196 -0
  68. django_cfg/apps/payments/tasks/__init__.py +12 -0
  69. django_cfg/apps/payments/tasks/webhook_processing.py +177 -0
  70. django_cfg/apps/payments/urls.py +5 -5
  71. django_cfg/apps/payments/utils/__init__.py +45 -0
  72. django_cfg/apps/payments/utils/billing_utils.py +342 -0
  73. django_cfg/apps/payments/utils/config_utils.py +245 -0
  74. django_cfg/apps/payments/utils/middleware_utils.py +228 -0
  75. django_cfg/apps/payments/utils/validation_utils.py +94 -0
  76. django_cfg/apps/payments/views/payment_views.py +40 -2
  77. django_cfg/apps/payments/views/webhook_views.py +266 -0
  78. django_cfg/apps/payments/viewsets.py +65 -0
  79. django_cfg/apps/support/signals.py +16 -4
  80. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  81. django_cfg/cli/README.md +2 -2
  82. django_cfg/cli/commands/create_project.py +1 -1
  83. django_cfg/cli/commands/info.py +1 -1
  84. django_cfg/cli/main.py +1 -1
  85. django_cfg/cli/utils.py +5 -5
  86. django_cfg/core/config.py +18 -4
  87. django_cfg/models/payments.py +546 -0
  88. django_cfg/models/revolution.py +1 -1
  89. django_cfg/models/tasks.py +51 -2
  90. django_cfg/modules/base.py +12 -6
  91. django_cfg/modules/django_currency/README.md +104 -269
  92. django_cfg/modules/django_currency/__init__.py +99 -41
  93. django_cfg/modules/django_currency/clients/__init__.py +11 -0
  94. django_cfg/modules/django_currency/clients/coingecko_client.py +257 -0
  95. django_cfg/modules/django_currency/clients/yfinance_client.py +246 -0
  96. django_cfg/modules/django_currency/core/__init__.py +42 -0
  97. django_cfg/modules/django_currency/core/converter.py +169 -0
  98. django_cfg/modules/django_currency/core/exceptions.py +28 -0
  99. django_cfg/modules/django_currency/core/models.py +54 -0
  100. django_cfg/modules/django_currency/database/__init__.py +25 -0
  101. django_cfg/modules/django_currency/database/database_loader.py +507 -0
  102. django_cfg/modules/django_currency/utils/__init__.py +9 -0
  103. django_cfg/modules/django_currency/utils/cache.py +92 -0
  104. django_cfg/modules/django_email.py +42 -4
  105. django_cfg/modules/django_unfold/dashboard.py +20 -0
  106. django_cfg/registry/core.py +10 -0
  107. django_cfg/template_archive/__init__.py +0 -0
  108. django_cfg/template_archive/django_sample.zip +0 -0
  109. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/METADATA +11 -6
  110. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/RECORD +113 -50
  111. django_cfg/apps/agents/examples/__init__.py +0 -3
  112. django_cfg/apps/agents/examples/simple_example.py +0 -161
  113. django_cfg/apps/knowbase/examples/__init__.py +0 -3
  114. django_cfg/apps/knowbase/examples/external_data_usage.py +0 -191
  115. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +0 -199
  116. django_cfg/apps/payments/services/base.py +0 -68
  117. django_cfg/apps/payments/services/nowpayments.py +0 -78
  118. django_cfg/apps/payments/services/providers.py +0 -77
  119. django_cfg/apps/payments/services/redis_service.py +0 -215
  120. django_cfg/modules/django_currency/cache.py +0 -430
  121. django_cfg/modules/django_currency/converter.py +0 -324
  122. django_cfg/modules/django_currency/service.py +0 -277
  123. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/WHEEL +0 -0
  124. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/entry_points.txt +0 -0
  125. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,546 @@
1
+ """
2
+ Payment system configuration models for Django-CFG.
3
+
4
+ This module provides type-safe Pydantic models for configuring the universal
5
+ payment system, including provider configurations, security settings,
6
+ and integration options.
7
+ """
8
+
9
+ from pydantic import BaseModel, Field, SecretStr, field_validator
10
+ from typing import Optional, List, Dict, Any, Literal
11
+ from enum import Enum
12
+ from decimal import Decimal
13
+ import logging
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class PaymentProvider(str, Enum):
19
+ """Supported payment providers."""
20
+ NOWPAYMENTS = "nowpayments"
21
+ CRYPTAPI = "cryptapi"
22
+ STRIPE = "stripe"
23
+ # Future providers can be added here
24
+
25
+
26
+ class BillingPeriod(str, Enum):
27
+ """Supported billing periods."""
28
+ MONTHLY = "monthly"
29
+ YEARLY = "yearly"
30
+
31
+
32
+ class PaymentProviderConfig(BaseModel):
33
+ """Base configuration for payment providers."""
34
+
35
+ name: str = Field(
36
+ description="Provider name (e.g., 'nowpayments', 'cryptapi', 'stripe')"
37
+ )
38
+ enabled: bool = Field(
39
+ default=True,
40
+ description="Enable this payment provider"
41
+ )
42
+ sandbox: bool = Field(
43
+ default=True,
44
+ description="Use sandbox/test mode"
45
+ )
46
+ api_key: SecretStr = Field(
47
+ description="Provider API key (stored securely)"
48
+ )
49
+ timeout: int = Field(
50
+ default=30,
51
+ ge=5,
52
+ le=300,
53
+ description="Request timeout in seconds"
54
+ )
55
+ max_retries: int = Field(
56
+ default=3,
57
+ ge=0,
58
+ le=10,
59
+ description="Maximum retry attempts for failed requests"
60
+ )
61
+
62
+ def get_config_dict(self) -> Dict[str, Any]:
63
+ """Get configuration as dictionary for provider initialization."""
64
+ return {
65
+ 'enabled': self.enabled,
66
+ 'api_key': self.api_key.get_secret_value(),
67
+ 'sandbox': self.sandbox,
68
+ 'timeout': self.timeout,
69
+ 'max_retries': self.max_retries
70
+ }
71
+
72
+
73
+ class NowPaymentsConfig(PaymentProviderConfig):
74
+ """NowPayments cryptocurrency provider configuration."""
75
+
76
+ ipn_secret: Optional[SecretStr] = Field(
77
+ default=None,
78
+ description="IPN secret for webhook validation"
79
+ )
80
+ callback_url: Optional[str] = Field(
81
+ default=None,
82
+ description="Custom webhook callback URL"
83
+ )
84
+ success_url: Optional[str] = Field(
85
+ default=None,
86
+ description="Payment success redirect URL"
87
+ )
88
+ cancel_url: Optional[str] = Field(
89
+ default=None,
90
+ description="Payment cancellation redirect URL"
91
+ )
92
+
93
+ def get_config_dict(self) -> Dict[str, Any]:
94
+ """Get configuration with NowPayments-specific fields."""
95
+ config = super().get_config_dict()
96
+ config.update({
97
+ 'ipn_secret': self.ipn_secret.get_secret_value() if self.ipn_secret else None,
98
+ 'callback_url': self.callback_url,
99
+ 'success_url': self.success_url,
100
+ 'cancel_url': self.cancel_url
101
+ })
102
+ return config
103
+
104
+
105
+ class CryptAPIConfig(PaymentProviderConfig):
106
+ """CryptAPI cryptocurrency provider configuration."""
107
+
108
+ own_address: str = Field(
109
+ description="Your cryptocurrency wallet address"
110
+ )
111
+ callback_url: Optional[str] = Field(
112
+ default=None,
113
+ description="Webhook callback URL"
114
+ )
115
+ convert_payments: bool = Field(
116
+ default=False,
117
+ description="Convert payments to your currency"
118
+ )
119
+ multi_token: bool = Field(
120
+ default=False,
121
+ description="Enable multi-token support"
122
+ )
123
+ priority: str = Field(
124
+ default="default",
125
+ description="Transaction priority level"
126
+ )
127
+
128
+ # CryptAPI doesn't use traditional API keys
129
+ api_key: SecretStr = Field(
130
+ default=SecretStr("not_required"),
131
+ description="Not required for CryptAPI"
132
+ )
133
+
134
+ def get_config_dict(self) -> Dict[str, Any]:
135
+ """Get configuration with CryptAPI-specific fields."""
136
+ config = super().get_config_dict()
137
+ config.update({
138
+ 'own_address': self.own_address,
139
+ 'callback_url': self.callback_url,
140
+ 'convert_payments': self.convert_payments,
141
+ 'multi_token': self.multi_token,
142
+ 'priority': self.priority
143
+ })
144
+ return config
145
+
146
+
147
+ class StripeConfig(PaymentProviderConfig):
148
+ """Stripe payment provider configuration."""
149
+
150
+ publishable_key: Optional[str] = Field(
151
+ default=None,
152
+ description="Stripe publishable key for frontend"
153
+ )
154
+ webhook_endpoint_secret: Optional[SecretStr] = Field(
155
+ default=None,
156
+ description="Webhook endpoint secret for signature validation"
157
+ )
158
+ success_url: Optional[str] = Field(
159
+ default=None,
160
+ description="Payment success redirect URL"
161
+ )
162
+ cancel_url: Optional[str] = Field(
163
+ default=None,
164
+ description="Payment cancellation redirect URL"
165
+ )
166
+
167
+ def get_config_dict(self) -> Dict[str, Any]:
168
+ """Get configuration with Stripe-specific fields."""
169
+ config = super().get_config_dict()
170
+ config.update({
171
+ 'publishable_key': self.publishable_key,
172
+ 'webhook_endpoint_secret': self.webhook_endpoint_secret.get_secret_value() if self.webhook_endpoint_secret else None,
173
+ 'success_url': self.success_url,
174
+ 'cancel_url': self.cancel_url
175
+ })
176
+ return config
177
+
178
+
179
+ class SecuritySettings(BaseModel):
180
+ """Security configuration for payments."""
181
+
182
+ auto_create_api_keys: bool = Field(
183
+ default=True,
184
+ description="Automatically create API keys for new users"
185
+ )
186
+ require_api_key: bool = Field(
187
+ default=True,
188
+ description="Require API key for payment endpoints"
189
+ )
190
+ min_balance_threshold: Decimal = Field(
191
+ default=Decimal('0.01'),
192
+ ge=0,
193
+ description="Minimum balance threshold for operations"
194
+ )
195
+ max_payment_amount: Decimal = Field(
196
+ default=Decimal('50000.00'),
197
+ gt=0,
198
+ description="Maximum payment amount in USD"
199
+ )
200
+ webhook_signature_validation: bool = Field(
201
+ default=True,
202
+ description="Validate webhook signatures"
203
+ )
204
+
205
+
206
+ class RateLimitSettings(BaseModel):
207
+ """Rate limiting configuration."""
208
+
209
+ enabled: bool = Field(
210
+ default=True,
211
+ description="Enable rate limiting"
212
+ )
213
+ requests_per_hour: int = Field(
214
+ default=1000,
215
+ ge=1,
216
+ description="Maximum requests per hour per user"
217
+ )
218
+ payment_requests_per_hour: int = Field(
219
+ default=100,
220
+ ge=1,
221
+ description="Maximum payment requests per hour per user"
222
+ )
223
+ webhook_requests_per_minute: int = Field(
224
+ default=60,
225
+ ge=1,
226
+ description="Maximum webhook requests per minute"
227
+ )
228
+
229
+
230
+ class NotificationSettings(BaseModel):
231
+ """Notification configuration."""
232
+
233
+ email_notifications: bool = Field(
234
+ default=True,
235
+ description="Send email notifications for payment events"
236
+ )
237
+ webhook_notifications: bool = Field(
238
+ default=True,
239
+ description="Send webhook notifications"
240
+ )
241
+ webhook_timeout: int = Field(
242
+ default=30,
243
+ ge=5,
244
+ le=300,
245
+ description="Webhook timeout in seconds"
246
+ )
247
+
248
+
249
+ class SubscriptionSettings(BaseModel):
250
+ """Subscription system configuration."""
251
+
252
+ enabled: bool = Field(
253
+ default=True,
254
+ description="Enable subscription system"
255
+ )
256
+ auto_renewal: bool = Field(
257
+ default=True,
258
+ description="Enable automatic subscription renewal"
259
+ )
260
+ grace_period_days: int = Field(
261
+ default=3,
262
+ ge=0,
263
+ le=30,
264
+ description="Grace period for expired subscriptions"
265
+ )
266
+ trial_period_days: int = Field(
267
+ default=7,
268
+ ge=0,
269
+ le=90,
270
+ description="Default trial period in days"
271
+ )
272
+ refund_policy: Literal["none", "prorated", "full"] = Field(
273
+ default="prorated",
274
+ description="Default refund policy"
275
+ )
276
+
277
+
278
+ class PaymentsConfig(BaseModel):
279
+ """
280
+ Universal payment system configuration.
281
+
282
+ This model provides comprehensive configuration for the django-cfg payments
283
+ module, including provider settings, security options, rate limiting,
284
+ and feature toggles.
285
+ """
286
+
287
+ # === Core Settings ===
288
+ enabled: bool = Field(
289
+ default=True,
290
+ description="Enable the payments module"
291
+ )
292
+ debug_mode: bool = Field(
293
+ default=False,
294
+ description="Enable debug mode for detailed logging"
295
+ )
296
+ strict_mode: bool = Field(
297
+ default=True,
298
+ description="Enable strict validation and security checks"
299
+ )
300
+
301
+
302
+ # === Payment Providers ===
303
+ providers: List[PaymentProviderConfig] = Field(
304
+ default_factory=list,
305
+ description="Payment provider configurations"
306
+ )
307
+
308
+ # === Feature Configuration ===
309
+ security: SecuritySettings = Field(
310
+ default_factory=SecuritySettings,
311
+ description="Security settings"
312
+ )
313
+ rate_limits: RateLimitSettings = Field(
314
+ default_factory=RateLimitSettings,
315
+ description="Rate limiting settings"
316
+ )
317
+ notifications: NotificationSettings = Field(
318
+ default_factory=NotificationSettings,
319
+ description="Notification settings"
320
+ )
321
+ subscriptions: SubscriptionSettings = Field(
322
+ default_factory=SubscriptionSettings,
323
+ description="Subscription system settings"
324
+ )
325
+
326
+ # === Feature Flags ===
327
+ enable_crypto_payments: bool = Field(
328
+ default=True,
329
+ description="Enable cryptocurrency payments"
330
+ )
331
+ enable_fiat_payments: bool = Field(
332
+ default=True,
333
+ description="Enable fiat currency payments"
334
+ )
335
+ enable_subscription_system: bool = Field(
336
+ default=True,
337
+ description="Enable subscription management"
338
+ )
339
+ enable_balance_system: bool = Field(
340
+ default=True,
341
+ description="Enable user balance system"
342
+ )
343
+ enable_api_key_system: bool = Field(
344
+ default=True,
345
+ description="Enable API key management"
346
+ )
347
+ enable_webhook_processing: bool = Field(
348
+ default=True,
349
+ description="Enable webhook processing"
350
+ )
351
+ enable_billing_utils: bool = Field(
352
+ default=True,
353
+ description="Enable billing utilities and calculations"
354
+ )
355
+
356
+ # === Middleware Configuration ===
357
+ middleware_enabled: bool = Field(
358
+ default=True,
359
+ description="Enable payments middleware"
360
+ )
361
+ custom_middleware: List[str] = Field(
362
+ default_factory=list,
363
+ description="Additional custom middleware classes"
364
+ )
365
+
366
+ # === URL Configuration ===
367
+ url_prefix: str = Field(
368
+ default="api/payments",
369
+ description="URL prefix for payment endpoints"
370
+ )
371
+ webhook_url_prefix: str = Field(
372
+ default="webhooks",
373
+ description="URL prefix for webhook endpoints"
374
+ )
375
+
376
+ @field_validator("providers")
377
+ @classmethod
378
+ def validate_providers(cls, v: List[PaymentProviderConfig]) -> List[PaymentProviderConfig]:
379
+ """Validate payment provider configurations."""
380
+ if not isinstance(v, list):
381
+ raise ValueError("Providers must be a list")
382
+
383
+ # Check for duplicate provider names
384
+ names = [provider.name for provider in v]
385
+ if len(names) != len(set(names)):
386
+ raise ValueError("Duplicate provider names found")
387
+
388
+ # Validate at least one provider is configured if payments are enabled
389
+ enabled_providers = [provider.name for provider in v if provider.enabled]
390
+ if not enabled_providers:
391
+ logger.warning("No payment providers are enabled")
392
+
393
+ return v
394
+
395
+ @field_validator("url_prefix", "webhook_url_prefix")
396
+ @classmethod
397
+ def validate_url_prefixes(cls, v: str) -> str:
398
+ """Validate URL prefixes."""
399
+ if not v:
400
+ raise ValueError("URL prefix cannot be empty")
401
+
402
+ # Remove leading/trailing slashes for consistency
403
+ v = v.strip("/")
404
+
405
+ # Basic validation
406
+ if not v.replace("/", "").replace("-", "").replace("_", "").isalnum():
407
+ raise ValueError("URL prefix must contain only alphanumeric characters, hyphens, underscores, and slashes")
408
+
409
+ return v
410
+
411
+ def get_enabled_providers(self) -> List[str]:
412
+ """Get list of enabled payment providers."""
413
+ return [
414
+ name for name, config in self.providers.items()
415
+ if config.enabled
416
+ ]
417
+
418
+ def get_provider_config(self, provider_name: str) -> Optional[PaymentProviderConfig]:
419
+ """Get configuration for specific provider."""
420
+ return self.providers.get(provider_name)
421
+
422
+ def is_provider_enabled(self, provider_name: str) -> bool:
423
+ """Check if specific provider is enabled."""
424
+ config = self.get_provider_config(provider_name)
425
+ return config is not None and config.enabled
426
+
427
+ def get_middleware_classes(self) -> List[str]:
428
+ """Get list of middleware classes to enable."""
429
+ middleware = []
430
+
431
+ if not self.middleware_enabled:
432
+ return middleware
433
+
434
+ if self.enable_api_key_system:
435
+ middleware.append("django_cfg.apps.payments.middleware.APIAccessMiddleware")
436
+
437
+ if self.rate_limits.enabled:
438
+ middleware.append("django_cfg.apps.payments.middleware.RateLimitingMiddleware")
439
+
440
+ if self.enable_subscription_system:
441
+ middleware.append("django_cfg.apps.payments.middleware.UsageTrackingMiddleware")
442
+
443
+ # Add custom middleware
444
+ middleware.extend(self.custom_middleware)
445
+
446
+ return middleware
447
+
448
+ def should_enable_tasks(self) -> bool:
449
+ """
450
+ Determine if background tasks should be enabled for payments.
451
+
452
+ Tasks are enabled if webhook processing is enabled.
453
+ """
454
+ return self.enabled and self.enable_webhook_processing
455
+
456
+
457
+ # Helper function for easy provider configuration
458
+ def create_nowpayments_config(
459
+ api_key: str,
460
+ sandbox: bool = True,
461
+ ipn_secret: Optional[str] = None,
462
+ **kwargs
463
+ ) -> NowPaymentsConfig:
464
+ """Helper to create NowPayments configuration."""
465
+ return NowPaymentsConfig(
466
+ name="nowpayments",
467
+ api_key=SecretStr(api_key),
468
+ sandbox=sandbox,
469
+ ipn_secret=SecretStr(ipn_secret) if ipn_secret else None,
470
+ **kwargs
471
+ )
472
+
473
+
474
+ def create_cryptapi_config(
475
+ own_address: str,
476
+ callback_url: Optional[str] = None,
477
+ **kwargs
478
+ ) -> CryptAPIConfig:
479
+ """Helper to create CryptAPI configuration."""
480
+ return CryptAPIConfig(
481
+ name="cryptapi",
482
+ own_address=own_address,
483
+ callback_url=callback_url,
484
+ **kwargs
485
+ )
486
+
487
+
488
+ def create_stripe_config(
489
+ api_key: str,
490
+ publishable_key: Optional[str] = None,
491
+ webhook_endpoint_secret: Optional[str] = None,
492
+ sandbox: bool = True,
493
+ **kwargs
494
+ ) -> StripeConfig:
495
+ """Helper to create Stripe configuration."""
496
+ return StripeConfig(
497
+ name="stripe",
498
+ api_key=SecretStr(api_key),
499
+ publishable_key=publishable_key,
500
+ webhook_endpoint_secret=SecretStr(webhook_endpoint_secret) if webhook_endpoint_secret else None,
501
+ sandbox=sandbox,
502
+ **kwargs
503
+ )
504
+
505
+
506
+ def create_cryptomus_config(
507
+ api_key: str,
508
+ merchant_uuid: str,
509
+ sandbox: bool = True,
510
+ callback_url: Optional[str] = None,
511
+ success_url: Optional[str] = None,
512
+ fail_url: Optional[str] = None,
513
+ **kwargs
514
+ ):
515
+ """Helper to create Cryptomus configuration."""
516
+ # Import here to avoid circular imports
517
+ from django_cfg.apps.payments.config.providers import CryptomusConfig
518
+
519
+ return CryptomusConfig(
520
+ api_key=SecretStr(api_key),
521
+ merchant_uuid=merchant_uuid,
522
+ sandbox=sandbox,
523
+ callback_url=callback_url,
524
+ success_url=success_url,
525
+ fail_url=fail_url,
526
+ **kwargs
527
+ )
528
+
529
+
530
+ __all__ = [
531
+ "PaymentsConfig",
532
+ "PaymentProviderConfig",
533
+ "NowPaymentsConfig",
534
+ "CryptAPIConfig",
535
+ "StripeConfig",
536
+ "SecuritySettings",
537
+ "RateLimitSettings",
538
+ "NotificationSettings",
539
+ "SubscriptionSettings",
540
+ "PaymentProvider",
541
+ "BillingPeriod",
542
+ "create_nowpayments_config",
543
+ "create_cryptapi_config",
544
+ "create_stripe_config",
545
+ "create_cryptomus_config",
546
+ ]
@@ -93,7 +93,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
93
93
  knowbase_enabled = base_module.is_knowbase_enabled()
94
94
  agents_enabled = base_module.is_agents_enabled()
95
95
  tasks_enabled = base_module.should_enable_tasks()
96
- payments_enabled = base_module.enable_payments()
96
+ payments_enabled = base_module.is_payments_enabled()
97
97
 
98
98
  # Add Support zone if enabled
99
99
  default_support_zone = 'cfg_support'
@@ -428,8 +428,57 @@ class TaskConfig(BaseModel, BaseCfgAutoModule):
428
428
 
429
429
  # === Utility Functions ===
430
430
 
431
+ def get_smart_queues(debug: bool = False) -> List[str]:
432
+ """
433
+ Get smart default queues based on enabled modules.
434
+
435
+ Automatically detects which django-cfg modules are enabled and adds
436
+ their corresponding queues to the default queue list.
437
+
438
+ Args:
439
+ debug: Whether running in debug mode (affects base queues)
440
+
441
+ Returns:
442
+ List of queue names appropriate for enabled modules
443
+ """
444
+ # Base queues
445
+ if debug:
446
+ base_queues = ["default"]
447
+ else:
448
+ base_queues = ["critical", "high", "default", "low", "background"]
449
+
450
+ # Try to detect enabled modules and add their queues
451
+ try:
452
+ from django_cfg.modules.base import BaseCfgModule
453
+ base_module = BaseCfgModule()
454
+
455
+ # Check for knowbase module (requires "knowbase" queue)
456
+ if base_module.is_knowbase_enabled():
457
+ if "knowbase" not in base_queues:
458
+ base_queues.append("knowbase")
459
+
460
+ # Check for payments module (requires "payments" queue)
461
+ if base_module.is_payments_enabled():
462
+ if "payments" not in base_queues:
463
+ base_queues.append("payments")
464
+
465
+ # Check for agents module (may require "agents" queue in future)
466
+ if base_module.is_agents_enabled():
467
+ if "agents" not in base_queues:
468
+ base_queues.append("agents")
469
+
470
+ logger.info(f"🎯 Smart queue detection: {base_queues}")
471
+
472
+ except Exception as e:
473
+ logger.warning(f"Failed to auto-detect queues, using defaults: {e}")
474
+
475
+ return base_queues
476
+
477
+
431
478
  def get_default_task_config(debug: bool = False) -> TaskConfig:
432
479
  """Get default task configuration based on environment."""
480
+ smart_queues = get_smart_queues(debug)
481
+
433
482
  if debug:
434
483
  # Development defaults
435
484
  return TaskConfig(
@@ -437,7 +486,7 @@ def get_default_task_config(debug: bool = False) -> TaskConfig:
437
486
  processes=2,
438
487
  threads=4,
439
488
  prometheus_enabled=False,
440
- queues=["default"],
489
+ queues=smart_queues,
441
490
  ),
442
491
  worker=WorkerConfig(
443
492
  log_level="DEBUG",
@@ -451,7 +500,7 @@ def get_default_task_config(debug: bool = False) -> TaskConfig:
451
500
  processes=8,
452
501
  threads=16,
453
502
  prometheus_enabled=True,
454
- queues=["critical", "high", "default", "low", "background"],
503
+ queues=smart_queues,
455
504
  ),
456
505
  worker=WorkerConfig(
457
506
  log_level="INFO",
@@ -77,7 +77,7 @@ class BaseCfgModule(ABC):
77
77
  """
78
78
  self._config = config
79
79
 
80
- def _get_config_key(self, key: str, default: Any) -> bool:
80
+ def _get_config_key(self, key: str, default: Any) -> Any:
81
81
  """
82
82
  Get a key from the configuration instance.
83
83
 
@@ -92,14 +92,14 @@ class BaseCfgModule(ABC):
92
92
  # If config is available, get the key
93
93
  if config is not None:
94
94
  result = getattr(config, key, default)
95
- return bool(result)
95
+ return result
96
96
 
97
97
  # Fallback to default if no config available
98
- return bool(default)
98
+ return default
99
99
 
100
100
  except Exception:
101
101
  # Return default on any error
102
- return bool(default)
102
+ return default
103
103
 
104
104
  def is_support_enabled(self) -> bool:
105
105
  """
@@ -175,14 +175,20 @@ class BaseCfgModule(ABC):
175
175
  """
176
176
  return self._get_config_key('enable_maintenance', False)
177
177
 
178
- def enable_payments(self) -> bool:
178
+ def is_payments_enabled(self) -> bool:
179
179
  """
180
180
  Check if django-cfg Payments is enabled.
181
181
 
182
182
  Returns:
183
183
  True if Payments is enabled, False otherwise
184
184
  """
185
- return self._get_config_key('enable_payments', False)
185
+ payments_config = self._get_config_key('payments', None)
186
+
187
+ # Only handle PaymentsConfig model
188
+ if payments_config and hasattr(payments_config, 'enabled'):
189
+ return payments_config.enabled
190
+
191
+ return False
186
192
 
187
193
 
188
194
  # Export the base class