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.
- 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/manage_currencies.py +303 -151
- django_cfg/apps/payments/management/commands/manage_providers.py +333 -160
- 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 +150 -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/{simple_cache.py → cache_service.py} +112 -12
- 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 +346 -467
- 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 +222 -571
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/METADATA +4 -1
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/RECORD +153 -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/management/commands/currency_stats.py +0 -304
- 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/base.py +0 -30
- 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.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.31.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,60 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Main payment dashboard view.
|
3
|
-
|
4
|
-
Provides overview, statistics, and recent payments for superuser access.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from django.views.generic import TemplateView
|
8
|
-
from .base import (
|
9
|
-
SuperuserRequiredMixin,
|
10
|
-
PaymentFilterMixin,
|
11
|
-
PaymentStatsMixin,
|
12
|
-
PaymentContextMixin,
|
13
|
-
log_view_access
|
14
|
-
)
|
15
|
-
|
16
|
-
|
17
|
-
class PaymentDashboardView(
|
18
|
-
SuperuserRequiredMixin,
|
19
|
-
PaymentFilterMixin,
|
20
|
-
PaymentStatsMixin,
|
21
|
-
PaymentContextMixin,
|
22
|
-
TemplateView
|
23
|
-
):
|
24
|
-
"""Main payment dashboard with overview and recent payments."""
|
25
|
-
|
26
|
-
template_name = 'payments/dashboard.html'
|
27
|
-
page_title = 'Payment Dashboard'
|
28
|
-
|
29
|
-
def get_context_data(self, **kwargs):
|
30
|
-
context = super().get_context_data(**kwargs)
|
31
|
-
|
32
|
-
# Log access for audit
|
33
|
-
log_view_access('dashboard', self.request.user)
|
34
|
-
|
35
|
-
# Get filtered payments
|
36
|
-
payments_qs = self.get_filtered_payments()
|
37
|
-
|
38
|
-
# Get recent payments (limit to 20 for performance)
|
39
|
-
recent_payments = payments_qs.order_by('-created_at')[:20]
|
40
|
-
|
41
|
-
# Check if there are more payments for pagination
|
42
|
-
has_more = payments_qs.count() > 20
|
43
|
-
|
44
|
-
# Get statistics
|
45
|
-
payment_stats = self.get_payment_stats()
|
46
|
-
provider_stats = self.get_provider_stats()
|
47
|
-
|
48
|
-
# Get common context
|
49
|
-
common_context = self.get_common_context()
|
50
|
-
|
51
|
-
context.update({
|
52
|
-
'payments': recent_payments,
|
53
|
-
'has_more_payments': has_more,
|
54
|
-
'payment_stats': payment_stats,
|
55
|
-
'provider_stats': provider_stats,
|
56
|
-
'filters': self.get_filter_context(),
|
57
|
-
**common_context
|
58
|
-
})
|
59
|
-
|
60
|
-
return context
|
@@ -1,102 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Payment detail view.
|
3
|
-
|
4
|
-
Provides detailed information about a single payment for superuser access.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from django.views.generic import DetailView
|
8
|
-
from .base import (
|
9
|
-
SuperuserRequiredMixin,
|
10
|
-
PaymentContextMixin,
|
11
|
-
log_view_access
|
12
|
-
)
|
13
|
-
from ...models import UniversalPayment, PaymentEvent
|
14
|
-
|
15
|
-
|
16
|
-
class PaymentDetailView(
|
17
|
-
SuperuserRequiredMixin,
|
18
|
-
PaymentContextMixin,
|
19
|
-
DetailView
|
20
|
-
):
|
21
|
-
"""Detailed view for a single payment."""
|
22
|
-
|
23
|
-
model = UniversalPayment
|
24
|
-
template_name = 'payments/payment_detail.html'
|
25
|
-
context_object_name = 'payment'
|
26
|
-
page_title = 'Payment Details'
|
27
|
-
|
28
|
-
def get_breadcrumbs(self):
|
29
|
-
payment = self.get_object()
|
30
|
-
return [
|
31
|
-
{'name': 'Dashboard', 'url': '/payments/admin/'},
|
32
|
-
{'name': 'Payments', 'url': '/payments/admin/list/'},
|
33
|
-
{'name': f'Payment #{payment.internal_payment_id or str(payment.id)[:8]}', 'url': ''},
|
34
|
-
]
|
35
|
-
|
36
|
-
def get_context_data(self, **kwargs):
|
37
|
-
context = super().get_context_data(**kwargs)
|
38
|
-
payment = self.get_object()
|
39
|
-
|
40
|
-
# Log access for audit
|
41
|
-
log_view_access('payment_detail', self.request.user, payment_id=payment.id)
|
42
|
-
|
43
|
-
# Get payment events for this payment
|
44
|
-
events = PaymentEvent.objects.filter(payment_id=payment.id).order_by('-created_at')
|
45
|
-
|
46
|
-
# Get related payments (same user, similar amount range)
|
47
|
-
related_payments = UniversalPayment.objects.filter(
|
48
|
-
user=payment.user,
|
49
|
-
amount_usd__gte=payment.amount_usd * 0.8,
|
50
|
-
amount_usd__lte=payment.amount_usd * 1.2
|
51
|
-
).exclude(id=payment.id).order_by('-created_at')[:5]
|
52
|
-
|
53
|
-
# Get provider-specific information
|
54
|
-
provider_info = self._get_provider_info(payment)
|
55
|
-
|
56
|
-
# Get common context
|
57
|
-
common_context = self.get_common_context()
|
58
|
-
|
59
|
-
context.update({
|
60
|
-
'events': events,
|
61
|
-
'related_payments': related_payments,
|
62
|
-
'provider_info': provider_info,
|
63
|
-
'can_retry': self._can_retry_payment(payment),
|
64
|
-
'can_cancel': self._can_cancel_payment(payment),
|
65
|
-
'can_refund': self._can_refund_payment(payment),
|
66
|
-
**common_context
|
67
|
-
})
|
68
|
-
|
69
|
-
return context
|
70
|
-
|
71
|
-
def _get_provider_info(self, payment):
|
72
|
-
"""Get provider-specific information for the payment."""
|
73
|
-
info = {
|
74
|
-
'display_name': payment.provider.title(),
|
75
|
-
'is_crypto': payment.provider in ['nowpayments', 'cryptapi', 'cryptomus'],
|
76
|
-
'supports_qr': payment.provider in ['nowpayments', 'cryptapi', 'cryptomus'],
|
77
|
-
'supports_webhook': True,
|
78
|
-
}
|
79
|
-
|
80
|
-
# Add crypto-specific info
|
81
|
-
if info['is_crypto'] and payment.pay_address:
|
82
|
-
info.update({
|
83
|
-
'crypto_address': payment.pay_address,
|
84
|
-
'crypto_amount': payment.pay_amount,
|
85
|
-
'crypto_currency': payment.currency_code,
|
86
|
-
'network': getattr(payment, 'network', 'mainnet'),
|
87
|
-
'confirmations': getattr(payment, 'confirmations_count', 0),
|
88
|
-
})
|
89
|
-
|
90
|
-
return info
|
91
|
-
|
92
|
-
def _can_retry_payment(self, payment):
|
93
|
-
"""Check if payment can be retried."""
|
94
|
-
return payment.status in ['failed', 'expired']
|
95
|
-
|
96
|
-
def _can_cancel_payment(self, payment):
|
97
|
-
"""Check if payment can be cancelled."""
|
98
|
-
return payment.status in ['pending', 'confirming']
|
99
|
-
|
100
|
-
def _can_refund_payment(self, payment):
|
101
|
-
"""Check if payment can be refunded."""
|
102
|
-
return payment.status == 'completed'
|
@@ -1,158 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Payment management views.
|
3
|
-
|
4
|
-
Provides list, create, and management functionality for payments.
|
5
|
-
"""
|
6
|
-
|
7
|
-
import json
|
8
|
-
from django.views.generic import TemplateView, ListView
|
9
|
-
from .base import (
|
10
|
-
SuperuserRequiredMixin,
|
11
|
-
PaymentFilterMixin,
|
12
|
-
PaymentContextMixin,
|
13
|
-
log_view_access
|
14
|
-
)
|
15
|
-
from ...models import UniversalPayment, Currency, PaymentProvider
|
16
|
-
from ...services.providers.registry import ProviderRegistry
|
17
|
-
|
18
|
-
|
19
|
-
class PaymentCreateView(
|
20
|
-
SuperuserRequiredMixin,
|
21
|
-
PaymentContextMixin,
|
22
|
-
TemplateView
|
23
|
-
):
|
24
|
-
"""Form view for creating a new payment."""
|
25
|
-
|
26
|
-
template_name = 'payments/payment_create.html'
|
27
|
-
page_title = 'Create Payment'
|
28
|
-
|
29
|
-
def get_breadcrumbs(self):
|
30
|
-
return [
|
31
|
-
{'name': 'Dashboard', 'url': '/payments/admin/'},
|
32
|
-
{'name': 'Payments', 'url': '/payments/admin/list/'},
|
33
|
-
{'name': 'Create Payment', 'url': ''},
|
34
|
-
]
|
35
|
-
|
36
|
-
def get_context_data(self, **kwargs):
|
37
|
-
context = super().get_context_data(**kwargs)
|
38
|
-
|
39
|
-
# Log access for audit
|
40
|
-
log_view_access('payment_create', self.request.user)
|
41
|
-
|
42
|
-
# Get available providers
|
43
|
-
providers = self._get_available_providers()
|
44
|
-
|
45
|
-
# Get available currencies
|
46
|
-
currencies = self._get_available_currencies()
|
47
|
-
|
48
|
-
# Get common context
|
49
|
-
common_context = self.get_common_context()
|
50
|
-
|
51
|
-
# Provider enum with defaults (serialize to JSON for JavaScript)
|
52
|
-
provider_defaults = {
|
53
|
-
PaymentProvider.NOWPAYMENTS.value: 'USDTTRC20',
|
54
|
-
PaymentProvider.CRYPTAPI.value: 'BTC',
|
55
|
-
PaymentProvider.CRYPTOMUS.value: 'USDTTRC20',
|
56
|
-
PaymentProvider.STRIPE.value: 'USD'
|
57
|
-
}
|
58
|
-
provider_defaults_json = json.dumps(provider_defaults)
|
59
|
-
|
60
|
-
context.update({
|
61
|
-
'providers': providers,
|
62
|
-
'currencies': currencies,
|
63
|
-
'provider_enum': PaymentProvider,
|
64
|
-
'provider_defaults_json': provider_defaults_json,
|
65
|
-
'default_amount': 10.0, # Default test amount
|
66
|
-
**common_context
|
67
|
-
})
|
68
|
-
|
69
|
-
return context
|
70
|
-
|
71
|
-
def _get_available_providers(self):
|
72
|
-
"""Get list of available payment providers from registry."""
|
73
|
-
registry = ProviderRegistry()
|
74
|
-
provider_names = registry.list_providers()
|
75
|
-
|
76
|
-
providers = []
|
77
|
-
for provider_name in provider_names:
|
78
|
-
provider_instance = registry.get_provider(provider_name)
|
79
|
-
providers.append({
|
80
|
-
'name': provider_name,
|
81
|
-
'display_name': provider_name.title(),
|
82
|
-
'is_crypto': provider_name in ['nowpayments', 'cryptapi', 'cryptomus'],
|
83
|
-
'description': getattr(provider_instance.__class__, '__doc__', '') if provider_instance else '',
|
84
|
-
})
|
85
|
-
return providers
|
86
|
-
|
87
|
-
def _get_available_currencies(self):
|
88
|
-
"""Get list of available currencies from database."""
|
89
|
-
# Get all active currencies - both fiat and crypto
|
90
|
-
return Currency.objects.all().order_by('currency_type', 'code')
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
class PaymentListView(
|
96
|
-
SuperuserRequiredMixin,
|
97
|
-
PaymentFilterMixin,
|
98
|
-
PaymentContextMixin,
|
99
|
-
ListView
|
100
|
-
):
|
101
|
-
"""Paginated list view for all payments."""
|
102
|
-
|
103
|
-
model = UniversalPayment
|
104
|
-
template_name = 'payments/payment_list.html'
|
105
|
-
context_object_name = 'payments'
|
106
|
-
paginate_by = 20
|
107
|
-
ordering = ['-created_at']
|
108
|
-
page_title = 'All Payments'
|
109
|
-
|
110
|
-
def get_breadcrumbs(self):
|
111
|
-
return [
|
112
|
-
{'name': 'Dashboard', 'url': '/payments/admin/'},
|
113
|
-
{'name': 'All Payments', 'url': ''},
|
114
|
-
]
|
115
|
-
|
116
|
-
def get_queryset(self):
|
117
|
-
# Log access for audit
|
118
|
-
log_view_access('payment_list', self.request.user)
|
119
|
-
|
120
|
-
# Use filter mixin to get filtered queryset
|
121
|
-
return self.get_filtered_payments().order_by(*self.ordering)
|
122
|
-
|
123
|
-
def get_context_data(self, **kwargs):
|
124
|
-
context = super().get_context_data(**kwargs)
|
125
|
-
|
126
|
-
# Get filter context
|
127
|
-
filter_context = self.get_filter_context()
|
128
|
-
|
129
|
-
# Get available filter options
|
130
|
-
filter_options = self._get_filter_options()
|
131
|
-
|
132
|
-
# Get common context
|
133
|
-
common_context = self.get_common_context()
|
134
|
-
|
135
|
-
context.update({
|
136
|
-
'filters': filter_context,
|
137
|
-
'filter_options': filter_options,
|
138
|
-
'total_count': self.get_queryset().count(),
|
139
|
-
**common_context
|
140
|
-
})
|
141
|
-
|
142
|
-
return context
|
143
|
-
|
144
|
-
def _get_filter_options(self):
|
145
|
-
"""Get available options for filter dropdowns."""
|
146
|
-
|
147
|
-
# Get unique statuses
|
148
|
-
statuses = UniversalPayment.objects.values_list('status', flat=True).distinct()
|
149
|
-
status_choices = [(status, status.title()) for status in statuses if status]
|
150
|
-
|
151
|
-
# Get unique providers
|
152
|
-
providers = UniversalPayment.objects.values_list('provider', flat=True).distinct()
|
153
|
-
provider_choices = [(provider, provider.title()) for provider in providers if provider]
|
154
|
-
|
155
|
-
return {
|
156
|
-
'statuses': status_choices,
|
157
|
-
'providers': provider_choices,
|
158
|
-
}
|
@@ -1,174 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
QR code views for crypto payments.
|
3
|
-
|
4
|
-
Provides QR code generation and display for cryptocurrency payments.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from django.views.generic import DetailView
|
8
|
-
from django.http import JsonResponse
|
9
|
-
from .base import (
|
10
|
-
SuperuserRequiredMixin,
|
11
|
-
PaymentContextMixin,
|
12
|
-
superuser_required,
|
13
|
-
log_view_access
|
14
|
-
)
|
15
|
-
from ...models import UniversalPayment
|
16
|
-
|
17
|
-
|
18
|
-
class PaymentQRCodeView(
|
19
|
-
SuperuserRequiredMixin,
|
20
|
-
PaymentContextMixin,
|
21
|
-
DetailView
|
22
|
-
):
|
23
|
-
"""QR code view for crypto payments."""
|
24
|
-
|
25
|
-
model = UniversalPayment
|
26
|
-
template_name = 'payments/payment_qr.html'
|
27
|
-
context_object_name = 'payment'
|
28
|
-
page_title = 'Payment QR Code'
|
29
|
-
|
30
|
-
def get_breadcrumbs(self):
|
31
|
-
payment = self.get_object()
|
32
|
-
return [
|
33
|
-
{'name': 'Dashboard', 'url': '/payments/admin/'},
|
34
|
-
{'name': 'Payments', 'url': '/payments/admin/list/'},
|
35
|
-
{'name': f'Payment #{payment.internal_payment_id or str(payment.id)[:8]}',
|
36
|
-
'url': f'/payments/admin/payment/{payment.id}/'},
|
37
|
-
{'name': 'QR Code', 'url': ''},
|
38
|
-
]
|
39
|
-
|
40
|
-
def get_context_data(self, **kwargs):
|
41
|
-
context = super().get_context_data(**kwargs)
|
42
|
-
payment = self.get_object()
|
43
|
-
|
44
|
-
# Log access for audit
|
45
|
-
log_view_access('payment_qr', self.request.user, payment_id=payment.id)
|
46
|
-
|
47
|
-
# Check if payment supports QR codes
|
48
|
-
if not self._supports_qr_code(payment):
|
49
|
-
context['error'] = "QR codes are not supported for this payment method"
|
50
|
-
return context
|
51
|
-
|
52
|
-
# Generate QR code data
|
53
|
-
qr_data = self._generate_qr_data(payment)
|
54
|
-
|
55
|
-
# Get payment instructions
|
56
|
-
instructions = self._get_payment_instructions(payment)
|
57
|
-
|
58
|
-
# Get common context
|
59
|
-
common_context = self.get_common_context()
|
60
|
-
|
61
|
-
context.update({
|
62
|
-
'qr_data': qr_data,
|
63
|
-
'qr_size': self.request.GET.get('size', 256),
|
64
|
-
'instructions': instructions,
|
65
|
-
'is_crypto': self._is_crypto_payment(payment),
|
66
|
-
'can_copy': True,
|
67
|
-
**common_context
|
68
|
-
})
|
69
|
-
|
70
|
-
return context
|
71
|
-
|
72
|
-
def _supports_qr_code(self, payment):
|
73
|
-
"""Check if payment method supports QR codes."""
|
74
|
-
crypto_providers = ['nowpayments', 'cryptapi', 'cryptomus']
|
75
|
-
return payment.provider in crypto_providers and payment.pay_address
|
76
|
-
|
77
|
-
def _is_crypto_payment(self, payment):
|
78
|
-
"""Check if payment is cryptocurrency-based."""
|
79
|
-
crypto_providers = ['nowpayments', 'cryptapi', 'cryptomus']
|
80
|
-
return payment.provider in crypto_providers
|
81
|
-
|
82
|
-
def _generate_qr_data(self, payment):
|
83
|
-
"""Generate QR code data for the payment."""
|
84
|
-
if not payment.pay_address:
|
85
|
-
return None
|
86
|
-
|
87
|
-
# For crypto payments, use standard format
|
88
|
-
if self._is_crypto_payment(payment):
|
89
|
-
qr_data = payment.pay_address
|
90
|
-
|
91
|
-
# Add amount if available
|
92
|
-
if payment.pay_amount:
|
93
|
-
# Use appropriate URI scheme based on currency
|
94
|
-
uri_schemes = {
|
95
|
-
'BTC': 'bitcoin',
|
96
|
-
'LTC': 'litecoin',
|
97
|
-
'ETH': 'ethereum',
|
98
|
-
'BCH': 'bitcoincash',
|
99
|
-
}
|
100
|
-
|
101
|
-
scheme = uri_schemes.get(payment.currency_code.upper(), 'crypto')
|
102
|
-
qr_data = f"{scheme}:{payment.pay_address}?amount={payment.pay_amount}"
|
103
|
-
|
104
|
-
# Add label if available
|
105
|
-
if payment.internal_payment_id:
|
106
|
-
qr_data += f"&label=Payment%20{payment.internal_payment_id}"
|
107
|
-
|
108
|
-
return qr_data
|
109
|
-
|
110
|
-
return payment.pay_address
|
111
|
-
|
112
|
-
def _get_payment_instructions(self, payment):
|
113
|
-
"""Get step-by-step payment instructions."""
|
114
|
-
if not self._is_crypto_payment(payment):
|
115
|
-
return []
|
116
|
-
|
117
|
-
instructions = [
|
118
|
-
"Scan the QR code with your crypto wallet app",
|
119
|
-
f"Send exactly {payment.pay_amount} {payment.currency_code} to the address",
|
120
|
-
"Wait for network confirmations",
|
121
|
-
"Payment will be automatically confirmed"
|
122
|
-
]
|
123
|
-
|
124
|
-
# Add provider-specific instructions
|
125
|
-
if payment.provider == 'cryptapi':
|
126
|
-
instructions.append("Minimum 1 confirmation required")
|
127
|
-
elif payment.provider == 'nowpayments':
|
128
|
-
instructions.append("Minimum 2 confirmations required")
|
129
|
-
elif payment.provider == 'cryptomus':
|
130
|
-
instructions.append("Confirmations depend on selected network")
|
131
|
-
|
132
|
-
return instructions
|
133
|
-
|
134
|
-
|
135
|
-
@superuser_required
|
136
|
-
def qr_code_data_ajax(request, payment_id):
|
137
|
-
"""AJAX endpoint to get QR code data."""
|
138
|
-
try:
|
139
|
-
payment = UniversalPayment.objects.get(id=payment_id)
|
140
|
-
|
141
|
-
# Log access for audit
|
142
|
-
log_view_access('qr_ajax', request.user, payment_id=payment_id)
|
143
|
-
|
144
|
-
view = PaymentQRCodeView()
|
145
|
-
|
146
|
-
# Check if payment supports QR codes
|
147
|
-
if not view._supports_qr_code(payment):
|
148
|
-
return JsonResponse({
|
149
|
-
'error': 'QR codes not supported for this payment method'
|
150
|
-
}, status=400)
|
151
|
-
|
152
|
-
# Generate QR data
|
153
|
-
qr_data = view._generate_qr_data(payment)
|
154
|
-
|
155
|
-
if not qr_data:
|
156
|
-
return JsonResponse({
|
157
|
-
'error': 'Unable to generate QR code data'
|
158
|
-
}, status=400)
|
159
|
-
|
160
|
-
response_data = {
|
161
|
-
'qr_data': qr_data,
|
162
|
-
'payment_address': payment.pay_address,
|
163
|
-
'payment_amount': str(payment.pay_amount) if payment.pay_amount else None,
|
164
|
-
'currency': payment.currency_code,
|
165
|
-
'provider': payment.provider,
|
166
|
-
'instructions': view._get_payment_instructions(payment),
|
167
|
-
}
|
168
|
-
|
169
|
-
return JsonResponse(response_data)
|
170
|
-
|
171
|
-
except UniversalPayment.DoesNotExist:
|
172
|
-
return JsonResponse({'error': 'Payment not found'}, status=404)
|
173
|
-
except Exception as e:
|
174
|
-
return JsonResponse({'error': str(e)}, status=500)
|