django-cfg 1.2.31__py3-none-any.whl → 1.3.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/api/health/views.py +4 -2
- django_cfg/apps/knowbase/config/settings.py +16 -15
- django_cfg/apps/payments/README.md +326 -0
- django_cfg/apps/payments/admin/__init__.py +20 -10
- django_cfg/apps/payments/admin/api_keys_admin.py +521 -237
- django_cfg/apps/payments/admin/balance_admin.py +592 -297
- django_cfg/apps/payments/admin/currencies_admin.py +526 -222
- django_cfg/apps/payments/admin/filters.py +306 -199
- django_cfg/apps/payments/admin/payments_admin.py +465 -70
- django_cfg/apps/payments/admin/subscriptions_admin.py +578 -128
- django_cfg/apps/payments/admin_interface/__init__.py +18 -0
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +162 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +38 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/loading_spinner.html +16 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/notification.html +27 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/provider_card.html +86 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +39 -0
- django_cfg/apps/payments/admin_interface/templates/payments/currency_converter.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +300 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +303 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_status.html +500 -0
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +594 -0
- django_cfg/apps/payments/admin_interface/views/__init__.py +23 -0
- django_cfg/apps/payments/admin_interface/views/payment_views.py +259 -0
- django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +37 -0
- django_cfg/apps/payments/apps.py +34 -9
- django_cfg/apps/payments/config/__init__.py +28 -51
- django_cfg/apps/payments/config/constance/__init__.py +22 -0
- django_cfg/apps/payments/config/constance/config_service.py +123 -0
- django_cfg/apps/payments/config/constance/fields.py +69 -0
- django_cfg/apps/payments/config/constance/settings.py +160 -0
- django_cfg/apps/payments/config/django_cfg_integration.py +202 -0
- django_cfg/apps/payments/config/helpers.py +130 -0
- django_cfg/apps/payments/management/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +419 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +297 -225
- django_cfg/apps/payments/management/commands/manage_currencies.py +303 -151
- django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
- django_cfg/apps/payments/management/commands/process_pending_payments.py +357 -0
- django_cfg/apps/payments/management/commands/test_providers.py +434 -0
- django_cfg/apps/payments/middleware/__init__.py +3 -1
- django_cfg/apps/payments/middleware/api_access.py +329 -222
- django_cfg/apps/payments/middleware/rate_limiting.py +342 -152
- django_cfg/apps/payments/middleware/usage_tracking.py +249 -240
- django_cfg/apps/payments/migrations/0001_initial.py +708 -536
- django_cfg/apps/payments/models/__init__.py +13 -18
- django_cfg/apps/payments/models/api_keys.py +121 -43
- django_cfg/apps/payments/models/balance.py +153 -115
- django_cfg/apps/payments/models/base.py +68 -15
- django_cfg/apps/payments/models/currencies.py +172 -148
- django_cfg/apps/payments/models/managers/__init__.py +44 -0
- django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
- django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
- django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
- django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
- django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
- django_cfg/apps/payments/models/payments.py +235 -285
- django_cfg/apps/payments/models/subscriptions.py +257 -177
- django_cfg/apps/payments/models/tariffs.py +147 -40
- django_cfg/apps/payments/services/__init__.py +209 -56
- django_cfg/apps/payments/services/cache/__init__.py +6 -6
- django_cfg/apps/payments/services/cache_service/__init__.py +143 -0
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +37 -0
- django_cfg/apps/payments/services/{cache/base.py → cache_service/interfaces.py} +3 -1
- django_cfg/apps/payments/services/cache_service/keys.py +49 -0
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +47 -0
- django_cfg/apps/payments/services/cache_service/simple_cache.py +101 -0
- django_cfg/apps/payments/services/core/__init__.py +10 -6
- django_cfg/apps/payments/services/core/balance_service.py +435 -360
- django_cfg/apps/payments/services/core/base.py +166 -0
- django_cfg/apps/payments/services/core/currency_service.py +478 -0
- django_cfg/apps/payments/services/core/payment_service.py +371 -465
- django_cfg/apps/payments/services/core/subscription_service.py +425 -481
- django_cfg/apps/payments/services/core/webhook_service.py +410 -0
- django_cfg/apps/payments/services/integrations/__init__.py +29 -0
- django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
- django_cfg/apps/payments/services/providers/__init__.py +9 -14
- django_cfg/apps/payments/services/providers/base.py +234 -174
- django_cfg/apps/payments/services/providers/nowpayments.py +478 -0
- django_cfg/apps/payments/services/providers/registry.py +367 -301
- django_cfg/apps/payments/services/types/__init__.py +78 -0
- django_cfg/apps/payments/services/types/data.py +177 -0
- django_cfg/apps/payments/services/types/requests.py +150 -0
- django_cfg/apps/payments/services/types/responses.py +156 -0
- django_cfg/apps/payments/services/types/webhooks.py +232 -0
- django_cfg/apps/payments/signals/__init__.py +33 -8
- django_cfg/apps/payments/signals/api_key_signals.py +210 -129
- django_cfg/apps/payments/signals/balance_signals.py +174 -0
- django_cfg/apps/payments/signals/payment_signals.py +128 -103
- django_cfg/apps/payments/signals/subscription_signals.py +194 -142
- django_cfg/apps/payments/static/payments/css/components.css +380 -0
- django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
- django_cfg/apps/payments/static/payments/js/components.js +545 -0
- django_cfg/apps/payments/static/payments/js/utils.js +412 -0
- django_cfg/apps/payments/templatetags/__init__.py +1 -1
- django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
- django_cfg/apps/payments/urls.py +45 -48
- django_cfg/apps/payments/urls_admin.py +33 -42
- django_cfg/apps/payments/views/api/__init__.py +101 -0
- django_cfg/apps/payments/views/api/api_keys.py +387 -0
- django_cfg/apps/payments/views/api/balances.py +381 -0
- django_cfg/apps/payments/views/api/base.py +298 -0
- django_cfg/apps/payments/views/api/currencies.py +402 -0
- django_cfg/apps/payments/views/api/payments.py +415 -0
- django_cfg/apps/payments/views/api/subscriptions.py +475 -0
- django_cfg/apps/payments/views/api/webhooks.py +476 -0
- django_cfg/apps/payments/views/serializers/__init__.py +99 -0
- django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
- django_cfg/apps/payments/views/serializers/balances.py +300 -0
- django_cfg/apps/payments/views/serializers/currencies.py +335 -0
- django_cfg/apps/payments/views/serializers/payments.py +387 -0
- django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
- django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +40 -4
- django_cfg/core/generation.py +25 -4
- django_cfg/core/integration/README.md +363 -0
- django_cfg/core/integration/__init__.py +47 -0
- django_cfg/core/integration/commands_collector.py +239 -0
- django_cfg/core/integration/display/__init__.py +15 -0
- django_cfg/core/integration/display/base.py +157 -0
- django_cfg/core/integration/display/ngrok.py +164 -0
- django_cfg/core/integration/display/startup.py +815 -0
- django_cfg/core/integration/url_integration.py +123 -0
- django_cfg/core/integration/version_checker.py +160 -0
- django_cfg/management/commands/auto_generate.py +4 -0
- django_cfg/management/commands/check_settings.py +6 -0
- django_cfg/management/commands/clear_constance.py +5 -2
- django_cfg/management/commands/create_token.py +6 -0
- django_cfg/management/commands/list_urls.py +6 -0
- django_cfg/management/commands/migrate_all.py +6 -0
- django_cfg/management/commands/migrator.py +3 -0
- django_cfg/management/commands/rundramatiq.py +6 -0
- django_cfg/management/commands/runserver_ngrok.py +51 -29
- django_cfg/management/commands/script.py +6 -0
- django_cfg/management/commands/show_config.py +12 -2
- django_cfg/management/commands/show_urls.py +4 -0
- django_cfg/management/commands/superuser.py +6 -0
- django_cfg/management/commands/task_clear.py +4 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -0
- django_cfg/management/commands/test_telegram.py +6 -0
- django_cfg/management/commands/test_twilio.py +6 -0
- django_cfg/management/commands/tree.py +6 -0
- django_cfg/management/commands/validate_config.py +155 -149
- django_cfg/models/constance.py +31 -11
- django_cfg/models/payments.py +175 -492
- django_cfg/modules/django_logger.py +160 -146
- django_cfg/modules/django_unfold/dashboard.py +64 -16
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/utils/smart_defaults.py +227 -570
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/METADATA +4 -1
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/RECORD +162 -185
- django_cfg/apps/payments/__init__.py +0 -8
- django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
- django_cfg/apps/payments/config/module.py +0 -70
- django_cfg/apps/payments/config/providers.py +0 -105
- django_cfg/apps/payments/config/settings.py +0 -96
- django_cfg/apps/payments/config/utils.py +0 -52
- django_cfg/apps/payments/decorators.py +0 -291
- django_cfg/apps/payments/management/commands/README.md +0 -146
- django_cfg/apps/payments/managers/__init__.py +0 -23
- django_cfg/apps/payments/managers/api_key_manager.py +0 -35
- django_cfg/apps/payments/managers/balance_manager.py +0 -361
- django_cfg/apps/payments/managers/currency_manager.py +0 -306
- django_cfg/apps/payments/managers/payment_manager.py +0 -192
- django_cfg/apps/payments/managers/subscription_manager.py +0 -37
- django_cfg/apps/payments/managers/tariff_manager.py +0 -29
- django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +0 -241
- django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +0 -30
- django_cfg/apps/payments/models/events.py +0 -73
- django_cfg/apps/payments/serializers/__init__.py +0 -57
- django_cfg/apps/payments/serializers/api_keys.py +0 -51
- django_cfg/apps/payments/serializers/balance.py +0 -59
- django_cfg/apps/payments/serializers/currencies.py +0 -63
- django_cfg/apps/payments/serializers/payments.py +0 -62
- django_cfg/apps/payments/serializers/subscriptions.py +0 -71
- django_cfg/apps/payments/serializers/tariffs.py +0 -56
- django_cfg/apps/payments/services/billing/__init__.py +0 -8
- django_cfg/apps/payments/services/cache/simple_cache.py +0 -135
- django_cfg/apps/payments/services/core/fallback_service.py +0 -432
- django_cfg/apps/payments/services/internal_types.py +0 -461
- django_cfg/apps/payments/services/middleware/__init__.py +0 -8
- django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
- django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -76
- django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
- django_cfg/apps/payments/services/providers/cryptapi/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/cryptapi/config.py +0 -8
- django_cfg/apps/payments/services/providers/cryptapi/models.py +0 -192
- django_cfg/apps/payments/services/providers/cryptapi/provider.py +0 -439
- django_cfg/apps/payments/services/providers/cryptomus/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/cryptomus/models.py +0 -176
- django_cfg/apps/payments/services/providers/cryptomus/provider.py +0 -429
- django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +0 -564
- django_cfg/apps/payments/services/providers/models/__init__.py +0 -34
- django_cfg/apps/payments/services/providers/models/currencies.py +0 -190
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/nowpayments/models.py +0 -196
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +0 -380
- django_cfg/apps/payments/services/providers/stripe/__init__.py +0 -4
- django_cfg/apps/payments/services/providers/stripe/models.py +0 -184
- django_cfg/apps/payments/services/providers/stripe/provider.py +0 -109
- django_cfg/apps/payments/services/security/__init__.py +0 -34
- django_cfg/apps/payments/services/security/error_handler.py +0 -635
- django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
- django_cfg/apps/payments/services/security/webhook_validator.py +0 -474
- django_cfg/apps/payments/static/payments/css/payments.css +0 -340
- django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
- django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
- django_cfg/apps/payments/static/payments/js/theme.js +0 -86
- django_cfg/apps/payments/tasks/__init__.py +0 -12
- django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +0 -50
- django_cfg/apps/payments/templates/payments/base.html +0 -182
- django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -43
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
- django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -34
- django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -148
- django_cfg/apps/payments/templates/payments/dashboard.html +0 -258
- django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +0 -35
- django_cfg/apps/payments/templates/payments/payment_create.html +0 -579
- django_cfg/apps/payments/templates/payments/payment_detail.html +0 -373
- django_cfg/apps/payments/templates/payments/payment_list.html +0 -354
- django_cfg/apps/payments/templates/payments/stats.html +0 -261
- django_cfg/apps/payments/templates/payments/test.html +0 -213
- django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
- django_cfg/apps/payments/utils/__init__.py +0 -43
- django_cfg/apps/payments/utils/billing_utils.py +0 -342
- django_cfg/apps/payments/utils/config_utils.py +0 -239
- django_cfg/apps/payments/utils/middleware_utils.py +0 -228
- django_cfg/apps/payments/utils/validation_utils.py +0 -94
- django_cfg/apps/payments/views/__init__.py +0 -63
- django_cfg/apps/payments/views/api_key_views.py +0 -164
- django_cfg/apps/payments/views/balance_views.py +0 -75
- django_cfg/apps/payments/views/currency_views.py +0 -122
- django_cfg/apps/payments/views/payment_views.py +0 -149
- django_cfg/apps/payments/views/subscription_views.py +0 -135
- django_cfg/apps/payments/views/tariff_views.py +0 -131
- django_cfg/apps/payments/views/templates/__init__.py +0 -25
- django_cfg/apps/payments/views/templates/ajax.py +0 -451
- django_cfg/apps/payments/views/templates/base.py +0 -212
- django_cfg/apps/payments/views/templates/dashboard.py +0 -60
- django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
- django_cfg/apps/payments/views/templates/payment_management.py +0 -158
- django_cfg/apps/payments/views/templates/qr_code.py +0 -174
- django_cfg/apps/payments/views/templates/stats.py +0 -244
- django_cfg/apps/payments/views/templates/utils.py +0 -181
- django_cfg/apps/payments/views/webhook_views.py +0 -266
- django_cfg/apps/payments/viewsets.py +0 -66
- django_cfg/core/integration.py +0 -160
- django_cfg/template_archive/.gitignore +0 -1
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/urls.py +0 -33
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,434 @@
|
|
1
|
+
"""
|
2
|
+
Test Providers Management Command for Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Test payment provider connections, configurations, and functionality.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import List, Dict, Any, Optional
|
8
|
+
from decimal import Decimal
|
9
|
+
import time
|
10
|
+
|
11
|
+
from django.core.management.base import BaseCommand, CommandError
|
12
|
+
from django.utils import timezone
|
13
|
+
|
14
|
+
from django_cfg.modules.django_logger import get_logger
|
15
|
+
from django_cfg.apps.payments.services.providers.registry import get_provider_registry
|
16
|
+
from django_cfg.apps.payments.models import Currency, Network
|
17
|
+
from django_cfg.apps.payments.services.types.requests import PaymentCreateRequest
|
18
|
+
|
19
|
+
logger = get_logger("test_providers")
|
20
|
+
|
21
|
+
|
22
|
+
class Command(BaseCommand):
|
23
|
+
"""
|
24
|
+
Test payment provider connections and functionality.
|
25
|
+
|
26
|
+
Features:
|
27
|
+
- Test provider connectivity
|
28
|
+
- Validate configurations
|
29
|
+
- Test currency support
|
30
|
+
- Check API responses
|
31
|
+
- Performance testing
|
32
|
+
"""
|
33
|
+
|
34
|
+
help = 'Test payment provider connections and functionality'
|
35
|
+
|
36
|
+
def add_arguments(self, parser):
|
37
|
+
"""Add command line arguments."""
|
38
|
+
parser.add_argument(
|
39
|
+
'--provider',
|
40
|
+
type=str,
|
41
|
+
help='Test specific provider only'
|
42
|
+
)
|
43
|
+
|
44
|
+
parser.add_argument(
|
45
|
+
'--test-type',
|
46
|
+
choices=['connectivity', 'currencies', 'payment', 'all'],
|
47
|
+
default='all',
|
48
|
+
help='Type of test to run (default: all)'
|
49
|
+
)
|
50
|
+
|
51
|
+
parser.add_argument(
|
52
|
+
'--timeout',
|
53
|
+
type=int,
|
54
|
+
default=30,
|
55
|
+
help='Request timeout in seconds (default: 30)'
|
56
|
+
)
|
57
|
+
|
58
|
+
parser.add_argument(
|
59
|
+
'--verbose',
|
60
|
+
action='store_true',
|
61
|
+
help='Show detailed test information'
|
62
|
+
)
|
63
|
+
|
64
|
+
parser.add_argument(
|
65
|
+
'--create-test-payment',
|
66
|
+
action='store_true',
|
67
|
+
help='Create actual test payment (use with caution!)'
|
68
|
+
)
|
69
|
+
|
70
|
+
parser.add_argument(
|
71
|
+
'--test-amount',
|
72
|
+
type=float,
|
73
|
+
default=1.0,
|
74
|
+
help='Test payment amount in USD (default: 1.0)'
|
75
|
+
)
|
76
|
+
|
77
|
+
def handle(self, *args, **options):
|
78
|
+
"""Execute the command."""
|
79
|
+
try:
|
80
|
+
self.options = options
|
81
|
+
self.verbose = options['verbose']
|
82
|
+
|
83
|
+
self.show_header()
|
84
|
+
|
85
|
+
# Get provider registry
|
86
|
+
self.provider_registry = get_provider_registry()
|
87
|
+
|
88
|
+
# Initialize test results
|
89
|
+
self.test_results = {}
|
90
|
+
|
91
|
+
# Get providers to test
|
92
|
+
if options['provider']:
|
93
|
+
providers = [options['provider']]
|
94
|
+
else:
|
95
|
+
providers = self.provider_registry.get_available_providers()
|
96
|
+
|
97
|
+
if not providers:
|
98
|
+
self.stdout.write(self.style.WARNING("No providers available to test"))
|
99
|
+
return
|
100
|
+
|
101
|
+
# Run tests
|
102
|
+
for provider_name in providers:
|
103
|
+
self.test_provider(provider_name)
|
104
|
+
|
105
|
+
self.show_summary()
|
106
|
+
|
107
|
+
except Exception as e:
|
108
|
+
logger.error(f"Test providers command failed: {e}")
|
109
|
+
raise CommandError(f"Failed to test providers: {e}")
|
110
|
+
|
111
|
+
def show_header(self):
|
112
|
+
"""Display command header."""
|
113
|
+
self.stdout.write(
|
114
|
+
self.style.SUCCESS("=" * 60)
|
115
|
+
)
|
116
|
+
self.stdout.write(
|
117
|
+
self.style.SUCCESS("🧪 PAYMENT PROVIDER TESTING")
|
118
|
+
)
|
119
|
+
self.stdout.write(
|
120
|
+
self.style.SUCCESS("=" * 60)
|
121
|
+
)
|
122
|
+
self.stdout.write(f"Started: {timezone.now().strftime('%Y-%m-%d %H:%M:%S UTC')}")
|
123
|
+
self.stdout.write("")
|
124
|
+
|
125
|
+
def test_provider(self, provider_name: str):
|
126
|
+
"""Test a specific provider."""
|
127
|
+
self.stdout.write(self.style.SUCCESS(f"🔍 TESTING PROVIDER: {provider_name.upper()}"))
|
128
|
+
self.stdout.write("-" * 50)
|
129
|
+
|
130
|
+
# Initialize provider results
|
131
|
+
self.test_results[provider_name] = {
|
132
|
+
'connectivity': False,
|
133
|
+
'currencies': False,
|
134
|
+
'payment': False,
|
135
|
+
'errors': [],
|
136
|
+
'warnings': [],
|
137
|
+
'performance': {}
|
138
|
+
}
|
139
|
+
|
140
|
+
try:
|
141
|
+
# Get provider instance
|
142
|
+
provider = self.provider_registry.get_provider(provider_name)
|
143
|
+
if not provider:
|
144
|
+
self.test_results[provider_name]['errors'].append("Provider not available")
|
145
|
+
self.stdout.write(self.style.ERROR(f"❌ Provider {provider_name} not available"))
|
146
|
+
return
|
147
|
+
|
148
|
+
# Run selected tests
|
149
|
+
test_type = self.options['test_type']
|
150
|
+
|
151
|
+
if test_type in ['connectivity', 'all']:
|
152
|
+
self.test_connectivity(provider_name, provider)
|
153
|
+
|
154
|
+
if test_type in ['currencies', 'all']:
|
155
|
+
self.test_currencies(provider_name, provider)
|
156
|
+
|
157
|
+
if test_type in ['payment', 'all'] and self.options['create_test_payment']:
|
158
|
+
self.test_payment_creation(provider_name, provider)
|
159
|
+
|
160
|
+
except Exception as e:
|
161
|
+
error_msg = f"Provider test failed: {e}"
|
162
|
+
self.test_results[provider_name]['errors'].append(error_msg)
|
163
|
+
logger.error(f"Error testing provider {provider_name}: {e}")
|
164
|
+
self.stdout.write(self.style.ERROR(f"❌ {error_msg}"))
|
165
|
+
|
166
|
+
self.stdout.write("")
|
167
|
+
|
168
|
+
def test_connectivity(self, provider_name: str, provider):
|
169
|
+
"""Test provider connectivity."""
|
170
|
+
self.stdout.write(" 🌐 Testing connectivity...")
|
171
|
+
|
172
|
+
try:
|
173
|
+
start_time = time.time()
|
174
|
+
|
175
|
+
# Test basic connectivity (health check or similar)
|
176
|
+
if hasattr(provider, 'health_check'):
|
177
|
+
result = provider.health_check()
|
178
|
+
success = result.success if hasattr(result, 'success') else True
|
179
|
+
elif hasattr(provider, 'get_supported_currencies'):
|
180
|
+
# Fallback: try to get currencies as connectivity test
|
181
|
+
result = provider.get_supported_currencies()
|
182
|
+
success = len(result) > 0 if isinstance(result, list) else bool(result)
|
183
|
+
else:
|
184
|
+
# Last resort: assume connectivity is OK if provider exists
|
185
|
+
success = True
|
186
|
+
|
187
|
+
end_time = time.time()
|
188
|
+
response_time = (end_time - start_time) * 1000 # Convert to milliseconds
|
189
|
+
|
190
|
+
self.test_results[provider_name]['performance']['connectivity_ms'] = response_time
|
191
|
+
|
192
|
+
if success:
|
193
|
+
self.test_results[provider_name]['connectivity'] = True
|
194
|
+
self.stdout.write(f" ✅ Connectivity OK ({response_time:.0f}ms)")
|
195
|
+
else:
|
196
|
+
self.test_results[provider_name]['errors'].append("Connectivity test failed")
|
197
|
+
self.stdout.write(f" ❌ Connectivity failed")
|
198
|
+
|
199
|
+
except Exception as e:
|
200
|
+
error_msg = f"Connectivity test error: {e}"
|
201
|
+
self.test_results[provider_name]['errors'].append(error_msg)
|
202
|
+
self.stdout.write(f" ❌ Connectivity error: {e}")
|
203
|
+
|
204
|
+
def test_currencies(self, provider_name: str, provider):
|
205
|
+
"""Test provider currency support."""
|
206
|
+
self.stdout.write(" 💰 Testing currency support...")
|
207
|
+
|
208
|
+
try:
|
209
|
+
start_time = time.time()
|
210
|
+
|
211
|
+
# Get supported currencies from provider
|
212
|
+
if hasattr(provider, 'get_supported_currencies'):
|
213
|
+
supported_currencies = provider.get_supported_currencies()
|
214
|
+
else:
|
215
|
+
self.test_results[provider_name]['warnings'].append("Provider doesn't support currency listing")
|
216
|
+
self.stdout.write(" ⚠️ Provider doesn't support currency listing")
|
217
|
+
return
|
218
|
+
|
219
|
+
end_time = time.time()
|
220
|
+
response_time = (end_time - start_time) * 1000
|
221
|
+
|
222
|
+
self.test_results[provider_name]['performance']['currencies_ms'] = response_time
|
223
|
+
|
224
|
+
if isinstance(supported_currencies, list) and len(supported_currencies) > 0:
|
225
|
+
self.test_results[provider_name]['currencies'] = True
|
226
|
+
currency_count = len(supported_currencies)
|
227
|
+
self.stdout.write(f" ✅ {currency_count} currencies supported ({response_time:.0f}ms)")
|
228
|
+
|
229
|
+
if self.verbose:
|
230
|
+
# Show first few currencies
|
231
|
+
sample_currencies = supported_currencies[:5]
|
232
|
+
currency_codes = [c.get('code', str(c)) for c in sample_currencies]
|
233
|
+
self.stdout.write(f" Sample: {', '.join(currency_codes)}")
|
234
|
+
|
235
|
+
# Check if our database currencies are supported
|
236
|
+
our_currencies = Currency.objects.filter(is_active=True)[:10]
|
237
|
+
supported_codes = []
|
238
|
+
|
239
|
+
if isinstance(supported_currencies[0], dict):
|
240
|
+
supported_codes = [c.get('code', '').upper() for c in supported_currencies]
|
241
|
+
else:
|
242
|
+
supported_codes = [str(c).upper() for c in supported_currencies]
|
243
|
+
|
244
|
+
matching_count = 0
|
245
|
+
for currency in our_currencies:
|
246
|
+
if currency.code.upper() in supported_codes:
|
247
|
+
matching_count += 1
|
248
|
+
|
249
|
+
if matching_count > 0:
|
250
|
+
self.stdout.write(f" ✅ {matching_count}/{our_currencies.count()} of our currencies supported")
|
251
|
+
else:
|
252
|
+
self.test_results[provider_name]['warnings'].append("No matching currencies found")
|
253
|
+
self.stdout.write(" ⚠️ No matching currencies found")
|
254
|
+
|
255
|
+
else:
|
256
|
+
self.test_results[provider_name]['errors'].append("No currencies returned")
|
257
|
+
self.stdout.write(" ❌ No currencies returned")
|
258
|
+
|
259
|
+
except Exception as e:
|
260
|
+
error_msg = f"Currency test error: {e}"
|
261
|
+
self.test_results[provider_name]['errors'].append(error_msg)
|
262
|
+
self.stdout.write(f" ❌ Currency test error: {e}")
|
263
|
+
|
264
|
+
def test_payment_creation(self, provider_name: str, provider):
|
265
|
+
"""Test payment creation (creates actual test payment!)."""
|
266
|
+
self.stdout.write(" 💳 Testing payment creation...")
|
267
|
+
self.stdout.write(" ⚠️ WARNING: This creates an actual payment!")
|
268
|
+
|
269
|
+
try:
|
270
|
+
# Get a supported currency for testing
|
271
|
+
test_currency = self.get_test_currency(provider)
|
272
|
+
if not test_currency:
|
273
|
+
self.test_results[provider_name]['warnings'].append("No suitable test currency found")
|
274
|
+
self.stdout.write(" ⚠️ No suitable test currency found")
|
275
|
+
return
|
276
|
+
|
277
|
+
# Create test payment request
|
278
|
+
payment_request = PaymentCreateRequest(
|
279
|
+
amount_usd=self.options['test_amount'],
|
280
|
+
currency_code=test_currency,
|
281
|
+
description=f"Test payment from django-cfg ({timezone.now().isoformat()})",
|
282
|
+
callback_url="https://example.com/webhook/test",
|
283
|
+
success_url="https://example.com/success",
|
284
|
+
cancel_url="https://example.com/cancel"
|
285
|
+
)
|
286
|
+
|
287
|
+
start_time = time.time()
|
288
|
+
|
289
|
+
# Create payment
|
290
|
+
result = provider.create_payment(payment_request)
|
291
|
+
|
292
|
+
end_time = time.time()
|
293
|
+
response_time = (end_time - start_time) * 1000
|
294
|
+
|
295
|
+
self.test_results[provider_name]['performance']['payment_creation_ms'] = response_time
|
296
|
+
|
297
|
+
if hasattr(result, 'success') and result.success:
|
298
|
+
self.test_results[provider_name]['payment'] = True
|
299
|
+
payment_id = getattr(result, 'provider_payment_id', 'Unknown')
|
300
|
+
payment_url = getattr(result, 'payment_url', 'No URL')
|
301
|
+
|
302
|
+
self.stdout.write(f" ✅ Payment created ({response_time:.0f}ms)")
|
303
|
+
self.stdout.write(f" Payment ID: {payment_id}")
|
304
|
+
|
305
|
+
if self.verbose and payment_url != 'No URL':
|
306
|
+
self.stdout.write(f" Payment URL: {payment_url}")
|
307
|
+
|
308
|
+
# Test payment status check
|
309
|
+
if hasattr(provider, 'get_payment_status') and payment_id != 'Unknown':
|
310
|
+
try:
|
311
|
+
status_result = provider.get_payment_status(payment_id)
|
312
|
+
if hasattr(status_result, 'success') and status_result.success:
|
313
|
+
status = getattr(status_result, 'status', 'Unknown')
|
314
|
+
self.stdout.write(f" ✅ Status check OK: {status}")
|
315
|
+
else:
|
316
|
+
self.test_results[provider_name]['warnings'].append("Status check failed")
|
317
|
+
self.stdout.write(" ⚠️ Status check failed")
|
318
|
+
except Exception as e:
|
319
|
+
self.test_results[provider_name]['warnings'].append(f"Status check error: {e}")
|
320
|
+
self.stdout.write(f" ⚠️ Status check error: {e}")
|
321
|
+
|
322
|
+
else:
|
323
|
+
error = getattr(result, 'error', 'Unknown error')
|
324
|
+
self.test_results[provider_name]['errors'].append(f"Payment creation failed: {error}")
|
325
|
+
self.stdout.write(f" ❌ Payment creation failed: {error}")
|
326
|
+
|
327
|
+
except Exception as e:
|
328
|
+
error_msg = f"Payment creation error: {e}"
|
329
|
+
self.test_results[provider_name]['errors'].append(error_msg)
|
330
|
+
self.stdout.write(f" ❌ Payment creation error: {e}")
|
331
|
+
|
332
|
+
def get_test_currency(self, provider) -> Optional[str]:
|
333
|
+
"""Get a suitable currency for testing."""
|
334
|
+
# Common test currencies
|
335
|
+
test_currencies = ['BTC', 'ETH', 'USDT', 'LTC', 'USD']
|
336
|
+
|
337
|
+
try:
|
338
|
+
# Get supported currencies from provider
|
339
|
+
if hasattr(provider, 'get_supported_currencies'):
|
340
|
+
supported = provider.get_supported_currencies()
|
341
|
+
|
342
|
+
if isinstance(supported, list) and len(supported) > 0:
|
343
|
+
# Extract currency codes
|
344
|
+
if isinstance(supported[0], dict):
|
345
|
+
supported_codes = [c.get('code', '').upper() for c in supported]
|
346
|
+
else:
|
347
|
+
supported_codes = [str(c).upper() for c in supported]
|
348
|
+
|
349
|
+
# Find first matching test currency
|
350
|
+
for currency in test_currencies:
|
351
|
+
if currency in supported_codes:
|
352
|
+
return currency
|
353
|
+
|
354
|
+
# Fallback: return first supported currency
|
355
|
+
if supported_codes:
|
356
|
+
return supported_codes[0]
|
357
|
+
|
358
|
+
# Last resort: try BTC
|
359
|
+
return 'BTC'
|
360
|
+
|
361
|
+
except Exception:
|
362
|
+
return 'BTC'
|
363
|
+
|
364
|
+
def show_summary(self):
|
365
|
+
"""Display test summary."""
|
366
|
+
self.stdout.write(self.style.SUCCESS("📊 TEST SUMMARY"))
|
367
|
+
self.stdout.write("-" * 40)
|
368
|
+
|
369
|
+
total_providers = len(self.test_results)
|
370
|
+
successful_providers = 0
|
371
|
+
total_errors = 0
|
372
|
+
total_warnings = 0
|
373
|
+
|
374
|
+
for provider_name, results in self.test_results.items():
|
375
|
+
errors = len(results['errors'])
|
376
|
+
warnings = len(results['warnings'])
|
377
|
+
|
378
|
+
total_errors += errors
|
379
|
+
total_warnings += warnings
|
380
|
+
|
381
|
+
# Count as successful if no errors and at least one test passed
|
382
|
+
if errors == 0 and (results['connectivity'] or results['currencies']):
|
383
|
+
successful_providers += 1
|
384
|
+
|
385
|
+
# Show provider summary
|
386
|
+
status_icon = "✅" if errors == 0 else "❌"
|
387
|
+
self.stdout.write(f"{status_icon} {provider_name}:")
|
388
|
+
|
389
|
+
if results['connectivity']:
|
390
|
+
self.stdout.write(" ✅ Connectivity")
|
391
|
+
if results['currencies']:
|
392
|
+
self.stdout.write(" ✅ Currencies")
|
393
|
+
if results['payment']:
|
394
|
+
self.stdout.write(" ✅ Payment Creation")
|
395
|
+
|
396
|
+
if errors > 0:
|
397
|
+
self.stdout.write(f" ❌ {errors} error(s)")
|
398
|
+
if warnings > 0:
|
399
|
+
self.stdout.write(f" ⚠️ {warnings} warning(s)")
|
400
|
+
|
401
|
+
# Show performance metrics
|
402
|
+
if self.verbose and results['performance']:
|
403
|
+
perf = results['performance']
|
404
|
+
if 'connectivity_ms' in perf:
|
405
|
+
self.stdout.write(f" ⏱️ Connectivity: {perf['connectivity_ms']:.0f}ms")
|
406
|
+
if 'currencies_ms' in perf:
|
407
|
+
self.stdout.write(f" ⏱️ Currencies: {perf['currencies_ms']:.0f}ms")
|
408
|
+
if 'payment_creation_ms' in perf:
|
409
|
+
self.stdout.write(f" ⏱️ Payment: {perf['payment_creation_ms']:.0f}ms")
|
410
|
+
|
411
|
+
# Overall summary
|
412
|
+
self.stdout.write("")
|
413
|
+
self.stdout.write(f"Providers tested: {total_providers}")
|
414
|
+
self.stdout.write(f"Successful: {self.style.SUCCESS(successful_providers)}")
|
415
|
+
self.stdout.write(f"Failed: {self.style.ERROR(total_providers - successful_providers)}")
|
416
|
+
self.stdout.write(f"Total errors: {self.style.ERROR(total_errors)}")
|
417
|
+
self.stdout.write(f"Total warnings: {self.style.WARNING(total_warnings)}")
|
418
|
+
|
419
|
+
# Show completion time
|
420
|
+
self.stdout.write("")
|
421
|
+
self.stdout.write(f"Completed: {timezone.now().strftime('%Y-%m-%d %H:%M:%S UTC')}")
|
422
|
+
|
423
|
+
# Recommendations
|
424
|
+
if total_errors > 0:
|
425
|
+
self.stdout.write("")
|
426
|
+
self.stdout.write(
|
427
|
+
self.style.WARNING("⚠️ Some providers have errors. Check configurations and network connectivity.")
|
428
|
+
)
|
429
|
+
|
430
|
+
if successful_providers == total_providers and total_errors == 0:
|
431
|
+
self.stdout.write("")
|
432
|
+
self.stdout.write(
|
433
|
+
self.style.SUCCESS("🎉 All providers tested successfully!")
|
434
|
+
)
|