django-cfg 1.2.29__py3-none-any.whl → 1.2.31__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/payments/admin/__init__.py +3 -2
- django_cfg/apps/payments/admin/balance_admin.py +18 -18
- django_cfg/apps/payments/admin/currencies_admin.py +319 -131
- django_cfg/apps/payments/admin/payments_admin.py +15 -4
- django_cfg/apps/payments/config/module.py +2 -2
- django_cfg/apps/payments/config/utils.py +2 -2
- django_cfg/apps/payments/decorators.py +2 -2
- django_cfg/apps/payments/management/commands/README.md +95 -127
- django_cfg/apps/payments/management/commands/currency_stats.py +5 -24
- django_cfg/apps/payments/management/commands/manage_currencies.py +229 -0
- django_cfg/apps/payments/management/commands/manage_providers.py +235 -0
- django_cfg/apps/payments/managers/__init__.py +3 -2
- django_cfg/apps/payments/managers/balance_manager.py +2 -2
- django_cfg/apps/payments/managers/currency_manager.py +272 -49
- django_cfg/apps/payments/managers/payment_manager.py +161 -13
- django_cfg/apps/payments/middleware/api_access.py +2 -2
- django_cfg/apps/payments/middleware/rate_limiting.py +8 -18
- django_cfg/apps/payments/middleware/usage_tracking.py +20 -17
- django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +241 -0
- django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +30 -0
- django_cfg/apps/payments/models/__init__.py +3 -2
- django_cfg/apps/payments/models/currencies.py +187 -71
- django_cfg/apps/payments/models/payments.py +3 -2
- django_cfg/apps/payments/serializers/__init__.py +3 -2
- django_cfg/apps/payments/serializers/currencies.py +20 -12
- django_cfg/apps/payments/services/cache/simple_cache.py +2 -2
- django_cfg/apps/payments/services/core/balance_service.py +2 -2
- django_cfg/apps/payments/services/core/fallback_service.py +2 -2
- django_cfg/apps/payments/services/core/payment_service.py +3 -6
- django_cfg/apps/payments/services/core/subscription_service.py +4 -7
- django_cfg/apps/payments/services/internal_types.py +171 -7
- django_cfg/apps/payments/services/monitoring/api_schemas.py +58 -204
- django_cfg/apps/payments/services/monitoring/provider_health.py +2 -2
- django_cfg/apps/payments/services/providers/base.py +144 -43
- django_cfg/apps/payments/services/providers/cryptapi/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/cryptapi/config.py +8 -0
- django_cfg/apps/payments/services/providers/cryptapi/models.py +192 -0
- django_cfg/apps/payments/services/providers/cryptapi/provider.py +439 -0
- django_cfg/apps/payments/services/providers/cryptomus/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/cryptomus/models.py +176 -0
- django_cfg/apps/payments/services/providers/cryptomus/provider.py +429 -0
- django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +564 -0
- django_cfg/apps/payments/services/providers/models/__init__.py +34 -0
- django_cfg/apps/payments/services/providers/models/currencies.py +190 -0
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/nowpayments/models.py +196 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +380 -0
- django_cfg/apps/payments/services/providers/registry.py +294 -11
- django_cfg/apps/payments/services/providers/stripe/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/stripe/models.py +184 -0
- django_cfg/apps/payments/services/providers/stripe/provider.py +109 -0
- django_cfg/apps/payments/services/security/error_handler.py +6 -8
- django_cfg/apps/payments/services/security/payment_notifications.py +2 -2
- django_cfg/apps/payments/services/security/webhook_validator.py +3 -4
- django_cfg/apps/payments/signals/api_key_signals.py +2 -2
- django_cfg/apps/payments/signals/payment_signals.py +11 -5
- django_cfg/apps/payments/signals/subscription_signals.py +2 -2
- django_cfg/apps/payments/tasks/webhook_processing.py +2 -2
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +50 -0
- django_cfg/apps/payments/templates/payments/base.html +4 -4
- django_cfg/apps/payments/templates/payments/components/payment_card.html +6 -6
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +4 -4
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +14 -7
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +2 -2
- django_cfg/apps/payments/templates/payments/components/status_badge.html +8 -1
- django_cfg/apps/payments/templates/payments/components/status_overview.html +34 -30
- django_cfg/apps/payments/templates/payments/dashboard.html +202 -290
- django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +35 -0
- django_cfg/apps/payments/templates/payments/payment_create.html +579 -0
- django_cfg/apps/payments/templates/payments/payment_detail.html +373 -0
- django_cfg/apps/payments/templates/payments/payment_list.html +354 -0
- django_cfg/apps/payments/templates/payments/stats.html +261 -0
- django_cfg/apps/payments/templates/payments/test.html +213 -0
- django_cfg/apps/payments/urls.py +3 -1
- django_cfg/apps/payments/{urls_templates.py → urls_admin.py} +6 -0
- django_cfg/apps/payments/utils/__init__.py +1 -3
- django_cfg/apps/payments/utils/billing_utils.py +2 -2
- django_cfg/apps/payments/utils/config_utils.py +2 -8
- django_cfg/apps/payments/utils/validation_utils.py +2 -2
- django_cfg/apps/payments/views/__init__.py +3 -2
- django_cfg/apps/payments/views/currency_views.py +31 -20
- django_cfg/apps/payments/views/payment_views.py +2 -2
- django_cfg/apps/payments/views/templates/ajax.py +141 -2
- django_cfg/apps/payments/views/templates/base.py +21 -13
- django_cfg/apps/payments/views/templates/payment_detail.py +1 -1
- django_cfg/apps/payments/views/templates/payment_management.py +34 -40
- django_cfg/apps/payments/views/templates/stats.py +8 -4
- django_cfg/apps/payments/views/webhook_views.py +2 -2
- django_cfg/apps/payments/viewsets.py +3 -2
- 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/core/config.py +35 -0
- django_cfg/models/payments.py +2 -8
- 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_unfold/dashboard.py +7 -2
- 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-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/METADATA +2 -4
- {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/RECORD +118 -96
- 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/services/providers/cryptapi.py +0 -273
- django_cfg/apps/payments/services/providers/cryptomus.py +0 -311
- django_cfg/apps/payments/services/providers/nowpayments.py +0 -293
- django_cfg/apps/payments/services/validators/__init__.py +0 -8
- django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
- django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
- {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.2.31.dist-info}/licenses/LICENSE +0 -0
@@ -3,14 +3,14 @@ Payment System Notification Service
|
|
3
3
|
Uses existing django_telegram and django_email modules for admin notifications.
|
4
4
|
"""
|
5
5
|
|
6
|
-
import
|
6
|
+
from django_cfg.modules.django_logger import get_logger
|
7
7
|
from typing import Dict, Any, Optional
|
8
8
|
from django.utils import timezone
|
9
9
|
from django_cfg.modules.django_telegram import DjangoTelegram
|
10
10
|
from django_cfg.modules.django_email import DjangoEmailService
|
11
11
|
from django_cfg.core.config import get_current_config
|
12
12
|
|
13
|
-
logger =
|
13
|
+
logger = get_logger("payment_notifications")
|
14
14
|
config = get_current_config()
|
15
15
|
|
16
16
|
|
@@ -6,7 +6,7 @@ Critical Foundation Security Component.
|
|
6
6
|
import json
|
7
7
|
import hmac
|
8
8
|
import hashlib
|
9
|
-
import
|
9
|
+
from django_cfg.modules.django_logger import get_logger
|
10
10
|
import time
|
11
11
|
from typing import Dict, Any, Optional, Tuple
|
12
12
|
from datetime import datetime, timedelta
|
@@ -16,8 +16,9 @@ from django.conf import settings
|
|
16
16
|
|
17
17
|
from django_cfg.apps.payments.config import get_payments_config
|
18
18
|
from django_cfg.apps.payments.models.events import PaymentEvent
|
19
|
+
from ...models.payments import UniversalPayment
|
19
20
|
|
20
|
-
logger =
|
21
|
+
logger = get_logger("webhook_validator")
|
21
22
|
|
22
23
|
|
23
24
|
class WebhookValidator:
|
@@ -400,8 +401,6 @@ class WebhookValidator:
|
|
400
401
|
|
401
402
|
CRITICAL: Prevents webhooks for unknown addresses.
|
402
403
|
"""
|
403
|
-
from ..models.payments import UniversalPayment
|
404
|
-
|
405
404
|
try:
|
406
405
|
# Check if address exists in our payments
|
407
406
|
return UniversalPayment.objects.filter(
|
@@ -10,12 +10,12 @@ from django.dispatch import receiver
|
|
10
10
|
from django.contrib.auth import get_user_model
|
11
11
|
from django.db import transaction
|
12
12
|
from django.utils import timezone
|
13
|
-
import
|
13
|
+
from django_cfg.modules.django_logger import get_logger
|
14
14
|
|
15
15
|
from ..models import APIKey
|
16
16
|
|
17
17
|
User = get_user_model()
|
18
|
-
logger =
|
18
|
+
logger = get_logger("api_key_signals")
|
19
19
|
|
20
20
|
|
21
21
|
@receiver(post_save, sender=User)
|
@@ -8,13 +8,13 @@ from django.db.models.signals import post_save, pre_save
|
|
8
8
|
from django.dispatch import receiver
|
9
9
|
from django.db import transaction
|
10
10
|
from django.utils import timezone
|
11
|
-
import
|
11
|
+
from django_cfg.modules.django_logger import get_logger
|
12
12
|
|
13
13
|
from ..models import UniversalPayment, UserBalance, Transaction
|
14
14
|
from ..services.cache import SimpleCache
|
15
|
-
from
|
15
|
+
from django.core.cache import cache
|
16
16
|
|
17
|
-
logger =
|
17
|
+
logger = get_logger("payment_signals")
|
18
18
|
|
19
19
|
|
20
20
|
@receiver(pre_save, sender=UniversalPayment)
|
@@ -92,8 +92,14 @@ def _process_completed_payment(payment: UniversalPayment):
|
|
92
92
|
|
93
93
|
# Clear Redis cache for user
|
94
94
|
try:
|
95
|
-
|
96
|
-
|
95
|
+
# Invalidate user cache using Django cache
|
96
|
+
user_cache_pattern = f"payments:user:{payment.user.id}:*"
|
97
|
+
# Note: Django cache doesn't support pattern deletion, so we clear specific keys
|
98
|
+
cache.delete_many([
|
99
|
+
f"payments:user:{payment.user.id}:balance",
|
100
|
+
f"payments:user:{payment.user.id}:api_keys",
|
101
|
+
f"payments:user:{payment.user.id}:subscriptions"
|
102
|
+
])
|
97
103
|
except Exception as e:
|
98
104
|
logger.warning(f"Failed to clear Redis cache for user {payment.user.id}: {e}")
|
99
105
|
|
@@ -9,12 +9,12 @@ from django.dispatch import receiver
|
|
9
9
|
from django.db import transaction
|
10
10
|
from django.utils import timezone
|
11
11
|
from datetime import timedelta
|
12
|
-
import
|
12
|
+
from django_cfg.modules.django_logger import get_logger
|
13
13
|
|
14
14
|
from ..models import Subscription, EndpointGroup, UserBalance, Transaction
|
15
15
|
from ..services.cache import SimpleCache
|
16
16
|
|
17
|
-
logger =
|
17
|
+
logger = get_logger("subscription_signals")
|
18
18
|
|
19
19
|
|
20
20
|
@receiver(pre_save, sender=Subscription)
|
@@ -5,7 +5,7 @@ Simple webhook processing with fallback to sync processing.
|
|
5
5
|
Uses existing Dramatiq configuration and graceful degradation.
|
6
6
|
"""
|
7
7
|
|
8
|
-
import
|
8
|
+
from django_cfg.modules.django_logger import get_logger
|
9
9
|
from typing import Dict, Any, Optional
|
10
10
|
from django.db import transaction
|
11
11
|
from django.utils import timezone
|
@@ -16,7 +16,7 @@ import dramatiq
|
|
16
16
|
from ..services.core.payment_service import PaymentService
|
17
17
|
from ..models.events import PaymentEvent
|
18
18
|
|
19
|
-
logger =
|
19
|
+
logger = get_logger("webhook_processing")
|
20
20
|
|
21
21
|
|
22
22
|
@dramatiq.actor(
|
@@ -0,0 +1,50 @@
|
|
1
|
+
{% extends "admin/change_list.html" %}
|
2
|
+
{% load static %}
|
3
|
+
|
4
|
+
{% block result_list %}
|
5
|
+
<!-- Currency Statistics Dashboard - Unfold Semantic Colors -->
|
6
|
+
<div class="bg-white border border-base-200 dark:bg-base-900 dark:border-base-700 p-4 rounded-default mb-4">
|
7
|
+
<h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark mb-3">📊 Currency Overview</h3>
|
8
|
+
|
9
|
+
<div class="grid grid-cols-4 gap-4 mb-4">
|
10
|
+
<div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
|
11
|
+
<p class="text-2xl font-bold text-primary-600 dark:text-primary-400">{{ total_currencies }}</p>
|
12
|
+
<p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">Total Currencies</p>
|
13
|
+
</div>
|
14
|
+
<div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
|
15
|
+
<p class="text-2xl font-bold text-success-600 dark:text-success-400">{{ enabled_provider_currencies }}</p>
|
16
|
+
<p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">Provider Mappings</p>
|
17
|
+
</div>
|
18
|
+
<div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
|
19
|
+
<p class="text-2xl font-bold text-warning-600 dark:text-warning-400">{{ currencies_with_rates }}</p>
|
20
|
+
<p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">With USD Rates</p>
|
21
|
+
</div>
|
22
|
+
<div class="text-center bg-base-50 dark:bg-base-800 p-3 rounded-default">
|
23
|
+
<p class="text-2xl font-bold text-info-600 dark:text-info-400">{{ rate_coverage|floatformat:1 }}%</p>
|
24
|
+
<p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">Rate Coverage</p>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="grid grid-cols-2 gap-4">
|
29
|
+
<div class="bg-base-50 dark:bg-base-800 p-3 rounded-default">
|
30
|
+
<h4 class="font-semibold text-font-important-light dark:text-font-important-dark mb-2">Currency Types</h4>
|
31
|
+
<ul class="text-sm space-y-1 text-font-default-light dark:text-font-default-dark">
|
32
|
+
<li>💵 Fiat: <span class="font-medium text-primary-600 dark:text-primary-400">{{ fiat_count }}</span></li>
|
33
|
+
<li>₿ Crypto: <span class="font-medium text-warning-600 dark:text-warning-400">{{ crypto_count }}</span></li>
|
34
|
+
</ul>
|
35
|
+
</div>
|
36
|
+
<div class="bg-base-50 dark:bg-base-800 p-3 rounded-default">
|
37
|
+
<h4 class="font-semibold text-font-important-light dark:text-font-important-dark mb-2">🚀 Top Supported</h4>
|
38
|
+
<ul class="text-sm space-y-1 text-font-default-light dark:text-font-default-dark">
|
39
|
+
{% for currency in top_currencies %}
|
40
|
+
<li><span class="font-semibold text-primary-600 dark:text-primary-400">{{ currency.code }}:</span> {{ currency.provider_count }} providers</li>
|
41
|
+
{% empty %}
|
42
|
+
<li class="text-font-subtle-light dark:text-font-subtle-dark">No provider data available</li>
|
43
|
+
{% endfor %}
|
44
|
+
</ul>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
{{ block.super }}
|
50
|
+
{% endblock %}
|
@@ -80,18 +80,18 @@
|
|
80
80
|
<div class="flex items-center space-x-3">
|
81
81
|
{% block header_actions %}
|
82
82
|
<a href="{% url 'payments_dashboard:list' %}"
|
83
|
-
|
83
|
+
class="inline-flex items-center px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-200">
|
84
84
|
<span class="material-icons text-sm mr-2">history</span>
|
85
85
|
Payment History
|
86
86
|
</a>
|
87
87
|
<a href="{% url 'payments_dashboard:create' %}"
|
88
|
-
class="inline-flex items-center px-3 py-2 bg-
|
88
|
+
class="inline-flex items-center px-3 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md text-sm font-medium transition-colors duration-200">
|
89
89
|
<span class="material-icons text-sm mr-2">add</span>
|
90
90
|
New Payment
|
91
91
|
</a>
|
92
92
|
<button id="theme-toggle"
|
93
|
-
class="group inline-flex items-center justify-center px-3 py-2 rounded-md bg-white dark:bg-gray-
|
94
|
-
<span class="material-icons text-gray-600 dark:text-yellow-400 group-hover:text-
|
93
|
+
class="group inline-flex items-center justify-center px-3 py-2 rounded-md bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
|
94
|
+
<span class="material-icons text-gray-600 dark:text-yellow-400 group-hover:text-blue-600 dark:group-hover:text-yellow-300 transition-colors duration-200">light_mode</span>
|
95
95
|
</button>
|
96
96
|
{% endblock %}
|
97
97
|
</div>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
{% load humanize %}
|
3
3
|
|
4
4
|
<!-- Payment Card Component -->
|
5
|
-
<div class="
|
5
|
+
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6"
|
6
6
|
data-payment-id="{{ payment.id }}">
|
7
7
|
|
8
8
|
<!-- Header -->
|
@@ -76,20 +76,20 @@
|
|
76
76
|
<!-- Actions -->
|
77
77
|
{% if show_actions %}
|
78
78
|
<div class="payment-actions mt-4 flex space-x-2">
|
79
|
-
<button class="
|
79
|
+
<button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200"
|
80
80
|
onclick="showPaymentDetails('{{ payment.id }}')">
|
81
81
|
<span class="material-icons text-sm mr-1">visibility</span>
|
82
82
|
View Details
|
83
83
|
</button>
|
84
84
|
{% if payment|can_cancel_payment %}
|
85
|
-
<button class="
|
85
|
+
<button class="px-3 py-1.5 text-xs bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 rounded-md transition-colors duration-200"
|
86
86
|
onclick="cancelPayment('{{ payment.id }}')">
|
87
87
|
<span class="material-icons text-sm mr-1">cancel</span>
|
88
88
|
Cancel
|
89
89
|
</button>
|
90
90
|
{% endif %}
|
91
91
|
{% if payment|is_crypto_payment and payment.pay_address %}
|
92
|
-
<button class="
|
92
|
+
<button class="px-3 py-1.5 text-xs bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 rounded-md transition-colors duration-200"
|
93
93
|
onclick="showQRCode('{{ payment.id }}')">
|
94
94
|
<span class="material-icons text-sm mr-1">qr_code</span>
|
95
95
|
QR Code
|
@@ -134,11 +134,11 @@
|
|
134
134
|
|
135
135
|
{% if show_actions %}
|
136
136
|
<div class="flex space-x-2">
|
137
|
-
<button class="flex-1
|
137
|
+
<button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200" onclick="showPaymentDetails('{{ payment.id }}')">
|
138
138
|
Details
|
139
139
|
</button>
|
140
140
|
{% if payment|can_cancel_payment %}
|
141
|
-
<button class="
|
141
|
+
<button class="px-3 py-1.5 text-xs bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 rounded-md transition-colors duration-200" onclick="cancelPayment('{{ payment.id }}')">
|
142
142
|
Cancel
|
143
143
|
</button>
|
144
144
|
{% endif %}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
{% load payments_tags %}
|
2
2
|
|
3
3
|
<!-- Payment QR Code Component -->
|
4
|
-
<div class="
|
4
|
+
<div class="flex flex-col items-center space-y-2 p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
|
5
5
|
{% if qr_data %}
|
6
|
-
<div class="
|
6
|
+
<div class="w-32 h-32 bg-gray-100 dark:bg-gray-700 rounded flex items-center justify-center" id="qr-code-{{ payment.id }}">
|
7
7
|
<!-- QR code will be generated here by JavaScript -->
|
8
8
|
<span class="material-icons text-gray-400 text-4xl">qr_code</span>
|
9
9
|
</div>
|
@@ -23,13 +23,13 @@
|
|
23
23
|
|
24
24
|
<!-- Action Buttons -->
|
25
25
|
<div class="flex space-x-2 pt-2">
|
26
|
-
<button class="
|
26
|
+
<button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200"
|
27
27
|
onclick="copyToClipboard('{{ payment.pay_address }}', 'Address copied!')">
|
28
28
|
<span class="material-icons text-sm mr-1">content_copy</span>
|
29
29
|
Copy Address
|
30
30
|
</button>
|
31
31
|
{% if payment.pay_amount %}
|
32
|
-
<button class="
|
32
|
+
<button class="flex-1 px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200"
|
33
33
|
onclick="copyToClipboard('{{ payment.pay_amount }}', 'Amount copied!')">
|
34
34
|
<span class="material-icons text-sm mr-1">content_copy</span>
|
35
35
|
Copy Amount
|
@@ -1,12 +1,15 @@
|
|
1
1
|
{% load payments_tags %}
|
2
2
|
|
3
3
|
<!-- Payment Progress Bar Component -->
|
4
|
-
<div
|
4
|
+
<div>
|
5
5
|
<!-- Progress Steps (Hidden on mobile) -->
|
6
|
-
<div class="
|
6
|
+
<div class="hidden md:flex justify-between items-center mb-4">
|
7
7
|
{% for step in payment|payment_progress_steps %}
|
8
|
-
<div class="
|
9
|
-
<div class="
|
8
|
+
<div class="flex flex-col items-center text-center">
|
9
|
+
<div class="w-8 h-8 flex items-center justify-center rounded-full border-2 mb-2
|
10
|
+
{% if step.completed %}border-green-500 bg-green-500 text-white
|
11
|
+
{% elif step.active %}border-blue-500 bg-blue-500 text-white
|
12
|
+
{% else %}border-gray-300 dark:border-gray-600{% endif %}">
|
10
13
|
{% if step.completed %}
|
11
14
|
<span class="material-icons text-sm">check</span>
|
12
15
|
{% elif step.active %}
|
@@ -15,14 +18,18 @@
|
|
15
18
|
<div class="w-3 h-3 bg-gray-300 rounded-full"></div>
|
16
19
|
{% endif %}
|
17
20
|
</div>
|
18
|
-
<div class="
|
21
|
+
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ step.label }}</div>
|
19
22
|
</div>
|
20
23
|
{% endfor %}
|
21
24
|
</div>
|
22
25
|
|
23
26
|
<!-- Progress Bar -->
|
24
|
-
<div class="
|
25
|
-
<div class="
|
27
|
+
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 mt-4 md:mt-0">
|
28
|
+
<div class="h-2 rounded-full transition-all duration-500 ease-out
|
29
|
+
{% if payment.status == 'completed' %}bg-green-600
|
30
|
+
{% elif payment.status == 'failed' %}bg-red-600
|
31
|
+
{% elif payment.status == 'pending' %}bg-yellow-600
|
32
|
+
{% else %}bg-blue-600{% endif %}"
|
26
33
|
style="width: {{ payment|payment_progress_percentage }}%"
|
27
34
|
data-percentage="{{ payment|payment_progress_percentage }}">
|
28
35
|
</div>
|
@@ -1,11 +1,11 @@
|
|
1
1
|
{% load payments_tags %}
|
2
2
|
|
3
3
|
<!-- Provider Statistics Component -->
|
4
|
-
<div class="
|
4
|
+
<div class="space-y-4">
|
5
5
|
{% for stat in provider_stats %}
|
6
6
|
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700 rounded-lg">
|
7
7
|
<div class="flex items-center space-x-3">
|
8
|
-
<div class="provider-
|
8
|
+
<div class="w-6 h-6 rounded {% if stat.provider == 'nowpayments' %}bg-orange-500{% elif stat.provider == 'cryptapi' %}bg-blue-500{% elif stat.provider == 'cryptomus' %}bg-purple-500{% elif stat.provider == 'stripe' %}bg-indigo-500{% else %}bg-gray-500{% endif %} flex items-center justify-center">
|
9
9
|
<span class="material-icons text-white text-sm">{{ stat.provider|payment_method_icon }}</span>
|
10
10
|
</div>
|
11
11
|
<div>
|
@@ -1,7 +1,14 @@
|
|
1
1
|
{% load payments_tags %}
|
2
2
|
|
3
3
|
<!-- Payment Status Badge Component -->
|
4
|
-
<span class="
|
4
|
+
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
5
|
+
{% if payment.status == 'pending' %}bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200
|
6
|
+
{% elif payment.status == 'confirming' %}bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
|
7
|
+
{% elif payment.status == 'confirmed' or payment.status == 'completed' %}bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200
|
8
|
+
{% elif payment.status == 'failed' %}bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200
|
9
|
+
{% elif payment.status == 'expired' or payment.status == 'cancelled' %}bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200
|
10
|
+
{% elif payment.status == 'refunded' %}bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200
|
11
|
+
{% else %}bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200{% endif %}"
|
5
12
|
data-status="{{ payment.status }}">
|
6
13
|
{% if payment.status == 'pending' %}
|
7
14
|
<span class="material-icons text-sm mr-1 animate-pulse">pending</span>
|
@@ -1,11 +1,13 @@
|
|
1
1
|
{% load payments_tags %}
|
2
2
|
|
3
3
|
<!-- Status Overview Cards -->
|
4
|
-
{%
|
4
|
+
{% if not payment_stats %}
|
5
|
+
{% get_payment_stats as payment_stats %}
|
6
|
+
{% endif %}
|
5
7
|
|
6
|
-
<div class="
|
7
|
-
|
8
|
-
|
8
|
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
9
|
+
<!-- Total Payments -->
|
10
|
+
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
9
11
|
<div class="flex items-center">
|
10
12
|
<div class="flex-shrink-0">
|
11
13
|
<span class="material-icons text-blue-600 dark:text-blue-400 text-3xl">payments</span>
|
@@ -13,14 +15,14 @@
|
|
13
15
|
<div class="ml-4">
|
14
16
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Total Payments</p>
|
15
17
|
<p class="text-2xl font-bold text-gray-900 dark:text-white">
|
16
|
-
{{
|
18
|
+
{{ payment_payment_stats.total_payments_count|default:0 }}
|
17
19
|
</p>
|
18
20
|
</div>
|
19
21
|
</div>
|
20
22
|
</div>
|
21
23
|
|
22
24
|
<!-- Pending Payments -->
|
23
|
-
|
25
|
+
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
24
26
|
<div class="flex items-center">
|
25
27
|
<div class="flex-shrink-0">
|
26
28
|
<span class="material-icons text-yellow-600 dark:text-yellow-400 text-3xl">pending</span>
|
@@ -28,11 +30,11 @@
|
|
28
30
|
<div class="ml-4">
|
29
31
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Pending</p>
|
30
32
|
<p class="text-2xl font-bold text-gray-900 dark:text-white">
|
31
|
-
{{
|
33
|
+
{{ payment_payment_stats.pending_payments_count|default:0 }}
|
32
34
|
</p>
|
33
|
-
{% if
|
35
|
+
{% if payment_payment_stats.confirming_payments_count %}
|
34
36
|
<p class="text-xs text-gray-500 dark:text-gray-400">
|
35
|
-
+{{
|
37
|
+
+{{ payment_payment_stats.confirming_payments_count }} confirming
|
36
38
|
</p>
|
37
39
|
{% endif %}
|
38
40
|
</div>
|
@@ -40,7 +42,7 @@
|
|
40
42
|
</div>
|
41
43
|
|
42
44
|
<!-- Completed Payments -->
|
43
|
-
|
45
|
+
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
44
46
|
<div class="flex items-center">
|
45
47
|
<div class="flex-shrink-0">
|
46
48
|
<span class="material-icons text-green-600 dark:text-green-400 text-3xl">check_circle</span>
|
@@ -48,11 +50,11 @@
|
|
48
50
|
<div class="ml-4">
|
49
51
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Completed</p>
|
50
52
|
<p class="text-2xl font-bold text-gray-900 dark:text-white">
|
51
|
-
{{
|
53
|
+
{{ payment_stats.completed_payments_count|default:0 }}
|
52
54
|
</p>
|
53
|
-
{% if
|
55
|
+
{% if payment_stats.total_payments_count > 0 %}
|
54
56
|
<p class="text-xs text-green-600 dark:text-green-400">
|
55
|
-
{{
|
57
|
+
{{ payment_stats.completed_payments_count|floatformat:0 }}/{{ payment_stats.total_payments_count }} success
|
56
58
|
</p>
|
57
59
|
{% endif %}
|
58
60
|
</div>
|
@@ -60,7 +62,7 @@
|
|
60
62
|
</div>
|
61
63
|
|
62
64
|
<!-- Total Volume -->
|
63
|
-
|
65
|
+
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
64
66
|
<div class="flex items-center">
|
65
67
|
<div class="flex-shrink-0">
|
66
68
|
<span class="material-icons text-purple-600 dark:text-purple-400 text-3xl">account_balance</span>
|
@@ -68,11 +70,11 @@
|
|
68
70
|
<div class="ml-4">
|
69
71
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Total Volume</p>
|
70
72
|
<p class="text-2xl font-bold text-gray-900 dark:text-white">
|
71
|
-
${{
|
73
|
+
${{ payment_stats.total_volume|floatformat:2|default:"0.00" }}
|
72
74
|
</p>
|
73
|
-
{% if
|
75
|
+
{% if payment_stats.failed_payments_count %}
|
74
76
|
<p class="text-xs text-red-500 dark:text-red-400">
|
75
|
-
{{
|
77
|
+
{{ payment_stats.failed_payments_count }} failed
|
76
78
|
</p>
|
77
79
|
{% endif %}
|
78
80
|
</div>
|
@@ -86,24 +88,25 @@
|
|
86
88
|
<div class="flex items-center space-x-4">
|
87
89
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Quick Actions:</span>
|
88
90
|
<div class="flex space-x-2">
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
91
|
+
<button class="px-3 py-1.5 text-xs bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 rounded-md transition-colors duration-200" onclick="createNewPayment()">
|
92
|
+
<span class="material-icons text-sm mr-1">add</span>
|
93
|
+
New Payment
|
94
|
+
</button>
|
95
|
+
<button class="px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200" onclick="refreshPayments()">
|
96
|
+
<span class="material-icons text-sm mr-1">refresh</span>
|
97
|
+
Refresh
|
98
|
+
</button>
|
99
|
+
<button class="px-3 py-1.5 text-xs border border-gray-300 dark:border-gray-500 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 rounded-md transition-colors duration-200" onclick="exportPayments()">
|
100
|
+
<span class="material-icons text-sm mr-1">download</span>
|
101
|
+
Export
|
102
|
+
</button>
|
101
103
|
</div>
|
102
104
|
</div>
|
103
105
|
|
104
106
|
<!-- Live Status Indicator -->
|
105
107
|
<div class="flex items-center space-x-2">
|
106
|
-
<div class="
|
108
|
+
<div class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
|
109
|
+
<div class="w-2 h-2 bg-green-500 rounded-full mr-2 animate-pulse"></div>
|
107
110
|
Live Updates
|
108
111
|
</div>
|
109
112
|
<span class="text-xs text-gray-500 dark:text-gray-400">
|
@@ -142,3 +145,4 @@ function updateStatsLastUpdate() {
|
|
142
145
|
}
|
143
146
|
}
|
144
147
|
</script>
|
148
|
+
|