django-cfg 1.2.29__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 (258) 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 -9
  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 +600 -108
  9. django_cfg/apps/payments/admin/filters.py +306 -199
  10. django_cfg/apps/payments/admin/payments_admin.py +470 -64
  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 +381 -0
  39. django_cfg/apps/payments/management/commands/manage_providers.py +408 -0
  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 +343 -163
  43. django_cfg/apps/payments/middleware/usage_tracking.py +250 -238
  44. django_cfg/apps/payments/migrations/0001_initial.py +708 -536
  45. django_cfg/apps/payments/models/__init__.py +16 -20
  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 +207 -67
  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 -284
  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 +344 -468
  67. django_cfg/apps/payments/services/core/subscription_service.py +425 -484
  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 +232 -71
  74. django_cfg/apps/payments/services/providers/nowpayments.py +404 -219
  75. django_cfg/apps/payments/services/providers/registry.py +429 -80
  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 +211 -130
  83. django_cfg/apps/payments/signals/balance_signals.py +174 -0
  84. django_cfg/apps/payments/signals/payment_signals.py +129 -98
  85. django_cfg/apps/payments/signals/subscription_signals.py +195 -143
  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 +46 -47
  93. django_cfg/apps/payments/urls_admin.py +49 -0
  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/apps/tasks/urls.py +0 -2
  110. django_cfg/apps/tasks/urls_admin.py +14 -0
  111. django_cfg/apps/urls.py +4 -4
  112. django_cfg/config.py +1 -1
  113. django_cfg/core/config.py +75 -4
  114. django_cfg/core/generation.py +25 -4
  115. django_cfg/core/integration/README.md +363 -0
  116. django_cfg/core/integration/__init__.py +47 -0
  117. django_cfg/core/integration/commands_collector.py +239 -0
  118. django_cfg/core/integration/display/__init__.py +15 -0
  119. django_cfg/core/integration/display/base.py +157 -0
  120. django_cfg/core/integration/display/ngrok.py +164 -0
  121. django_cfg/core/integration/display/startup.py +815 -0
  122. django_cfg/core/integration/url_integration.py +123 -0
  123. django_cfg/core/integration/version_checker.py +160 -0
  124. django_cfg/management/commands/auto_generate.py +4 -0
  125. django_cfg/management/commands/check_settings.py +6 -0
  126. django_cfg/management/commands/clear_constance.py +5 -2
  127. django_cfg/management/commands/create_token.py +6 -0
  128. django_cfg/management/commands/list_urls.py +6 -0
  129. django_cfg/management/commands/migrate_all.py +6 -0
  130. django_cfg/management/commands/migrator.py +3 -0
  131. django_cfg/management/commands/rundramatiq.py +6 -0
  132. django_cfg/management/commands/runserver_ngrok.py +51 -29
  133. django_cfg/management/commands/script.py +6 -0
  134. django_cfg/management/commands/show_config.py +12 -2
  135. django_cfg/management/commands/show_urls.py +4 -0
  136. django_cfg/management/commands/superuser.py +6 -0
  137. django_cfg/management/commands/task_clear.py +4 -1
  138. django_cfg/management/commands/task_status.py +3 -1
  139. django_cfg/management/commands/test_email.py +3 -0
  140. django_cfg/management/commands/test_telegram.py +6 -0
  141. django_cfg/management/commands/test_twilio.py +6 -0
  142. django_cfg/management/commands/tree.py +6 -0
  143. django_cfg/management/commands/validate_config.py +155 -149
  144. django_cfg/models/constance.py +31 -11
  145. django_cfg/models/payments.py +175 -498
  146. django_cfg/modules/django_currency/__init__.py +16 -11
  147. django_cfg/modules/django_currency/clients/__init__.py +4 -4
  148. django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
  149. django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
  150. django_cfg/modules/django_currency/core/__init__.py +1 -7
  151. django_cfg/modules/django_currency/core/converter.py +18 -23
  152. django_cfg/modules/django_currency/core/models.py +122 -11
  153. django_cfg/modules/django_currency/database/__init__.py +4 -4
  154. django_cfg/modules/django_currency/database/database_loader.py +190 -309
  155. django_cfg/modules/django_logger.py +160 -146
  156. django_cfg/modules/django_unfold/dashboard.py +65 -12
  157. django_cfg/registry/core.py +1 -0
  158. django_cfg/template_archive/django_sample.zip +0 -0
  159. django_cfg/templates/admin/components/action_grid.html +9 -9
  160. django_cfg/templates/admin/components/metric_card.html +5 -5
  161. django_cfg/templates/admin/components/status_badge.html +2 -2
  162. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
  163. django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
  164. django_cfg/templates/admin/snippets/components/system_health.html +1 -1
  165. django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
  166. django_cfg/utils/smart_defaults.py +222 -571
  167. django_cfg/utils/toolkit.py +51 -11
  168. {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/METADATA +5 -4
  169. {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/RECORD +172 -182
  170. django_cfg/apps/payments/__init__.py +0 -8
  171. django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
  172. django_cfg/apps/payments/config/module.py +0 -70
  173. django_cfg/apps/payments/config/providers.py +0 -105
  174. django_cfg/apps/payments/config/settings.py +0 -96
  175. django_cfg/apps/payments/config/utils.py +0 -52
  176. django_cfg/apps/payments/decorators.py +0 -291
  177. django_cfg/apps/payments/management/commands/README.md +0 -178
  178. django_cfg/apps/payments/management/commands/currency_stats.py +0 -323
  179. django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
  180. django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
  181. django_cfg/apps/payments/managers/__init__.py +0 -22
  182. django_cfg/apps/payments/managers/api_key_manager.py +0 -35
  183. django_cfg/apps/payments/managers/balance_manager.py +0 -361
  184. django_cfg/apps/payments/managers/currency_manager.py +0 -83
  185. django_cfg/apps/payments/managers/payment_manager.py +0 -44
  186. django_cfg/apps/payments/managers/subscription_manager.py +0 -37
  187. django_cfg/apps/payments/managers/tariff_manager.py +0 -29
  188. django_cfg/apps/payments/models/events.py +0 -73
  189. django_cfg/apps/payments/serializers/__init__.py +0 -56
  190. django_cfg/apps/payments/serializers/api_keys.py +0 -51
  191. django_cfg/apps/payments/serializers/balance.py +0 -59
  192. django_cfg/apps/payments/serializers/currencies.py +0 -55
  193. django_cfg/apps/payments/serializers/payments.py +0 -62
  194. django_cfg/apps/payments/serializers/subscriptions.py +0 -71
  195. django_cfg/apps/payments/serializers/tariffs.py +0 -56
  196. django_cfg/apps/payments/services/billing/__init__.py +0 -8
  197. django_cfg/apps/payments/services/cache/base.py +0 -30
  198. django_cfg/apps/payments/services/core/fallback_service.py +0 -432
  199. django_cfg/apps/payments/services/internal_types.py +0 -297
  200. django_cfg/apps/payments/services/middleware/__init__.py +0 -8
  201. django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
  202. django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -222
  203. django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
  204. django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
  205. django_cfg/apps/payments/services/providers/cryptomus.py +0 -311
  206. django_cfg/apps/payments/services/security/__init__.py +0 -34
  207. django_cfg/apps/payments/services/security/error_handler.py +0 -637
  208. django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
  209. django_cfg/apps/payments/services/security/webhook_validator.py +0 -475
  210. django_cfg/apps/payments/services/validators/__init__.py +0 -8
  211. django_cfg/apps/payments/static/payments/css/payments.css +0 -340
  212. django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
  213. django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
  214. django_cfg/apps/payments/static/payments/js/theme.js +0 -86
  215. django_cfg/apps/payments/tasks/__init__.py +0 -12
  216. django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
  217. django_cfg/apps/payments/templates/payments/base.html +0 -182
  218. django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
  219. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
  220. django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -36
  221. django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
  222. django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -27
  223. django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -144
  224. django_cfg/apps/payments/templates/payments/dashboard.html +0 -346
  225. django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
  226. django_cfg/apps/payments/urls_templates.py +0 -52
  227. django_cfg/apps/payments/utils/__init__.py +0 -45
  228. django_cfg/apps/payments/utils/billing_utils.py +0 -342
  229. django_cfg/apps/payments/utils/config_utils.py +0 -245
  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 -62
  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 -111
  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 -312
  241. django_cfg/apps/payments/views/templates/base.py +0 -204
  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 -164
  245. django_cfg/apps/payments/views/templates/qr_code.py +0 -174
  246. django_cfg/apps/payments/views/templates/stats.py +0 -240
  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 -65
  250. django_cfg/core/integration.py +0 -160
  251. django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
  252. django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
  253. django_cfg/template_archive/.gitignore +0 -1
  254. django_cfg/template_archive/__init__.py +0 -0
  255. django_cfg/urls.py +0 -33
  256. {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
  257. {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
  258. {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,311 +0,0 @@
1
- """
2
- Cryptomus payment provider implementation.
3
- """
4
-
5
- import logging
6
- import hashlib
7
- import json
8
- import base64
9
- from decimal import Decimal
10
- from typing import Dict, Any, Optional
11
- from dataclasses import dataclass
12
-
13
- import requests
14
- from pydantic import BaseModel, Field, validator
15
-
16
- from .base import PaymentProvider, ProviderResponse
17
- from ..internal_types import ProviderConfig
18
-
19
- logger = logging.getLogger(__name__)
20
-
21
-
22
- class CryptomusConfig(ProviderConfig):
23
- """Configuration for Cryptomus provider."""
24
-
25
- merchant_id: str = Field(..., description="Cryptomus merchant ID")
26
- api_key: str = Field(..., description="Cryptomus API key")
27
- test_mode: bool = Field(default=False, description="Enable test mode")
28
- callback_url: Optional[str] = Field(None, description="Default callback URL")
29
-
30
- @validator('merchant_id')
31
- def validate_merchant_id(cls, v):
32
- if not v or not v.strip():
33
- raise ValueError("Merchant ID is required")
34
- return v.strip()
35
-
36
- @validator('api_key')
37
- def validate_api_key(cls, v):
38
- if not v or len(v) < 10:
39
- raise ValueError("API key must be at least 10 characters")
40
- return v
41
-
42
-
43
- class CryptomusProvider(PaymentProvider):
44
- """Cryptomus payment provider with universal field mapping."""
45
-
46
- def __init__(self, config: CryptomusConfig):
47
- super().__init__(config)
48
- self.merchant_id = config.merchant_id
49
- self.api_key = config.api_key
50
- self.test_mode = config.test_mode
51
- self.base_url = "https://api.cryptomus.com/v1" if not config.test_mode else "https://api.cryptomus.com/v1"
52
-
53
- def create_payment(self, payment_data: dict) -> ProviderResponse:
54
- """
55
- Create payment using Cryptomus API.
56
- Maps to universal payment fields.
57
- """
58
- try:
59
- # Extract required data
60
- order_id = payment_data.get('order_id')
61
- amount = payment_data.get('amount')
62
- currency = payment_data.get('currency', 'USD')
63
- callback_url = payment_data.get('callback_url', self.config.callback_url)
64
-
65
- if not all([order_id, amount]):
66
- return ProviderResponse(
67
- success=False,
68
- error_message="Missing required fields: order_id, amount"
69
- )
70
-
71
- # Prepare Cryptomus API request
72
- payload = {
73
- "amount": str(amount),
74
- "currency": currency,
75
- "order_id": order_id,
76
- "url_callback": callback_url,
77
- "url_return": payment_data.get('return_url'),
78
- "url_success": payment_data.get('success_url'),
79
- "is_payment_multiple": False,
80
- "lifetime": 3600, # 1 hour
81
- "to_currency": payment_data.get('crypto_currency', 'BTC')
82
- }
83
-
84
- # Generate signature
85
- headers = self._generate_headers(payload)
86
-
87
- # Make API request
88
- response = requests.post(
89
- f"{self.base_url}/payment",
90
- json=payload,
91
- headers=headers,
92
- timeout=30
93
- )
94
-
95
- if response.status_code == 200:
96
- result = response.json()
97
-
98
- if result.get('state') == 0: # Success
99
- payment_info = result.get('result', {})
100
-
101
- return ProviderResponse(
102
- success=True,
103
- transaction_id=payment_info.get('uuid'),
104
- data={
105
- # Universal field mapping
106
- 'provider_payment_id': payment_info.get('uuid'),
107
- 'receiver_address': payment_info.get('address'),
108
- 'crypto_amount': float(payment_info.get('amount', 0)),
109
- 'provider_callback_url': callback_url,
110
- 'payment_url': payment_info.get('url'),
111
- 'qr_code': payment_info.get('static_qr'),
112
-
113
- # Cryptomus specific fields
114
- 'cryptomus_order_id': payment_info.get('order_id'),
115
- 'cryptomus_currency': payment_info.get('currency'),
116
- 'cryptomus_network': payment_info.get('network'),
117
- 'cryptomus_status': payment_info.get('status'),
118
- 'expires_at': payment_info.get('expired_at')
119
- }
120
- )
121
- else:
122
- error_msg = result.get('message', 'Unknown Cryptomus error')
123
- return ProviderResponse(
124
- success=False,
125
- error_message=f"Cryptomus API error: {error_msg}"
126
- )
127
- else:
128
- return ProviderResponse(
129
- success=False,
130
- error_message=f"HTTP {response.status_code}: {response.text}"
131
- )
132
-
133
- except requests.RequestException as e:
134
- logger.error(f"Cryptomus API request failed: {e}")
135
- return ProviderResponse(
136
- success=False,
137
- error_message=f"Network error: {str(e)}"
138
- )
139
- except Exception as e:
140
- logger.error(f"Cryptomus payment creation failed: {e}")
141
- return ProviderResponse(
142
- success=False,
143
- error_message=f"Unexpected error: {str(e)}"
144
- )
145
-
146
- def validate_webhook(self, webhook_data: Dict[str, Any],
147
- request_headers: Dict[str, str], raw_body: bytes) -> tuple[bool, Optional[str]]:
148
- """
149
- Validate Cryptomus webhook signature and required fields.
150
- """
151
- try:
152
- # Check required fields
153
- required_fields = ['uuid', 'order_id', 'amount', 'currency', 'status']
154
- for field in required_fields:
155
- if field not in webhook_data:
156
- return False, f"Missing required field: {field}"
157
-
158
- # Validate signature if provided
159
- sign = request_headers.get('sign') or webhook_data.get('sign')
160
- if sign:
161
- # Generate expected signature
162
- expected_sign = self._generate_webhook_signature(webhook_data)
163
- if sign != expected_sign:
164
- return False, "Invalid webhook signature"
165
-
166
- return True, None
167
-
168
- except Exception as e:
169
- logger.error(f"Cryptomus webhook validation failed: {e}")
170
- return False, f"Validation error: {str(e)}"
171
-
172
- def process_webhook(self, webhook_data: Dict[str, Any]) -> ProviderResponse:
173
- """
174
- Process Cryptomus webhook and map to universal fields.
175
- """
176
- try:
177
- # Map Cryptomus webhook fields to universal fields
178
- universal_data = {
179
- 'provider_payment_id': webhook_data.get('uuid'),
180
- 'status': self._map_status(webhook_data.get('status')),
181
- 'transaction_hash': webhook_data.get('txid'),
182
- 'sender_address': webhook_data.get('from'),
183
- 'receiver_address': webhook_data.get('to'),
184
- 'crypto_amount': float(webhook_data.get('amount', 0)),
185
- 'confirmations_count': int(webhook_data.get('confirmations', 0)),
186
-
187
- # Additional Cryptomus data
188
- 'cryptomus_network': webhook_data.get('network'),
189
- 'cryptomus_currency': webhook_data.get('currency'),
190
- 'cryptomus_commission': webhook_data.get('commission'),
191
- 'updated_at': webhook_data.get('updated_at')
192
- }
193
-
194
- return ProviderResponse(
195
- success=True,
196
- data=universal_data
197
- )
198
-
199
- except Exception as e:
200
- logger.error(f"Cryptomus webhook processing failed: {e}")
201
- return ProviderResponse(
202
- success=False,
203
- error_message=f"Webhook processing error: {str(e)}"
204
- )
205
-
206
- def get_payment_status(self, payment_id: str) -> ProviderResponse:
207
- """Get payment status from Cryptomus."""
208
- try:
209
- payload = {"uuid": payment_id}
210
- headers = self._generate_headers(payload)
211
-
212
- response = requests.post(
213
- f"{self.base_url}/payment/info",
214
- json=payload,
215
- headers=headers,
216
- timeout=30
217
- )
218
-
219
- if response.status_code == 200:
220
- result = response.json()
221
- if result.get('state') == 0:
222
- payment_info = result.get('result', {})
223
-
224
- return ProviderResponse(
225
- success=True,
226
- data={
227
- 'status': self._map_status(payment_info.get('status')),
228
- 'provider_payment_id': payment_info.get('uuid'),
229
- 'transaction_hash': payment_info.get('txid'),
230
- 'crypto_amount': float(payment_info.get('amount', 0)),
231
- 'confirmations_count': int(payment_info.get('confirmations', 0))
232
- }
233
- )
234
-
235
- return ProviderResponse(
236
- success=False,
237
- error_message="Failed to get payment status"
238
- )
239
-
240
- except Exception as e:
241
- logger.error(f"Cryptomus status check failed: {e}")
242
- return ProviderResponse(
243
- success=False,
244
- error_message=f"Status check error: {str(e)}"
245
- )
246
-
247
- def _generate_headers(self, payload: dict) -> dict:
248
- """Generate required headers for Cryptomus API."""
249
- data_string = base64.b64encode(json.dumps(payload).encode()).decode()
250
- sign = hashlib.md5(f"{data_string}{self.api_key}".encode()).hexdigest()
251
-
252
- return {
253
- "merchant": self.merchant_id,
254
- "sign": sign,
255
- "Content-Type": "application/json"
256
- }
257
-
258
- def _generate_webhook_signature(self, webhook_data: dict) -> str:
259
- """Generate expected webhook signature for validation."""
260
- # Cryptomus webhook signature generation
261
- data_string = base64.b64encode(json.dumps(webhook_data, sort_keys=True).encode()).decode()
262
- return hashlib.md5(f"{data_string}{self.api_key}".encode()).hexdigest()
263
-
264
- def _map_status(self, cryptomus_status: str) -> str:
265
- """Map Cryptomus status to universal status."""
266
- status_mapping = {
267
- 'check': 'pending',
268
- 'process': 'pending',
269
- 'confirm_check': 'pending',
270
- 'confirmed': 'completed',
271
- 'fail': 'failed',
272
- 'cancel': 'cancelled',
273
- 'system_fail': 'failed',
274
- 'refund_process': 'refunding',
275
- 'refund_fail': 'failed',
276
- 'refund_paid': 'refunded'
277
- }
278
- return status_mapping.get(cryptomus_status, 'pending')
279
-
280
- def get_supported_currencies(self) -> ProviderResponse:
281
- """Get supported currencies from Cryptomus."""
282
- try:
283
- headers = self._generate_headers({})
284
-
285
- response = requests.post(
286
- f"{self.base_url}/exchange-rate/list",
287
- json={},
288
- headers=headers,
289
- timeout=30
290
- )
291
-
292
- if response.status_code == 200:
293
- result = response.json()
294
- if result.get('state') == 0:
295
- currencies = result.get('result', [])
296
- return ProviderResponse(
297
- success=True,
298
- data={'currencies': currencies}
299
- )
300
-
301
- return ProviderResponse(
302
- success=False,
303
- error_message="Failed to get supported currencies"
304
- )
305
-
306
- except Exception as e:
307
- logger.error(f"Cryptomus currencies request failed: {e}")
308
- return ProviderResponse(
309
- success=False,
310
- error_message=f"Currencies request error: {str(e)}"
311
- )
@@ -1,34 +0,0 @@
1
- """
2
- Security services for payment system.
3
- Foundation layer security components.
4
- """
5
-
6
- from .webhook_validator import webhook_validator, WebhookValidator
7
- from .error_handler import (
8
- error_handler,
9
- CentralizedErrorHandler,
10
- PaymentError,
11
- SecurityError,
12
- ProviderError,
13
- ValidationError,
14
- ErrorSeverity,
15
- ErrorCategory,
16
- error_context
17
- )
18
- from .payment_notifications import payment_notifications, PaymentNotifications
19
-
20
- __all__ = [
21
- 'webhook_validator',
22
- 'WebhookValidator',
23
- 'error_handler',
24
- 'CentralizedErrorHandler',
25
- 'PaymentError',
26
- 'SecurityError',
27
- 'ProviderError',
28
- 'ValidationError',
29
- 'ErrorSeverity',
30
- 'ErrorCategory',
31
- 'error_context',
32
- 'payment_notifications',
33
- 'PaymentNotifications'
34
- ]