django-cfg 1.2.31__py3-none-any.whl → 1.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/api/health/views.py +4 -2
  3. django_cfg/apps/knowbase/config/settings.py +16 -15
  4. django_cfg/apps/payments/README.md +326 -0
  5. django_cfg/apps/payments/admin/__init__.py +20 -10
  6. django_cfg/apps/payments/admin/api_keys_admin.py +521 -237
  7. django_cfg/apps/payments/admin/balance_admin.py +592 -297
  8. django_cfg/apps/payments/admin/currencies_admin.py +526 -222
  9. django_cfg/apps/payments/admin/filters.py +306 -199
  10. django_cfg/apps/payments/admin/payments_admin.py +465 -70
  11. django_cfg/apps/payments/admin/subscriptions_admin.py +578 -128
  12. django_cfg/apps/payments/admin_interface/__init__.py +18 -0
  13. django_cfg/apps/payments/admin_interface/templates/payments/base.html +162 -0
  14. django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +38 -0
  15. django_cfg/apps/payments/admin_interface/templates/payments/components/loading_spinner.html +16 -0
  16. django_cfg/apps/payments/admin_interface/templates/payments/components/notification.html +27 -0
  17. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_card.html +86 -0
  18. django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +39 -0
  19. django_cfg/apps/payments/admin_interface/templates/payments/currency_converter.html +382 -0
  20. django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +300 -0
  21. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +303 -0
  22. django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +382 -0
  23. django_cfg/apps/payments/admin_interface/templates/payments/payment_status.html +500 -0
  24. django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +594 -0
  25. django_cfg/apps/payments/admin_interface/views/__init__.py +23 -0
  26. django_cfg/apps/payments/admin_interface/views/payment_views.py +259 -0
  27. django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +37 -0
  28. django_cfg/apps/payments/apps.py +34 -9
  29. django_cfg/apps/payments/config/__init__.py +28 -51
  30. django_cfg/apps/payments/config/constance/__init__.py +22 -0
  31. django_cfg/apps/payments/config/constance/config_service.py +123 -0
  32. django_cfg/apps/payments/config/constance/fields.py +69 -0
  33. django_cfg/apps/payments/config/constance/settings.py +160 -0
  34. django_cfg/apps/payments/config/django_cfg_integration.py +202 -0
  35. django_cfg/apps/payments/config/helpers.py +130 -0
  36. django_cfg/apps/payments/management/__init__.py +1 -3
  37. django_cfg/apps/payments/management/commands/__init__.py +1 -3
  38. django_cfg/apps/payments/management/commands/manage_currencies.py +303 -151
  39. django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
  40. django_cfg/apps/payments/middleware/__init__.py +3 -1
  41. django_cfg/apps/payments/middleware/api_access.py +329 -222
  42. django_cfg/apps/payments/middleware/rate_limiting.py +342 -152
  43. django_cfg/apps/payments/middleware/usage_tracking.py +249 -240
  44. django_cfg/apps/payments/migrations/0001_initial.py +708 -536
  45. django_cfg/apps/payments/models/__init__.py +13 -18
  46. django_cfg/apps/payments/models/api_keys.py +121 -43
  47. django_cfg/apps/payments/models/balance.py +150 -115
  48. django_cfg/apps/payments/models/base.py +68 -15
  49. django_cfg/apps/payments/models/currencies.py +172 -148
  50. django_cfg/apps/payments/models/managers/__init__.py +44 -0
  51. django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
  52. django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
  53. django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
  54. django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
  55. django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
  56. django_cfg/apps/payments/models/payments.py +235 -285
  57. django_cfg/apps/payments/models/subscriptions.py +257 -177
  58. django_cfg/apps/payments/models/tariffs.py +147 -40
  59. django_cfg/apps/payments/services/__init__.py +209 -56
  60. django_cfg/apps/payments/services/cache/__init__.py +6 -6
  61. django_cfg/apps/payments/services/cache/{simple_cache.py → cache_service.py} +112 -12
  62. django_cfg/apps/payments/services/core/__init__.py +10 -6
  63. django_cfg/apps/payments/services/core/balance_service.py +435 -360
  64. django_cfg/apps/payments/services/core/base.py +166 -0
  65. django_cfg/apps/payments/services/core/currency_service.py +478 -0
  66. django_cfg/apps/payments/services/core/payment_service.py +346 -467
  67. django_cfg/apps/payments/services/core/subscription_service.py +425 -481
  68. django_cfg/apps/payments/services/core/webhook_service.py +410 -0
  69. django_cfg/apps/payments/services/integrations/__init__.py +29 -0
  70. django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
  71. django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
  72. django_cfg/apps/payments/services/providers/__init__.py +9 -14
  73. django_cfg/apps/payments/services/providers/base.py +234 -174
  74. django_cfg/apps/payments/services/providers/nowpayments.py +478 -0
  75. django_cfg/apps/payments/services/providers/registry.py +367 -301
  76. django_cfg/apps/payments/services/types/__init__.py +78 -0
  77. django_cfg/apps/payments/services/types/data.py +177 -0
  78. django_cfg/apps/payments/services/types/requests.py +150 -0
  79. django_cfg/apps/payments/services/types/responses.py +156 -0
  80. django_cfg/apps/payments/services/types/webhooks.py +232 -0
  81. django_cfg/apps/payments/signals/__init__.py +33 -8
  82. django_cfg/apps/payments/signals/api_key_signals.py +210 -129
  83. django_cfg/apps/payments/signals/balance_signals.py +174 -0
  84. django_cfg/apps/payments/signals/payment_signals.py +128 -103
  85. django_cfg/apps/payments/signals/subscription_signals.py +194 -142
  86. django_cfg/apps/payments/static/payments/css/components.css +380 -0
  87. django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
  88. django_cfg/apps/payments/static/payments/js/components.js +545 -0
  89. django_cfg/apps/payments/static/payments/js/utils.js +412 -0
  90. django_cfg/apps/payments/templatetags/__init__.py +1 -1
  91. django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
  92. django_cfg/apps/payments/urls.py +45 -48
  93. django_cfg/apps/payments/urls_admin.py +33 -42
  94. django_cfg/apps/payments/views/api/__init__.py +101 -0
  95. django_cfg/apps/payments/views/api/api_keys.py +387 -0
  96. django_cfg/apps/payments/views/api/balances.py +381 -0
  97. django_cfg/apps/payments/views/api/base.py +298 -0
  98. django_cfg/apps/payments/views/api/currencies.py +402 -0
  99. django_cfg/apps/payments/views/api/payments.py +415 -0
  100. django_cfg/apps/payments/views/api/subscriptions.py +475 -0
  101. django_cfg/apps/payments/views/api/webhooks.py +476 -0
  102. django_cfg/apps/payments/views/serializers/__init__.py +99 -0
  103. django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
  104. django_cfg/apps/payments/views/serializers/balances.py +300 -0
  105. django_cfg/apps/payments/views/serializers/currencies.py +335 -0
  106. django_cfg/apps/payments/views/serializers/payments.py +387 -0
  107. django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
  108. django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
  109. django_cfg/config.py +1 -1
  110. django_cfg/core/config.py +40 -4
  111. django_cfg/core/generation.py +25 -4
  112. django_cfg/core/integration/README.md +363 -0
  113. django_cfg/core/integration/__init__.py +47 -0
  114. django_cfg/core/integration/commands_collector.py +239 -0
  115. django_cfg/core/integration/display/__init__.py +15 -0
  116. django_cfg/core/integration/display/base.py +157 -0
  117. django_cfg/core/integration/display/ngrok.py +164 -0
  118. django_cfg/core/integration/display/startup.py +815 -0
  119. django_cfg/core/integration/url_integration.py +123 -0
  120. django_cfg/core/integration/version_checker.py +160 -0
  121. django_cfg/management/commands/auto_generate.py +4 -0
  122. django_cfg/management/commands/check_settings.py +6 -0
  123. django_cfg/management/commands/clear_constance.py +5 -2
  124. django_cfg/management/commands/create_token.py +6 -0
  125. django_cfg/management/commands/list_urls.py +6 -0
  126. django_cfg/management/commands/migrate_all.py +6 -0
  127. django_cfg/management/commands/migrator.py +3 -0
  128. django_cfg/management/commands/rundramatiq.py +6 -0
  129. django_cfg/management/commands/runserver_ngrok.py +51 -29
  130. django_cfg/management/commands/script.py +6 -0
  131. django_cfg/management/commands/show_config.py +12 -2
  132. django_cfg/management/commands/show_urls.py +4 -0
  133. django_cfg/management/commands/superuser.py +6 -0
  134. django_cfg/management/commands/task_clear.py +4 -1
  135. django_cfg/management/commands/task_status.py +3 -1
  136. django_cfg/management/commands/test_email.py +3 -0
  137. django_cfg/management/commands/test_telegram.py +6 -0
  138. django_cfg/management/commands/test_twilio.py +6 -0
  139. django_cfg/management/commands/tree.py +6 -0
  140. django_cfg/management/commands/validate_config.py +155 -149
  141. django_cfg/models/constance.py +31 -11
  142. django_cfg/models/payments.py +175 -492
  143. django_cfg/modules/django_logger.py +160 -146
  144. django_cfg/modules/django_unfold/dashboard.py +64 -16
  145. django_cfg/registry/core.py +1 -0
  146. django_cfg/template_archive/django_sample.zip +0 -0
  147. django_cfg/utils/smart_defaults.py +222 -571
  148. django_cfg/utils/toolkit.py +51 -11
  149. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/METADATA +4 -1
  150. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/RECORD +153 -185
  151. django_cfg/apps/payments/__init__.py +0 -8
  152. django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
  153. django_cfg/apps/payments/config/module.py +0 -70
  154. django_cfg/apps/payments/config/providers.py +0 -105
  155. django_cfg/apps/payments/config/settings.py +0 -96
  156. django_cfg/apps/payments/config/utils.py +0 -52
  157. django_cfg/apps/payments/decorators.py +0 -291
  158. django_cfg/apps/payments/management/commands/README.md +0 -146
  159. django_cfg/apps/payments/management/commands/currency_stats.py +0 -304
  160. django_cfg/apps/payments/managers/__init__.py +0 -23
  161. django_cfg/apps/payments/managers/api_key_manager.py +0 -35
  162. django_cfg/apps/payments/managers/balance_manager.py +0 -361
  163. django_cfg/apps/payments/managers/currency_manager.py +0 -306
  164. django_cfg/apps/payments/managers/payment_manager.py +0 -192
  165. django_cfg/apps/payments/managers/subscription_manager.py +0 -37
  166. django_cfg/apps/payments/managers/tariff_manager.py +0 -29
  167. django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +0 -241
  168. django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +0 -30
  169. django_cfg/apps/payments/models/events.py +0 -73
  170. django_cfg/apps/payments/serializers/__init__.py +0 -57
  171. django_cfg/apps/payments/serializers/api_keys.py +0 -51
  172. django_cfg/apps/payments/serializers/balance.py +0 -59
  173. django_cfg/apps/payments/serializers/currencies.py +0 -63
  174. django_cfg/apps/payments/serializers/payments.py +0 -62
  175. django_cfg/apps/payments/serializers/subscriptions.py +0 -71
  176. django_cfg/apps/payments/serializers/tariffs.py +0 -56
  177. django_cfg/apps/payments/services/billing/__init__.py +0 -8
  178. django_cfg/apps/payments/services/cache/base.py +0 -30
  179. django_cfg/apps/payments/services/core/fallback_service.py +0 -432
  180. django_cfg/apps/payments/services/internal_types.py +0 -461
  181. django_cfg/apps/payments/services/middleware/__init__.py +0 -8
  182. django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
  183. django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -76
  184. django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
  185. django_cfg/apps/payments/services/providers/cryptapi/__init__.py +0 -4
  186. django_cfg/apps/payments/services/providers/cryptapi/config.py +0 -8
  187. django_cfg/apps/payments/services/providers/cryptapi/models.py +0 -192
  188. django_cfg/apps/payments/services/providers/cryptapi/provider.py +0 -439
  189. django_cfg/apps/payments/services/providers/cryptomus/__init__.py +0 -4
  190. django_cfg/apps/payments/services/providers/cryptomus/models.py +0 -176
  191. django_cfg/apps/payments/services/providers/cryptomus/provider.py +0 -429
  192. django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +0 -564
  193. django_cfg/apps/payments/services/providers/models/__init__.py +0 -34
  194. django_cfg/apps/payments/services/providers/models/currencies.py +0 -190
  195. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +0 -4
  196. django_cfg/apps/payments/services/providers/nowpayments/models.py +0 -196
  197. django_cfg/apps/payments/services/providers/nowpayments/provider.py +0 -380
  198. django_cfg/apps/payments/services/providers/stripe/__init__.py +0 -4
  199. django_cfg/apps/payments/services/providers/stripe/models.py +0 -184
  200. django_cfg/apps/payments/services/providers/stripe/provider.py +0 -109
  201. django_cfg/apps/payments/services/security/__init__.py +0 -34
  202. django_cfg/apps/payments/services/security/error_handler.py +0 -635
  203. django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
  204. django_cfg/apps/payments/services/security/webhook_validator.py +0 -474
  205. django_cfg/apps/payments/static/payments/css/payments.css +0 -340
  206. django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
  207. django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
  208. django_cfg/apps/payments/static/payments/js/theme.js +0 -86
  209. django_cfg/apps/payments/tasks/__init__.py +0 -12
  210. django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
  211. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +0 -50
  212. django_cfg/apps/payments/templates/payments/base.html +0 -182
  213. django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
  214. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
  215. django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -43
  216. django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
  217. django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -34
  218. django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -148
  219. django_cfg/apps/payments/templates/payments/dashboard.html +0 -258
  220. django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +0 -35
  221. django_cfg/apps/payments/templates/payments/payment_create.html +0 -579
  222. django_cfg/apps/payments/templates/payments/payment_detail.html +0 -373
  223. django_cfg/apps/payments/templates/payments/payment_list.html +0 -354
  224. django_cfg/apps/payments/templates/payments/stats.html +0 -261
  225. django_cfg/apps/payments/templates/payments/test.html +0 -213
  226. django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
  227. django_cfg/apps/payments/utils/__init__.py +0 -43
  228. django_cfg/apps/payments/utils/billing_utils.py +0 -342
  229. django_cfg/apps/payments/utils/config_utils.py +0 -239
  230. django_cfg/apps/payments/utils/middleware_utils.py +0 -228
  231. django_cfg/apps/payments/utils/validation_utils.py +0 -94
  232. django_cfg/apps/payments/views/__init__.py +0 -63
  233. django_cfg/apps/payments/views/api_key_views.py +0 -164
  234. django_cfg/apps/payments/views/balance_views.py +0 -75
  235. django_cfg/apps/payments/views/currency_views.py +0 -122
  236. django_cfg/apps/payments/views/payment_views.py +0 -149
  237. django_cfg/apps/payments/views/subscription_views.py +0 -135
  238. django_cfg/apps/payments/views/tariff_views.py +0 -131
  239. django_cfg/apps/payments/views/templates/__init__.py +0 -25
  240. django_cfg/apps/payments/views/templates/ajax.py +0 -451
  241. django_cfg/apps/payments/views/templates/base.py +0 -212
  242. django_cfg/apps/payments/views/templates/dashboard.py +0 -60
  243. django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
  244. django_cfg/apps/payments/views/templates/payment_management.py +0 -158
  245. django_cfg/apps/payments/views/templates/qr_code.py +0 -174
  246. django_cfg/apps/payments/views/templates/stats.py +0 -244
  247. django_cfg/apps/payments/views/templates/utils.py +0 -181
  248. django_cfg/apps/payments/views/webhook_views.py +0 -266
  249. django_cfg/apps/payments/viewsets.py +0 -66
  250. django_cfg/core/integration.py +0 -160
  251. django_cfg/template_archive/.gitignore +0 -1
  252. django_cfg/template_archive/__init__.py +0 -0
  253. django_cfg/urls.py +0 -33
  254. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
  255. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
  256. {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,541 +1,224 @@
1
1
  """
2
- Payment system configuration models for Django-CFG.
2
+ Payments configuration model for Django-CFG.
3
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.
4
+ Simple, clean configuration following django-cfg philosophy.
7
5
  """
8
6
 
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
7
+ from pydantic import BaseModel, Field
8
+ from typing import List, Dict, Optional
14
9
 
15
- logger = logging.getLogger(__name__)
16
10
 
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."""
11
+ class PaymentsConfig(BaseModel):
12
+ """
13
+ Payments app configuration for django-cfg.
34
14
 
35
- name: str = Field(
36
- description="Provider name (e.g., 'nowpayments', 'cryptapi', 'stripe')"
37
- )
15
+ Static configuration that doesn't change at runtime.
16
+ Dynamic settings (API keys, secrets) are handled by Constance.
17
+ """
18
+
19
+ # Core settings
38
20
  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"
21
+ default=False,
22
+ description="Enable payments app"
60
23
  )
61
24
 
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"
25
+ # Middleware settings
26
+ middleware_enabled: bool = Field(
27
+ default=True,
28
+ description="Enable payments middleware"
91
29
  )
92
30
 
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"
31
+ api_prefixes: List[str] = Field(
32
+ default=['/api/'],
33
+ description="API path prefixes that require authentication"
126
34
  )
127
35
 
128
- # CryptAPI doesn't use traditional API keys
129
- api_key: SecretStr = Field(
130
- default=SecretStr("not_required"),
131
- description="Not required for CryptAPI"
36
+ exempt_paths: List[str] = Field(
37
+ default=[
38
+ '/api/payments/create/',
39
+ '/api/payments/status/',
40
+ '/api/currencies/rates/',
41
+ '/api/currencies/supported/',
42
+ '/api/api-keys/create/',
43
+ '/api/api-keys/validate/',
44
+ '/api/health/',
45
+ '/admin/',
46
+ '/static/',
47
+ '/media/',
48
+ ],
49
+ description="Paths exempt from API authentication"
132
50
  )
133
51
 
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"
52
+ # Rate limiting defaults
53
+ rate_limiting_enabled: bool = Field(
54
+ default=True,
55
+ description="Enable rate limiting middleware"
165
56
  )
166
57
 
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"
58
+ default_rate_limits: Dict[str, int] = Field(
59
+ default={
60
+ 'anonymous': 60,
61
+ 'authenticated': 300,
62
+ 'free': 100,
63
+ 'basic': 500,
64
+ 'premium': 2000,
65
+ 'enterprise': 10000,
66
+ },
67
+ description="Default rate limits (requests per minute) by tier"
199
68
  )
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
69
 
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"
70
+ # Usage tracking
71
+ usage_tracking_enabled: bool = Field(
72
+ default=True,
73
+ description="Enable usage tracking middleware"
217
74
  )
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
75
 
233
- email_notifications: bool = Field(
234
- default=True,
235
- description="Send email notifications for payment events"
76
+ track_anonymous_usage: bool = Field(
77
+ default=False,
78
+ description="Track anonymous user requests"
236
79
  )
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
80
 
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"
81
+ # Cache settings
82
+ cache_timeouts: Dict[str, int] = Field(
83
+ default={
84
+ 'api_key': 300, # 5 minutes
85
+ 'rate_limit': 3600, # 1 hour
86
+ 'session': 1800, # 30 minutes
87
+ 'default': 600 # 10 minutes
88
+ },
89
+ description="Cache timeout settings in seconds"
275
90
  )
276
-
277
-
278
- class PaymentsConfig(BaseModel):
279
- """
280
- Universal payment system configuration.
281
91
 
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
- """
92
+ def get_middleware_classes(self) -> List[str]:
93
+ """
94
+ Get middleware classes to add to Django MIDDLEWARE setting.
95
+
96
+ Returns:
97
+ List of middleware class paths
98
+ """
99
+ if not self.enabled or not self.middleware_enabled:
100
+ return []
101
+
102
+ middleware = []
103
+
104
+ # Always add API access middleware first
105
+ middleware.append('django_cfg.apps.payments.middleware.APIAccessMiddleware')
106
+
107
+ # Add rate limiting if enabled
108
+ if self.rate_limiting_enabled:
109
+ middleware.append('django_cfg.apps.payments.middleware.RateLimitingMiddleware')
110
+
111
+ # Add usage tracking if enabled
112
+ if self.usage_tracking_enabled:
113
+ middleware.append('django_cfg.apps.payments.middleware.UsageTrackingMiddleware')
114
+
115
+ return middleware
286
116
 
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
- )
117
+ def should_enable_tasks(self) -> bool:
118
+ """
119
+ Check if payments app requires Celery tasks.
120
+
121
+ Returns:
122
+ True if tasks should be enabled
123
+ """
124
+ return self.enabled # Enable tasks if payments is enabled
300
125
 
126
+ # Navigation and UI feature checks
127
+ def show_webhook_dashboard(self) -> bool:
128
+ """Check if webhook dashboard should be shown in navigation."""
129
+ return self.enabled
301
130
 
302
- # === Payment Providers ===
303
- providers: List[PaymentProviderConfig] = Field(
304
- default_factory=list,
305
- description="Payment provider configurations"
306
- )
131
+ def show_payment_creation(self) -> bool:
132
+ """Check if payment creation should be shown in navigation."""
133
+ return self.enabled
307
134
 
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
- )
135
+ def show_currency_converter(self) -> bool:
136
+ """Check if currency converter should be shown in navigation."""
137
+ return self.enabled
325
138
 
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
- )
139
+ def show_api_management(self) -> bool:
140
+ """Check if API key management should be shown in navigation."""
141
+ return self.enabled
355
142
 
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
- )
143
+ def show_subscription_management(self) -> bool:
144
+ """Check if subscription management should be shown in navigation."""
145
+ return self.enabled
365
146
 
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
- )
147
+ def show_balance_management(self) -> bool:
148
+ """Check if balance management should be shown in navigation."""
149
+ return self.enabled
375
150
 
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")
151
+ def show_transaction_history(self) -> bool:
152
+ """Check if transaction history should be shown in navigation."""
153
+ return self.enabled
154
+
155
+ def show_currency_management(self) -> bool:
156
+ """Check if currency management should be shown in navigation."""
157
+ return self.enabled
158
+
159
+ def show_rate_limiting_features(self) -> bool:
160
+ """Check if rate limiting features should be shown."""
161
+ return self.enabled and self.rate_limiting_enabled
162
+
163
+ def show_usage_tracking_features(self) -> bool:
164
+ """Check if usage tracking features should be shown."""
165
+ return self.enabled and self.usage_tracking_enabled
166
+
167
+ def get_enabled_navigation_items(self) -> List[str]:
168
+ """
169
+ Get list of enabled navigation items for dynamic UI generation.
382
170
 
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")
171
+ Returns:
172
+ List of enabled navigation item identifiers
173
+ """
174
+ items = []
387
175
 
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")
176
+ if not self.enabled:
177
+ return items
392
178
 
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")
179
+ # Core features (always enabled if payments is enabled)
180
+ items.extend([
181
+ 'payment_dashboard',
182
+ 'payments_admin',
183
+ 'currencies_admin',
184
+ 'networks_admin',
185
+ 'provider_currencies_admin',
186
+ ])
401
187
 
402
- # Remove leading/trailing slashes for consistency
403
- v = v.strip("/")
188
+ # Optional features based on configuration
189
+ if self.show_webhook_dashboard():
190
+ items.append('webhook_dashboard')
404
191
 
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")
192
+ if self.show_payment_creation():
193
+ items.append('payment_creation')
408
194
 
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 = []
195
+ if self.show_currency_converter():
196
+ items.append('currency_converter')
430
197
 
431
- if not self.middleware_enabled:
432
- return middleware
198
+ if self.show_api_management():
199
+ items.extend(['api_keys_admin', 'endpoint_groups_admin'])
433
200
 
434
- if self.enable_api_key_system:
435
- middleware.append("django_cfg.apps.payments.middleware.APIAccessMiddleware")
201
+ if self.show_subscription_management():
202
+ items.extend(['subscriptions_admin', 'tariffs_admin'])
436
203
 
437
- if self.rate_limits.enabled:
438
- middleware.append("django_cfg.apps.payments.middleware.RateLimitingMiddleware")
204
+ if self.show_balance_management():
205
+ items.append('balances_admin')
439
206
 
440
- if self.enable_subscription_system:
441
- middleware.append("django_cfg.apps.payments.middleware.UsageTrackingMiddleware")
207
+ if self.show_transaction_history():
208
+ items.append('transactions_admin')
442
209
 
443
- # Add custom middleware
444
- middleware.extend(self.custom_middleware)
445
-
446
- return middleware
210
+ return items
447
211
 
448
- def should_enable_tasks(self) -> bool:
212
+ @classmethod
213
+ def get_current_config(cls) -> 'PaymentsConfig':
449
214
  """
450
- Determine if background tasks should be enabled for payments.
215
+ Get current payments configuration from django-cfg.
451
216
 
452
- Tasks are enabled if webhook processing is enabled.
217
+ Uses PaymentsConfigManager for consistent access.
453
218
  """
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
- ipn_secret: Optional[str] = None,
461
- **kwargs
462
- ) -> NowPaymentsConfig:
463
- """Helper to create NowPayments configuration."""
464
- return NowPaymentsConfig(
465
- name="nowpayments",
466
- api_key=SecretStr(api_key),
467
- ipn_secret=SecretStr(ipn_secret) if ipn_secret else None,
468
- **kwargs
469
- )
470
-
471
-
472
- def create_cryptapi_config(
473
- own_address: str,
474
- callback_url: Optional[str] = None,
475
- **kwargs
476
- ) -> CryptAPIConfig:
477
- """Helper to create CryptAPI configuration."""
478
- return CryptAPIConfig(
479
- name="cryptapi",
480
- own_address=own_address,
481
- callback_url=callback_url,
482
- **kwargs
483
- )
484
-
485
-
486
- def create_stripe_config(
487
- api_key: str,
488
- publishable_key: Optional[str] = None,
489
- webhook_endpoint_secret: Optional[str] = None,
490
- **kwargs
491
- ) -> StripeConfig:
492
- """Helper to create Stripe configuration with automatic sandbox detection."""
493
- return StripeConfig(
494
- name="stripe",
495
- api_key=SecretStr(api_key),
496
- publishable_key=publishable_key,
497
- webhook_endpoint_secret=SecretStr(webhook_endpoint_secret) if webhook_endpoint_secret else None,
498
- **kwargs
499
- )
500
-
501
-
502
- def create_cryptomus_config(
503
- api_key: str,
504
- merchant_uuid: str,
505
- callback_url: Optional[str] = None,
506
- success_url: Optional[str] = None,
507
- fail_url: Optional[str] = None,
508
- **kwargs
509
- ):
510
- """Helper to create Cryptomus configuration with automatic sandbox detection."""
511
- # Import here to avoid circular imports
512
- from django_cfg.apps.payments.config.providers import CryptomusConfig
513
-
514
- return CryptomusConfig(
515
- name="cryptomus",
516
- api_key=SecretStr(api_key),
517
- merchant_uuid=merchant_uuid,
518
- callback_url=callback_url,
519
- success_url=success_url,
520
- fail_url=fail_url,
521
- **kwargs
522
- )
523
-
524
-
525
- __all__ = [
526
- "PaymentsConfig",
527
- "PaymentProviderConfig",
528
- "NowPaymentsConfig",
529
- "CryptAPIConfig",
530
- "StripeConfig",
531
- "SecuritySettings",
532
- "RateLimitSettings",
533
- "NotificationSettings",
534
- "SubscriptionSettings",
535
- "PaymentProvider",
536
- "BillingPeriod",
537
- "create_nowpayments_config",
538
- "create_cryptapi_config",
539
- "create_stripe_config",
540
- "create_cryptomus_config",
541
- ]
219
+ try:
220
+ # Import here to avoid circular dependencies
221
+ from django_cfg.apps.payments.config.django_cfg_integration import PaymentsConfigManager
222
+ return PaymentsConfigManager.get_payments_config_safe()
223
+ except Exception:
224
+ return cls()