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.
- 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 -9
- 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 +600 -108
- django_cfg/apps/payments/admin/filters.py +306 -199
- django_cfg/apps/payments/admin/payments_admin.py +470 -64
- 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 +381 -0
- django_cfg/apps/payments/management/commands/manage_providers.py +408 -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 +343 -163
- django_cfg/apps/payments/middleware/usage_tracking.py +250 -238
- django_cfg/apps/payments/migrations/0001_initial.py +708 -536
- django_cfg/apps/payments/models/__init__.py +16 -20
- 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 +207 -67
- 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 -284
- 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 +344 -468
- django_cfg/apps/payments/services/core/subscription_service.py +425 -484
- 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 +232 -71
- django_cfg/apps/payments/services/providers/nowpayments.py +404 -219
- django_cfg/apps/payments/services/providers/registry.py +429 -80
- 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 +211 -130
- django_cfg/apps/payments/signals/balance_signals.py +174 -0
- django_cfg/apps/payments/signals/payment_signals.py +129 -98
- django_cfg/apps/payments/signals/subscription_signals.py +195 -143
- 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 +46 -47
- django_cfg/apps/payments/urls_admin.py +49 -0
- 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/apps/tasks/urls.py +0 -2
- django_cfg/apps/tasks/urls_admin.py +14 -0
- django_cfg/apps/urls.py +4 -4
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +75 -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 -498
- django_cfg/modules/django_currency/__init__.py +16 -11
- django_cfg/modules/django_currency/clients/__init__.py +4 -4
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
- django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
- django_cfg/modules/django_currency/core/__init__.py +1 -7
- django_cfg/modules/django_currency/core/converter.py +18 -23
- django_cfg/modules/django_currency/core/models.py +122 -11
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +190 -309
- django_cfg/modules/django_logger.py +160 -146
- django_cfg/modules/django_unfold/dashboard.py +65 -12
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/admin/components/action_grid.html +9 -9
- django_cfg/templates/admin/components/metric_card.html +5 -5
- django_cfg/templates/admin/components/status_badge.html +2 -2
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
- django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
- django_cfg/templates/admin/snippets/components/system_health.html +1 -1
- django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
- django_cfg/utils/smart_defaults.py +222 -571
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/METADATA +5 -4
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/RECORD +172 -182
- 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 -178
- django_cfg/apps/payments/management/commands/currency_stats.py +0 -323
- django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
- django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
- django_cfg/apps/payments/managers/__init__.py +0 -22
- 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 -83
- django_cfg/apps/payments/managers/payment_manager.py +0 -44
- django_cfg/apps/payments/managers/subscription_manager.py +0 -37
- django_cfg/apps/payments/managers/tariff_manager.py +0 -29
- django_cfg/apps/payments/models/events.py +0 -73
- django_cfg/apps/payments/serializers/__init__.py +0 -56
- 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 -55
- 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 -297
- 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 -222
- django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
- django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
- django_cfg/apps/payments/services/providers/cryptomus.py +0 -311
- django_cfg/apps/payments/services/security/__init__.py +0 -34
- django_cfg/apps/payments/services/security/error_handler.py +0 -637
- django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
- django_cfg/apps/payments/services/security/webhook_validator.py +0 -475
- django_cfg/apps/payments/services/validators/__init__.py +0 -8
- 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/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 -36
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
- django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -27
- django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -144
- django_cfg/apps/payments/templates/payments/dashboard.html +0 -346
- django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
- django_cfg/apps/payments/urls_templates.py +0 -52
- django_cfg/apps/payments/utils/__init__.py +0 -45
- django_cfg/apps/payments/utils/billing_utils.py +0 -342
- django_cfg/apps/payments/utils/config_utils.py +0 -245
- 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 -62
- 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 -111
- 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 -312
- django_cfg/apps/payments/views/templates/base.py +0 -204
- 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 -164
- django_cfg/apps/payments/views/templates/qr_code.py +0 -174
- django_cfg/apps/payments/views/templates/stats.py +0 -240
- 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 -65
- django_cfg/core/integration.py +0 -160
- django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
- django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
- 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.29.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,315 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Payment Template Tags
|
3
|
-
|
4
|
-
Custom template tags for payment functionality, status badges, progress bars,
|
5
|
-
and real-time payment tracking components.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from django import template
|
9
|
-
from django.utils.safestring import mark_safe
|
10
|
-
from django.utils.html import format_html
|
11
|
-
from django.db.models import Count, Sum, Q
|
12
|
-
from decimal import Decimal
|
13
|
-
import json
|
14
|
-
|
15
|
-
register = template.Library()
|
16
|
-
|
17
|
-
|
18
|
-
@register.simple_tag
|
19
|
-
def payment_status_badge(payment):
|
20
|
-
"""Render payment status badge with icon and color."""
|
21
|
-
status_config = {
|
22
|
-
'pending': {'color': 'yellow', 'icon': 'pending', 'animate': True},
|
23
|
-
'confirming': {'color': 'blue', 'icon': 'sync', 'animate': True},
|
24
|
-
'confirmed': {'color': 'green', 'icon': 'check_circle', 'animate': False},
|
25
|
-
'completed': {'color': 'green', 'icon': 'verified', 'animate': False},
|
26
|
-
'failed': {'color': 'red', 'icon': 'error', 'animate': False},
|
27
|
-
'expired': {'color': 'gray', 'icon': 'schedule', 'animate': False},
|
28
|
-
'cancelled': {'color': 'gray', 'icon': 'cancel', 'animate': False},
|
29
|
-
'refunded': {'color': 'purple', 'icon': 'undo', 'animate': False},
|
30
|
-
}
|
31
|
-
|
32
|
-
config = status_config.get(payment.status, {'color': 'gray', 'icon': 'help', 'animate': False})
|
33
|
-
animate_class = 'animate-pulse' if config['animate'] else ''
|
34
|
-
|
35
|
-
return format_html(
|
36
|
-
'<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-{}-100 text-{}-800 dark:bg-{}-900 dark:text-{}-200">'
|
37
|
-
'<span class="material-icons text-sm mr-1 {}">{}</span>'
|
38
|
-
'<span class="status-text">{}</span>'
|
39
|
-
'</span>',
|
40
|
-
config['color'], config['color'], config['color'], config['color'],
|
41
|
-
animate_class,
|
42
|
-
config['icon'],
|
43
|
-
payment.get_status_display()
|
44
|
-
)
|
45
|
-
|
46
|
-
|
47
|
-
@register.filter
|
48
|
-
def payment_progress_percentage(payment):
|
49
|
-
"""Calculate payment progress percentage."""
|
50
|
-
progress_map = {
|
51
|
-
'pending': 10,
|
52
|
-
'confirming': 40,
|
53
|
-
'confirmed': 70,
|
54
|
-
'completed': 100,
|
55
|
-
'failed': 0,
|
56
|
-
'expired': 0,
|
57
|
-
'cancelled': 0,
|
58
|
-
'refunded': 50, # Partial progress for refunds
|
59
|
-
}
|
60
|
-
return progress_map.get(payment.status, 0)
|
61
|
-
|
62
|
-
|
63
|
-
@register.filter
|
64
|
-
def payment_progress_steps(payment):
|
65
|
-
"""Get payment progress steps with status."""
|
66
|
-
steps = [
|
67
|
-
{'label': 'Created', 'key': 'created'},
|
68
|
-
{'label': 'Processing', 'key': 'processing'},
|
69
|
-
{'label': 'Confirming', 'key': 'confirming'},
|
70
|
-
{'label': 'Completed', 'key': 'completed'},
|
71
|
-
]
|
72
|
-
|
73
|
-
status_order = ['pending', 'confirming', 'confirmed', 'completed']
|
74
|
-
current_index = status_order.index(payment.status) if payment.status in status_order else -1
|
75
|
-
|
76
|
-
for i, step in enumerate(steps):
|
77
|
-
step['completed'] = i < current_index
|
78
|
-
step['active'] = i == current_index
|
79
|
-
|
80
|
-
return steps
|
81
|
-
|
82
|
-
|
83
|
-
@register.inclusion_tag('payments/components/payment_card.html')
|
84
|
-
def payment_card(payment, show_actions=True, compact=False):
|
85
|
-
"""Render payment card component."""
|
86
|
-
return {
|
87
|
-
'payment': payment,
|
88
|
-
'show_actions': show_actions,
|
89
|
-
'compact': compact
|
90
|
-
}
|
91
|
-
|
92
|
-
|
93
|
-
@register.inclusion_tag('payments/components/status_badge.html')
|
94
|
-
def render_payment_status(payment):
|
95
|
-
"""Render payment status badge component."""
|
96
|
-
return {'payment': payment}
|
97
|
-
|
98
|
-
|
99
|
-
@register.inclusion_tag('payments/components/progress_bar.html')
|
100
|
-
def payment_progress_bar(payment):
|
101
|
-
"""Render payment progress bar component."""
|
102
|
-
return {
|
103
|
-
'payment': payment,
|
104
|
-
'percentage': payment_progress_percentage(payment),
|
105
|
-
'steps': payment_progress_steps(payment)
|
106
|
-
}
|
107
|
-
|
108
|
-
|
109
|
-
@register.inclusion_tag('payments/components/payment_tracker.html', takes_context=True)
|
110
|
-
def payment_tracker(context, payment_id):
|
111
|
-
"""Render real-time payment tracker."""
|
112
|
-
try:
|
113
|
-
from ..models import UniversalPayment
|
114
|
-
payment = UniversalPayment.objects.get(id=payment_id)
|
115
|
-
return {
|
116
|
-
'payment': payment,
|
117
|
-
'request': context.get('request'),
|
118
|
-
'user': context.get('user'),
|
119
|
-
'websocket_url': f"/ws/payments/{payment_id}/"
|
120
|
-
}
|
121
|
-
except UniversalPayment.DoesNotExist:
|
122
|
-
return {'payment': None}
|
123
|
-
|
124
|
-
|
125
|
-
@register.simple_tag
|
126
|
-
def payment_websocket_url(payment_id):
|
127
|
-
"""Get WebSocket URL for real-time payment updates."""
|
128
|
-
return f"/ws/payments/{payment_id}/"
|
129
|
-
|
130
|
-
|
131
|
-
@register.filter
|
132
|
-
def format_crypto_amount(amount, currency_code):
|
133
|
-
"""Format cryptocurrency amount with proper decimals."""
|
134
|
-
if not amount:
|
135
|
-
return "0"
|
136
|
-
|
137
|
-
# Different currencies have different decimal places
|
138
|
-
decimal_places = {
|
139
|
-
'BTC': 8,
|
140
|
-
'ETH': 6,
|
141
|
-
'LTC': 8,
|
142
|
-
'USDT': 6,
|
143
|
-
'USDC': 6,
|
144
|
-
'USD': 2,
|
145
|
-
'EUR': 2,
|
146
|
-
}
|
147
|
-
|
148
|
-
places = decimal_places.get(currency_code.upper(), 6)
|
149
|
-
formatted = f"{float(amount):.{places}f}".rstrip('0').rstrip('.')
|
150
|
-
return formatted if formatted else "0"
|
151
|
-
|
152
|
-
|
153
|
-
@register.simple_tag
|
154
|
-
def get_payment_stats():
|
155
|
-
"""Get payment statistics for dashboard."""
|
156
|
-
try:
|
157
|
-
from ..models import UniversalPayment
|
158
|
-
|
159
|
-
stats = UniversalPayment.objects.aggregate(
|
160
|
-
total_count=Count('id'),
|
161
|
-
pending_count=Count('id', filter=Q(status='pending')),
|
162
|
-
confirming_count=Count('id', filter=Q(status='confirming')),
|
163
|
-
completed_count=Count('id', filter=Q(status='completed')),
|
164
|
-
failed_count=Count('id', filter=Q(status='failed')),
|
165
|
-
total_volume=Sum('amount_usd')
|
166
|
-
)
|
167
|
-
|
168
|
-
return {
|
169
|
-
'total_payments_count': stats['total_count'] or 0,
|
170
|
-
'pending_payments_count': stats['pending_count'] or 0,
|
171
|
-
'confirming_payments_count': stats['confirming_count'] or 0,
|
172
|
-
'completed_payments_count': stats['completed_count'] or 0,
|
173
|
-
'failed_payments_count': stats['failed_count'] or 0,
|
174
|
-
'total_volume': float(stats['total_volume'] or 0),
|
175
|
-
}
|
176
|
-
except Exception:
|
177
|
-
# Return default values if there's any error
|
178
|
-
return {
|
179
|
-
'total_payments_count': 0,
|
180
|
-
'pending_payments_count': 0,
|
181
|
-
'confirming_payments_count': 0,
|
182
|
-
'completed_payments_count': 0,
|
183
|
-
'failed_payments_count': 0,
|
184
|
-
'total_volume': 0.0,
|
185
|
-
}
|
186
|
-
|
187
|
-
|
188
|
-
@register.inclusion_tag('payments/components/provider_stats.html')
|
189
|
-
def provider_statistics():
|
190
|
-
"""Render provider statistics."""
|
191
|
-
try:
|
192
|
-
from ..models import UniversalPayment
|
193
|
-
from django.db.models import Avg
|
194
|
-
|
195
|
-
stats = UniversalPayment.objects.values('provider').annotate(
|
196
|
-
count=Count('id'),
|
197
|
-
volume=Sum('amount_usd'),
|
198
|
-
avg_amount=Avg('amount_usd'),
|
199
|
-
completed_count=Count('id', filter=Q(status='completed')),
|
200
|
-
).order_by('-volume')
|
201
|
-
|
202
|
-
# Calculate success rate
|
203
|
-
for stat in stats:
|
204
|
-
if stat['count'] > 0:
|
205
|
-
stat['success_rate'] = (stat['completed_count'] / stat['count']) * 100
|
206
|
-
else:
|
207
|
-
stat['success_rate'] = 0
|
208
|
-
|
209
|
-
return {'provider_stats': stats}
|
210
|
-
except Exception:
|
211
|
-
return {'provider_stats': []}
|
212
|
-
|
213
|
-
|
214
|
-
@register.simple_tag
|
215
|
-
def payment_status_distribution():
|
216
|
-
"""Get payment status distribution for charts."""
|
217
|
-
try:
|
218
|
-
from ..models import UniversalPayment
|
219
|
-
|
220
|
-
distribution = UniversalPayment.objects.values('status').annotate(
|
221
|
-
count=Count('id')
|
222
|
-
).order_by('-count')
|
223
|
-
|
224
|
-
return {item['status']: item['count'] for item in distribution}
|
225
|
-
except Exception:
|
226
|
-
return {}
|
227
|
-
|
228
|
-
|
229
|
-
@register.filter
|
230
|
-
def provider_display_name(provider_key):
|
231
|
-
"""Get display name for provider."""
|
232
|
-
provider_names = {
|
233
|
-
'nowpayments': 'NowPayments',
|
234
|
-
'cryptapi': 'CryptAPI',
|
235
|
-
'cryptomus': 'Cryptomus',
|
236
|
-
'stripe': 'Stripe',
|
237
|
-
'internal': 'Internal',
|
238
|
-
}
|
239
|
-
return provider_names.get(provider_key, provider_key.title())
|
240
|
-
|
241
|
-
|
242
|
-
@register.filter
|
243
|
-
def payment_method_icon(provider):
|
244
|
-
"""Get icon for payment method."""
|
245
|
-
icons = {
|
246
|
-
'nowpayments': 'currency_bitcoin',
|
247
|
-
'cryptapi': 'currency_bitcoin',
|
248
|
-
'cryptomus': 'currency_bitcoin',
|
249
|
-
'stripe': 'credit_card',
|
250
|
-
'internal': 'account_balance',
|
251
|
-
}
|
252
|
-
return icons.get(provider, 'payment')
|
253
|
-
|
254
|
-
|
255
|
-
@register.simple_tag
|
256
|
-
def payment_json_data(payment):
|
257
|
-
"""Convert payment to JSON for JavaScript use."""
|
258
|
-
try:
|
259
|
-
data = {
|
260
|
-
'id': str(payment.id),
|
261
|
-
'status': payment.status,
|
262
|
-
'amount_usd': float(payment.amount_usd),
|
263
|
-
'currency_code': payment.currency_code,
|
264
|
-
'provider': payment.provider,
|
265
|
-
'created_at': payment.created_at.isoformat(),
|
266
|
-
'progress_percentage': payment_progress_percentage(payment),
|
267
|
-
}
|
268
|
-
return mark_safe(json.dumps(data))
|
269
|
-
except Exception:
|
270
|
-
return mark_safe('{}')
|
271
|
-
|
272
|
-
|
273
|
-
@register.filter
|
274
|
-
def time_since_created(payment):
|
275
|
-
"""Get human-readable time since payment was created."""
|
276
|
-
from django.utils import timezone
|
277
|
-
from django.utils.timesince import timesince
|
278
|
-
|
279
|
-
if payment.created_at:
|
280
|
-
return timesince(payment.created_at, timezone.now())
|
281
|
-
return "Unknown"
|
282
|
-
|
283
|
-
|
284
|
-
@register.filter
|
285
|
-
def is_crypto_payment(payment):
|
286
|
-
"""Check if payment is cryptocurrency-based."""
|
287
|
-
crypto_providers = ['nowpayments', 'cryptapi', 'cryptomus']
|
288
|
-
return payment.provider in crypto_providers
|
289
|
-
|
290
|
-
|
291
|
-
@register.filter
|
292
|
-
def can_cancel_payment(payment):
|
293
|
-
"""Check if payment can be cancelled."""
|
294
|
-
cancellable_statuses = ['pending', 'confirming']
|
295
|
-
return payment.status in cancellable_statuses
|
296
|
-
|
297
|
-
|
298
|
-
@register.filter
|
299
|
-
def payment_qr_code_data(payment):
|
300
|
-
"""Get QR code data for payment."""
|
301
|
-
if hasattr(payment, 'pay_address') and payment.pay_address:
|
302
|
-
# For crypto payments, use address:amount format
|
303
|
-
if payment.pay_amount:
|
304
|
-
return f"{payment.pay_address}?amount={payment.pay_amount}"
|
305
|
-
return payment.pay_address
|
306
|
-
return None
|
307
|
-
|
308
|
-
|
309
|
-
@register.inclusion_tag('payments/components/payment_qr_code.html')
|
310
|
-
def payment_qr_code(payment):
|
311
|
-
"""Render QR code for payment."""
|
312
|
-
return {
|
313
|
-
'payment': payment,
|
314
|
-
'qr_data': payment_qr_code_data(payment)
|
315
|
-
}
|
@@ -1,52 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Template URLs for Payment Dashboard.
|
3
|
-
|
4
|
-
All URLs require superuser access as this is an internal admin tool.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from django.urls import path
|
8
|
-
from .views.templates import (
|
9
|
-
PaymentDashboardView,
|
10
|
-
PaymentDetailView,
|
11
|
-
PaymentCreateView,
|
12
|
-
PaymentStatsView,
|
13
|
-
PaymentListView,
|
14
|
-
PaymentQRCodeView,
|
15
|
-
PaymentTestView,
|
16
|
-
payment_status_ajax,
|
17
|
-
payment_events_ajax,
|
18
|
-
)
|
19
|
-
from .views.templates.ajax import (
|
20
|
-
payment_stats_ajax,
|
21
|
-
payment_search_ajax,
|
22
|
-
payment_action_ajax,
|
23
|
-
)
|
24
|
-
from .views.templates.qr_code import qr_code_data_ajax
|
25
|
-
|
26
|
-
app_name = 'payments_dashboard'
|
27
|
-
|
28
|
-
urlpatterns = [
|
29
|
-
# Main dashboard
|
30
|
-
path('', PaymentDashboardView.as_view(), name='dashboard'),
|
31
|
-
path('dashboard/', PaymentDashboardView.as_view(), name='dashboard_alt'),
|
32
|
-
|
33
|
-
# Payment management
|
34
|
-
path('list/', PaymentListView.as_view(), name='list'),
|
35
|
-
path('create/', PaymentCreateView.as_view(), name='create'),
|
36
|
-
path('stats/', PaymentStatsView.as_view(), name='stats'),
|
37
|
-
|
38
|
-
# Payment details
|
39
|
-
path('payment/<uuid:pk>/', PaymentDetailView.as_view(), name='detail'),
|
40
|
-
path('payment/<uuid:pk>/qr/', PaymentQRCodeView.as_view(), name='qr_code'),
|
41
|
-
|
42
|
-
# AJAX endpoints
|
43
|
-
path('ajax/payment/<uuid:payment_id>/status/', payment_status_ajax, name='payment_status_ajax'),
|
44
|
-
path('ajax/payment/<uuid:payment_id>/events/', payment_events_ajax, name='payment_events_ajax'),
|
45
|
-
path('ajax/payment/<uuid:payment_id>/qr-data/', qr_code_data_ajax, name='qr_data_ajax'),
|
46
|
-
path('ajax/payment/<uuid:payment_id>/action/', payment_action_ajax, name='payment_action_ajax'),
|
47
|
-
path('ajax/stats/', payment_stats_ajax, name='payment_stats_ajax'),
|
48
|
-
path('ajax/search/', payment_search_ajax, name='payment_search_ajax'),
|
49
|
-
|
50
|
-
# Development/testing
|
51
|
-
path('test/', PaymentTestView.as_view(), name='test'),
|
52
|
-
]
|
@@ -1,45 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Utilities for universal payments.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from .middleware_utils import get_client_ip, is_api_request, extract_api_key
|
6
|
-
from .billing_utils import calculate_usage_cost, create_billing_transaction, calculate_subscription_refund, process_subscription_billing, get_billing_summary
|
7
|
-
from .validation_utils import validate_api_key, check_subscription_access
|
8
|
-
|
9
|
-
# Configuration utilities
|
10
|
-
from .config_utils import (
|
11
|
-
PaymentsConfigUtil,
|
12
|
-
RedisConfigHelper,
|
13
|
-
CacheConfigHelper,
|
14
|
-
ProviderConfigHelper,
|
15
|
-
get_payments_config,
|
16
|
-
is_payments_enabled,
|
17
|
-
is_debug_mode
|
18
|
-
)
|
19
|
-
|
20
|
-
__all__ = [
|
21
|
-
# Middleware utilities
|
22
|
-
'get_client_ip',
|
23
|
-
'is_api_request',
|
24
|
-
'extract_api_key',
|
25
|
-
|
26
|
-
# Billing utilities
|
27
|
-
'calculate_usage_cost',
|
28
|
-
'create_billing_transaction',
|
29
|
-
'calculate_subscription_refund',
|
30
|
-
'process_subscription_billing',
|
31
|
-
'get_billing_summary',
|
32
|
-
|
33
|
-
# Validation utilities
|
34
|
-
'validate_api_key',
|
35
|
-
'check_subscription_access',
|
36
|
-
|
37
|
-
# Configuration utilities
|
38
|
-
'PaymentsConfigUtil',
|
39
|
-
'RedisConfigHelper',
|
40
|
-
'CacheConfigHelper',
|
41
|
-
'ProviderConfigHelper',
|
42
|
-
'get_payments_config',
|
43
|
-
'is_payments_enabled',
|
44
|
-
'is_debug_mode',
|
45
|
-
]
|