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
@@ -0,0 +1,500 @@
|
|
1
|
+
{% extends 'payments/base.html' %}
|
2
|
+
{% load static %}
|
3
|
+
|
4
|
+
{% block title %}Payment Status - Universal Payment System{% endblock %}
|
5
|
+
|
6
|
+
{% block page_title %}Payment Status{% endblock %}
|
7
|
+
{% block page_subtitle %}Track your payment progress in real-time{% endblock %}
|
8
|
+
|
9
|
+
{% block extra_css %}
|
10
|
+
<style>
|
11
|
+
.status-timeline {
|
12
|
+
position: relative;
|
13
|
+
}
|
14
|
+
|
15
|
+
.status-timeline::before {
|
16
|
+
content: '';
|
17
|
+
position: absolute;
|
18
|
+
left: 16px;
|
19
|
+
top: 0;
|
20
|
+
bottom: 0;
|
21
|
+
width: 2px;
|
22
|
+
background: linear-gradient(to bottom, #3b82f6, #e5e7eb);
|
23
|
+
}
|
24
|
+
|
25
|
+
.timeline-item {
|
26
|
+
position: relative;
|
27
|
+
padding-left: 48px;
|
28
|
+
padding-bottom: 24px;
|
29
|
+
}
|
30
|
+
|
31
|
+
.timeline-item:last-child {
|
32
|
+
padding-bottom: 0;
|
33
|
+
}
|
34
|
+
|
35
|
+
.timeline-icon {
|
36
|
+
position: absolute;
|
37
|
+
left: 0;
|
38
|
+
top: 0;
|
39
|
+
width: 32px;
|
40
|
+
height: 32px;
|
41
|
+
border-radius: 50%;
|
42
|
+
display: flex;
|
43
|
+
align-items: center;
|
44
|
+
justify-content: center;
|
45
|
+
z-index: 1;
|
46
|
+
}
|
47
|
+
|
48
|
+
.timeline-icon.completed {
|
49
|
+
background-color: #10b981;
|
50
|
+
color: white;
|
51
|
+
}
|
52
|
+
|
53
|
+
.timeline-icon.current {
|
54
|
+
background-color: #3b82f6;
|
55
|
+
color: white;
|
56
|
+
animation: pulse 2s infinite;
|
57
|
+
}
|
58
|
+
|
59
|
+
.timeline-icon.pending {
|
60
|
+
background-color: #e5e7eb;
|
61
|
+
color: #6b7280;
|
62
|
+
}
|
63
|
+
|
64
|
+
@keyframes pulse {
|
65
|
+
0%, 100% { transform: scale(1); }
|
66
|
+
50% { transform: scale(1.1); }
|
67
|
+
}
|
68
|
+
|
69
|
+
.payment-qr {
|
70
|
+
max-width: 200px;
|
71
|
+
margin: 0 auto;
|
72
|
+
}
|
73
|
+
|
74
|
+
.countdown {
|
75
|
+
font-variant-numeric: tabular-nums;
|
76
|
+
}
|
77
|
+
</style>
|
78
|
+
{% endblock %}
|
79
|
+
|
80
|
+
{% block content %}
|
81
|
+
<div x-data="paymentStatus('{{ payment.id }}')" x-init="init()" class="max-w-4xl mx-auto">
|
82
|
+
<!-- Payment Header -->
|
83
|
+
<div class="payment-card mb-8">
|
84
|
+
<div class="flex items-center justify-between">
|
85
|
+
<div class="flex items-center">
|
86
|
+
<div class="w-12 h-12 bg-blue-100 dark:bg-blue-900 rounded-full flex items-center justify-center mr-4">
|
87
|
+
<span class="material-icons-outlined text-blue-600 dark:text-blue-400">receipt_long</span>
|
88
|
+
</div>
|
89
|
+
<div>
|
90
|
+
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">Payment #{{ payment.external_id|default:payment.id|truncatechars:8 }}</h1>
|
91
|
+
<p class="text-gray-600 dark:text-gray-400">Created {{ payment.created_at|date:"M d, Y H:i" }}</p>
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
|
95
|
+
<div class="text-right">
|
96
|
+
<div class="text-2xl font-bold text-gray-900 dark:text-white">
|
97
|
+
${{ payment.amount_usd|floatformat:2 }}
|
98
|
+
</div>
|
99
|
+
<div class="text-sm text-gray-600 dark:text-gray-400">
|
100
|
+
{{ payment.currency.code }}
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
</div>
|
104
|
+
</div>
|
105
|
+
|
106
|
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
107
|
+
<!-- Status Timeline -->
|
108
|
+
<div class="lg:col-span-2">
|
109
|
+
<div class="payment-card">
|
110
|
+
<div class="payment-card-header">
|
111
|
+
<h2 class="payment-card-title">
|
112
|
+
<span class="material-icons-outlined">timeline</span>
|
113
|
+
Payment Progress
|
114
|
+
</h2>
|
115
|
+
<div class="flex items-center">
|
116
|
+
<span class="status-indicator" :class="getStatusIndicatorClass(payment.status)"></span>
|
117
|
+
<span class="status-badge" :class="getStatusBadgeClass(payment.status)" x-text="payment.status_display"></span>
|
118
|
+
</div>
|
119
|
+
</div>
|
120
|
+
|
121
|
+
<div class="payment-card-content">
|
122
|
+
<div class="status-timeline">
|
123
|
+
<!-- Created -->
|
124
|
+
<div class="timeline-item">
|
125
|
+
<div class="timeline-icon completed">
|
126
|
+
<span class="material-icons-outlined text-sm">add_circle</span>
|
127
|
+
</div>
|
128
|
+
<div>
|
129
|
+
<h3 class="font-medium text-gray-900 dark:text-white">Payment Created</h3>
|
130
|
+
<p class="text-sm text-gray-600 dark:text-gray-400">
|
131
|
+
Payment request initiated
|
132
|
+
</p>
|
133
|
+
<p class="text-xs text-gray-500 dark:text-gray-500 mt-1">
|
134
|
+
{{ payment.created_at|date:"M d, Y H:i:s" }}
|
135
|
+
</p>
|
136
|
+
</div>
|
137
|
+
</div>
|
138
|
+
|
139
|
+
<!-- Processing -->
|
140
|
+
<div class="timeline-item">
|
141
|
+
<div class="timeline-icon" :class="payment.status === 'pending' || payment.status === 'processing' ? 'current' : (payment.status === 'completed' || payment.status === 'confirmed' ? 'completed' : 'pending')">
|
142
|
+
<span class="material-icons-outlined text-sm">sync</span>
|
143
|
+
</div>
|
144
|
+
<div>
|
145
|
+
<h3 class="font-medium text-gray-900 dark:text-white">Processing</h3>
|
146
|
+
<p class="text-sm text-gray-600 dark:text-gray-400">
|
147
|
+
<span x-show="payment.status === 'pending' || payment.status === 'processing'">
|
148
|
+
Payment is being processed by {{ payment.provider|title }}
|
149
|
+
</span>
|
150
|
+
<span x-show="payment.status === 'completed' || payment.status === 'confirmed'">
|
151
|
+
Payment processed successfully
|
152
|
+
</span>
|
153
|
+
<span x-show="payment.status === 'failed' || payment.status === 'cancelled'">
|
154
|
+
Payment processing failed
|
155
|
+
</span>
|
156
|
+
</p>
|
157
|
+
<p x-show="payment.updated_at" class="text-xs text-gray-500 dark:text-gray-500 mt-1" x-text="formatDate(payment.updated_at)"></p>
|
158
|
+
</div>
|
159
|
+
</div>
|
160
|
+
|
161
|
+
<!-- Confirmation -->
|
162
|
+
<div class="timeline-item">
|
163
|
+
<div class="timeline-icon" :class="payment.status === 'completed' || payment.status === 'confirmed' ? 'completed' : 'pending'">
|
164
|
+
<span class="material-icons-outlined text-sm">check_circle</span>
|
165
|
+
</div>
|
166
|
+
<div>
|
167
|
+
<h3 class="font-medium text-gray-900 dark:text-white">Confirmation</h3>
|
168
|
+
<p class="text-sm text-gray-600 dark:text-gray-400">
|
169
|
+
<span x-show="payment.status === 'completed' || payment.status === 'confirmed'">
|
170
|
+
Payment confirmed and completed
|
171
|
+
</span>
|
172
|
+
<span x-show="payment.status !== 'completed' && payment.status !== 'confirmed'">
|
173
|
+
Waiting for confirmation
|
174
|
+
</span>
|
175
|
+
</p>
|
176
|
+
<p x-show="payment.confirmed_at" class="text-xs text-gray-500 dark:text-gray-500 mt-1" x-text="formatDate(payment.confirmed_at)"></p>
|
177
|
+
</div>
|
178
|
+
</div>
|
179
|
+
</div>
|
180
|
+
</div>
|
181
|
+
</div>
|
182
|
+
|
183
|
+
<!-- Transaction Details -->
|
184
|
+
<div class="payment-card mt-8">
|
185
|
+
<div class="payment-card-header">
|
186
|
+
<h2 class="payment-card-title">
|
187
|
+
<span class="material-icons-outlined">info</span>
|
188
|
+
Transaction Details
|
189
|
+
</h2>
|
190
|
+
</div>
|
191
|
+
|
192
|
+
<div class="payment-card-content">
|
193
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
194
|
+
<div>
|
195
|
+
<h4 class="font-medium text-gray-900 dark:text-white mb-3">Payment Information</h4>
|
196
|
+
<div class="space-y-2 text-sm">
|
197
|
+
<div class="flex justify-between">
|
198
|
+
<span class="text-gray-600 dark:text-gray-400">Payment ID:</span>
|
199
|
+
<span class="font-mono" data-copy="{{ payment.id }}">{{ payment.id|truncatechars:12 }}</span>
|
200
|
+
</div>
|
201
|
+
<div class="flex justify-between">
|
202
|
+
<span class="text-gray-600 dark:text-gray-400">External ID:</span>
|
203
|
+
<span class="font-mono" x-text="payment.external_id || 'N/A'"></span>
|
204
|
+
</div>
|
205
|
+
<div class="flex justify-between">
|
206
|
+
<span class="text-gray-600 dark:text-gray-400">Provider:</span>
|
207
|
+
<span x-text="payment.provider"></span>
|
208
|
+
</div>
|
209
|
+
<div class="flex justify-between">
|
210
|
+
<span class="text-gray-600 dark:text-gray-400">Network:</span>
|
211
|
+
<span x-text="payment.network || 'N/A'"></span>
|
212
|
+
</div>
|
213
|
+
</div>
|
214
|
+
</div>
|
215
|
+
|
216
|
+
<div>
|
217
|
+
<h4 class="font-medium text-gray-900 dark:text-white mb-3">Amount Details</h4>
|
218
|
+
<div class="space-y-2 text-sm">
|
219
|
+
<div class="flex justify-between">
|
220
|
+
<span class="text-gray-600 dark:text-gray-400">USD Amount:</span>
|
221
|
+
<span class="font-medium">${{ payment.amount_usd|floatformat:2 }}</span>
|
222
|
+
</div>
|
223
|
+
<div class="flex justify-between">
|
224
|
+
<span class="text-gray-600 dark:text-gray-400">Crypto Amount:</span>
|
225
|
+
<span class="font-mono" x-text="payment.amount_crypto || 'N/A'"></span>
|
226
|
+
</div>
|
227
|
+
<div class="flex justify-between">
|
228
|
+
<span class="text-gray-600 dark:text-gray-400">Currency:</span>
|
229
|
+
<span x-text="payment.currency_code"></span>
|
230
|
+
</div>
|
231
|
+
<div class="flex justify-between">
|
232
|
+
<span class="text-gray-600 dark:text-gray-400">Exchange Rate:</span>
|
233
|
+
<span x-text="payment.exchange_rate || 'N/A'"></span>
|
234
|
+
</div>
|
235
|
+
</div>
|
236
|
+
</div>
|
237
|
+
</div>
|
238
|
+
</div>
|
239
|
+
</div>
|
240
|
+
</div>
|
241
|
+
|
242
|
+
<!-- Payment Actions Sidebar -->
|
243
|
+
<div class="space-y-6">
|
244
|
+
<!-- Quick Actions -->
|
245
|
+
<div class="payment-card">
|
246
|
+
<div class="payment-card-header">
|
247
|
+
<h3 class="payment-card-title">
|
248
|
+
<span class="material-icons-outlined">bolt</span>
|
249
|
+
Quick Actions
|
250
|
+
</h3>
|
251
|
+
</div>
|
252
|
+
|
253
|
+
<div class="payment-card-content space-y-3">
|
254
|
+
<button @click="refreshPayment()"
|
255
|
+
:disabled="loading"
|
256
|
+
class="btn-primary w-full">
|
257
|
+
<span x-show="!loading" class="material-icons-outlined">refresh</span>
|
258
|
+
<span x-show="loading" class="loading-spinner sm mr-2"></span>
|
259
|
+
<span x-text="loading ? 'Refreshing...' : 'Refresh Status'"></span>
|
260
|
+
</button>
|
261
|
+
|
262
|
+
<button @click="copyPaymentUrl()" class="btn-outline w-full">
|
263
|
+
<span class="material-icons-outlined">share</span>
|
264
|
+
Share Payment
|
265
|
+
</button>
|
266
|
+
|
267
|
+
<button @click="downloadReceipt()"
|
268
|
+
x-show="payment.status === 'completed' || payment.status === 'confirmed'"
|
269
|
+
class="btn-outline w-full">
|
270
|
+
<span class="material-icons-outlined">download</span>
|
271
|
+
Download Receipt
|
272
|
+
</button>
|
273
|
+
</div>
|
274
|
+
</div>
|
275
|
+
|
276
|
+
<!-- Payment QR Code -->
|
277
|
+
<div x-show="payment.qr_code_url || payment.payment_url" class="payment-card">
|
278
|
+
<div class="payment-card-header">
|
279
|
+
<h3 class="payment-card-title">
|
280
|
+
<span class="material-icons-outlined">qr_code</span>
|
281
|
+
Payment QR Code
|
282
|
+
</h3>
|
283
|
+
</div>
|
284
|
+
|
285
|
+
<div class="payment-card-content text-center">
|
286
|
+
<div class="payment-qr mb-4">
|
287
|
+
<div x-show="payment.qr_code_url" class="bg-white p-4 rounded-lg inline-block">
|
288
|
+
<img :src="payment.qr_code_url" alt="Payment QR Code" class="w-full h-auto">
|
289
|
+
</div>
|
290
|
+
<div x-show="!payment.qr_code_url" class="bg-gray-100 dark:bg-gray-700 p-8 rounded-lg">
|
291
|
+
<span class="material-icons-outlined text-gray-400 text-4xl">qr_code</span>
|
292
|
+
<p class="text-sm text-gray-500 mt-2">QR Code not available</p>
|
293
|
+
</div>
|
294
|
+
</div>
|
295
|
+
|
296
|
+
<button x-show="payment.payment_url"
|
297
|
+
@click="copyToClipboard(payment.payment_url)"
|
298
|
+
class="btn-outline w-full text-sm">
|
299
|
+
<span class="material-icons-outlined">content_copy</span>
|
300
|
+
Copy Payment URL
|
301
|
+
</button>
|
302
|
+
</div>
|
303
|
+
</div>
|
304
|
+
|
305
|
+
<!-- Auto-refresh Settings -->
|
306
|
+
<div class="payment-card">
|
307
|
+
<div class="payment-card-header">
|
308
|
+
<h3 class="payment-card-title">
|
309
|
+
<span class="material-icons-outlined">settings</span>
|
310
|
+
Auto-refresh
|
311
|
+
</h3>
|
312
|
+
</div>
|
313
|
+
|
314
|
+
<div class="payment-card-content">
|
315
|
+
<div class="flex items-center justify-between">
|
316
|
+
<span class="text-sm text-gray-600 dark:text-gray-400">Enable auto-refresh</span>
|
317
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
318
|
+
<input type="checkbox" x-model="autoRefresh" @change="toggleAutoRefresh()" class="sr-only peer">
|
319
|
+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
|
320
|
+
</label>
|
321
|
+
</div>
|
322
|
+
|
323
|
+
<div x-show="autoRefresh" class="mt-3">
|
324
|
+
<div class="flex items-center justify-between text-sm">
|
325
|
+
<span class="text-gray-600 dark:text-gray-400">Next refresh in:</span>
|
326
|
+
<span class="countdown font-mono" x-text="formatCountdown(refreshCountdown)"></span>
|
327
|
+
</div>
|
328
|
+
<div class="w-full bg-gray-200 rounded-full h-1 mt-2">
|
329
|
+
<div class="bg-blue-600 h-1 rounded-full transition-all duration-1000"
|
330
|
+
:style="`width: ${(refreshCountdown / refreshInterval) * 100}%`"></div>
|
331
|
+
</div>
|
332
|
+
</div>
|
333
|
+
</div>
|
334
|
+
</div>
|
335
|
+
|
336
|
+
<!-- Support -->
|
337
|
+
<div class="payment-card">
|
338
|
+
<div class="payment-card-header">
|
339
|
+
<h3 class="payment-card-title">
|
340
|
+
<span class="material-icons-outlined">support_agent</span>
|
341
|
+
Need Help?
|
342
|
+
</h3>
|
343
|
+
</div>
|
344
|
+
|
345
|
+
<div class="payment-card-content space-y-3">
|
346
|
+
<a href="#" class="flex items-center text-sm text-blue-600 hover:text-blue-800">
|
347
|
+
<span class="material-icons-outlined mr-2 text-sm">help</span>
|
348
|
+
Payment FAQ
|
349
|
+
</a>
|
350
|
+
<a href="#" class="flex items-center text-sm text-blue-600 hover:text-blue-800">
|
351
|
+
<span class="material-icons-outlined mr-2 text-sm">chat</span>
|
352
|
+
Contact Support
|
353
|
+
</a>
|
354
|
+
<a href="#" class="flex items-center text-sm text-blue-600 hover:text-blue-800">
|
355
|
+
<span class="material-icons-outlined mr-2 text-sm">bug_report</span>
|
356
|
+
Report Issue
|
357
|
+
</a>
|
358
|
+
</div>
|
359
|
+
</div>
|
360
|
+
</div>
|
361
|
+
</div>
|
362
|
+
</div>
|
363
|
+
{% endblock %}
|
364
|
+
|
365
|
+
{% block extra_js %}
|
366
|
+
<script>
|
367
|
+
function paymentStatus(paymentId) {
|
368
|
+
return {
|
369
|
+
payment: {
|
370
|
+
id: '{{ payment.id }}',
|
371
|
+
external_id: '{{ payment.external_id|default:"" }}',
|
372
|
+
status: '{{ payment.status }}',
|
373
|
+
status_display: '{{ payment.get_status_display }}',
|
374
|
+
amount_usd: {{ payment.amount_usd }},
|
375
|
+
currency_code: '{{ payment.currency.code }}',
|
376
|
+
provider: '{{ payment.provider }}',
|
377
|
+
created_at: '{{ payment.created_at|date:"c" }}',
|
378
|
+
updated_at: '{{ payment.updated_at|date:"c" }}',
|
379
|
+
payment_url: '{{ payment.payment_url|default:"" }}',
|
380
|
+
qr_code_url: '{{ payment.qr_code_url|default:"" }}'
|
381
|
+
},
|
382
|
+
loading: false,
|
383
|
+
autoRefresh: false,
|
384
|
+
refreshInterval: 30000, // 30 seconds
|
385
|
+
refreshCountdown: 30,
|
386
|
+
refreshTimer: null,
|
387
|
+
countdownTimer: null,
|
388
|
+
|
389
|
+
async init() {
|
390
|
+
// Auto-enable refresh for pending payments
|
391
|
+
if (this.payment.status === 'pending' || this.payment.status === 'processing') {
|
392
|
+
this.autoRefresh = true;
|
393
|
+
this.toggleAutoRefresh();
|
394
|
+
}
|
395
|
+
},
|
396
|
+
|
397
|
+
async refreshPayment() {
|
398
|
+
this.loading = true;
|
399
|
+
try {
|
400
|
+
const response = await fetch(`/payments/api/payments/${this.payment.id}/`);
|
401
|
+
const data = await response.json();
|
402
|
+
|
403
|
+
if (response.ok) {
|
404
|
+
this.payment = { ...this.payment, ...data };
|
405
|
+
PaymentSystem.Utils.showNotification('Payment status updated', 'success', 'refresh');
|
406
|
+
|
407
|
+
// Disable auto-refresh if payment is completed
|
408
|
+
if (this.payment.status === 'completed' || this.payment.status === 'failed') {
|
409
|
+
this.autoRefresh = false;
|
410
|
+
this.toggleAutoRefresh();
|
411
|
+
}
|
412
|
+
} else {
|
413
|
+
throw new Error(data.error || 'Failed to refresh payment');
|
414
|
+
}
|
415
|
+
} catch (error) {
|
416
|
+
console.error('Failed to refresh payment:', error);
|
417
|
+
PaymentSystem.Utils.showNotification('Failed to refresh payment status', 'error', 'error');
|
418
|
+
} finally {
|
419
|
+
this.loading = false;
|
420
|
+
}
|
421
|
+
},
|
422
|
+
|
423
|
+
toggleAutoRefresh() {
|
424
|
+
if (this.autoRefresh) {
|
425
|
+
this.startAutoRefresh();
|
426
|
+
} else {
|
427
|
+
this.stopAutoRefresh();
|
428
|
+
}
|
429
|
+
},
|
430
|
+
|
431
|
+
startAutoRefresh() {
|
432
|
+
this.refreshCountdown = this.refreshInterval / 1000;
|
433
|
+
|
434
|
+
this.refreshTimer = setInterval(() => {
|
435
|
+
this.refreshPayment();
|
436
|
+
this.refreshCountdown = this.refreshInterval / 1000;
|
437
|
+
}, this.refreshInterval);
|
438
|
+
|
439
|
+
this.countdownTimer = setInterval(() => {
|
440
|
+
this.refreshCountdown--;
|
441
|
+
if (this.refreshCountdown <= 0) {
|
442
|
+
this.refreshCountdown = this.refreshInterval / 1000;
|
443
|
+
}
|
444
|
+
}, 1000);
|
445
|
+
},
|
446
|
+
|
447
|
+
stopAutoRefresh() {
|
448
|
+
if (this.refreshTimer) {
|
449
|
+
clearInterval(this.refreshTimer);
|
450
|
+
this.refreshTimer = null;
|
451
|
+
}
|
452
|
+
if (this.countdownTimer) {
|
453
|
+
clearInterval(this.countdownTimer);
|
454
|
+
this.countdownTimer = null;
|
455
|
+
}
|
456
|
+
},
|
457
|
+
|
458
|
+
copyPaymentUrl() {
|
459
|
+
const url = window.location.href;
|
460
|
+
PaymentSystem.Utils.copyToClipboard(url, 'Payment URL copied to clipboard!');
|
461
|
+
},
|
462
|
+
|
463
|
+
copyToClipboard(text) {
|
464
|
+
PaymentSystem.Utils.copyToClipboard(text);
|
465
|
+
},
|
466
|
+
|
467
|
+
downloadReceipt() {
|
468
|
+
// This would generate and download a PDF receipt
|
469
|
+
PaymentSystem.Utils.showNotification('Receipt download started', 'info', 'download');
|
470
|
+
},
|
471
|
+
|
472
|
+
getStatusIndicatorClass(status) {
|
473
|
+
const statusMap = {
|
474
|
+
'completed': 'status-active',
|
475
|
+
'confirmed': 'status-active',
|
476
|
+
'pending': 'status-warning',
|
477
|
+
'processing': 'status-warning',
|
478
|
+
'failed': 'status-inactive',
|
479
|
+
'cancelled': 'status-inactive'
|
480
|
+
};
|
481
|
+
return statusMap[status] || 'status-warning';
|
482
|
+
},
|
483
|
+
|
484
|
+
getStatusBadgeClass(status) {
|
485
|
+
return PaymentSystem.Utils.getStatusBadgeClass(status);
|
486
|
+
},
|
487
|
+
|
488
|
+
formatDate(dateString) {
|
489
|
+
return PaymentSystem.Utils.formatDate(dateString);
|
490
|
+
},
|
491
|
+
|
492
|
+
formatCountdown(seconds) {
|
493
|
+
const mins = Math.floor(seconds / 60);
|
494
|
+
const secs = seconds % 60;
|
495
|
+
return `${mins}:${secs.toString().padStart(2, '0')}`;
|
496
|
+
}
|
497
|
+
}
|
498
|
+
}
|
499
|
+
</script>
|
500
|
+
{% endblock %}
|