856 lines
49 KiB
PHP
856 lines
49 KiB
PHP
<?php
|
||
require_once __DIR__ . '/db/config.php';
|
||
require_once __DIR__ . '/includes/lang.php';
|
||
if (session_status() === PHP_SESSION_NONE) session_start();
|
||
|
||
$user = null;
|
||
if (isset($_SESSION['user_id'])) {
|
||
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$user = $stmt->fetch();
|
||
}
|
||
|
||
if (!$user) {
|
||
header('Location: /auth/login.php');
|
||
exit;
|
||
}
|
||
|
||
require_once __DIR__ . '/includes/header.php';
|
||
require_once __DIR__ . '/includes/exchange.php';
|
||
|
||
// Fetch rates
|
||
$rates = get_exchange_rates();
|
||
|
||
// Fetch settings
|
||
$stmt = db()->query("SELECT setting_key, setting_value FROM system_settings");
|
||
$settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
|
||
|
||
$trc20_addr = $settings['usdt_trc20_address'] ?? 'TYv9V5J1P1eEwz7y3WqJg9M2yv7f7xXv3x';
|
||
$erc20_addr = $settings['usdt_erc20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
|
||
$bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
|
||
?>
|
||
|
||
<div class="container py-4">
|
||
<div class="row justify-content-center">
|
||
<div class="col-lg-8">
|
||
<!-- Back Button -->
|
||
<div class="mb-4">
|
||
<a href="javascript:history.back()" class="text-white-50 text-decoration-none d-inline-flex align-items-center gap-2">
|
||
<i class="bi bi-arrow-left fs-4"></i>
|
||
<span><?= __('back') ?></span>
|
||
</a>
|
||
</div>
|
||
|
||
<div class="card bg-surface border-secondary rounded-4 shadow-lg overflow-hidden mb-4">
|
||
<div class="card-header border-secondary bg-black bg-opacity-30 p-4">
|
||
<h4 class="mb-0 fw-bold d-flex align-items-center gap-3 text-white">
|
||
<i class="bi bi-wallet2 text-primary"></i>
|
||
<?= __('recharge') ?>
|
||
</h4>
|
||
</div>
|
||
|
||
<div class="card-body p-4">
|
||
<!-- Tabs -->
|
||
<ul class="nav nav-pills nav-fill mb-4 bg-black p-1 rounded-pill" id="rechargeTabs" role="tablist">
|
||
<li class="nav-item" role="presentation">
|
||
<button class="nav-link active rounded-pill px-4" id="fiat-tab" data-bs-toggle="pill" data-bs-target="#fiat" type="button" role="tab"><?= __('fiat_recharge') ?></button>
|
||
</li>
|
||
<li class="nav-item" role="presentation">
|
||
<button class="nav-link rounded-pill px-4" id="crypto-tab" data-bs-toggle="pill" data-bs-target="#crypto" type="button" role="tab"><?= __('crypto_recharge') ?></button>
|
||
</li>
|
||
</ul>
|
||
|
||
<div class="tab-content" id="rechargeTabsContent">
|
||
<!-- Fiat Recharge -->
|
||
<div class="tab-pane fade show active" id="fiat" role="tabpanel">
|
||
<form id="fiatRechargeForm">
|
||
<div class="mb-4">
|
||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('select_currency') ?></label>
|
||
<select class="form-select bg-dark border-secondary text-white py-3" id="fiatCurrency" onchange="updateRate()">
|
||
<?php
|
||
$currencies = get_global_currencies();
|
||
foreach ($currencies as $code => $info) {
|
||
$rate = $rates[$code] ?? 1.0;
|
||
echo "<option value=\"$code\" data-rate=\"$rate\">{$info['flag']} $code - {$info['name']}</option>";
|
||
}
|
||
?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('fiat_amount') ?></label>
|
||
<div class="input-group">
|
||
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="fiatAmount" placeholder="0.00" oninput="calculateUSDT()">
|
||
<span class="input-group-text bg-dark border-secondary text-white-50 fw-bold" id="selectedCurrencyLabel">USD</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-5 p-4 bg-primary bg-opacity-10 border border-primary border-opacity-20 rounded-4">
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<span class="text-white-50"><?= __('est_usdt') ?></span>
|
||
<span class="h4 mb-0 fw-bold text-primary" id="estUsdt">0.00 USDT</span>
|
||
</div>
|
||
<div class="mt-2 small text-white-50">
|
||
<i class="bi bi-info-circle me-1"></i>
|
||
<?= __('rate') ?>: 1 USDT ≈ <span id="currentRateText" class="text-white">1.00 USD</span>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="button" class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-lg" onclick="confirmFiatOrder(this, event)">
|
||
<?= __('confirm_order') ?>
|
||
</button>
|
||
</form>
|
||
|
||
<div class="mt-5 p-4 bg-black bg-opacity-20 rounded-4 border border-secondary border-opacity-50">
|
||
<h6 class="text-white fw-bold mb-3 d-flex align-items-center gap-2">
|
||
<i class="bi bi-info-circle text-info"></i> <?= __('recharge_steps') ?>
|
||
</h6>
|
||
<ul class="text-white-50 small mb-0 ps-3">
|
||
<li class="mb-2"><?= __('recharge_step1') ?></li>
|
||
<li class="mb-2"><?= __('recharge_step2') ?></li>
|
||
<li class="mb-2"><?= __('recharge_step3') ?></li>
|
||
<li><?= __('recharge_step4') ?></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="bg-black bg-opacity-20 rounded-4 p-4 mt-4 border border-secondary border-opacity-50">
|
||
<h6 class="text-white fw-bold mb-3 d-flex align-items-center gap-2">
|
||
<i class="bi bi-shield-check text-warning"></i> <?= __('security_tips') ?>
|
||
</h6>
|
||
<ul class="text-white-50 small mb-0 ps-3">
|
||
<li class="mb-2"><?= __('recharge_tip1') ?></li>
|
||
<li class="mb-2"><?= __('recharge_tip2') ?></li>
|
||
<li><?= __('recharge_tip3') ?></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Crypto Recharge -->
|
||
<div class="tab-pane fade" id="crypto" role="tabpanel">
|
||
<div class="mb-4">
|
||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('coin') ?></label>
|
||
<div class="d-flex align-items-center gap-3 p-3 bg-dark border border-secondary rounded-4">
|
||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT" onerror="handleIconError(this, 'USDT')">
|
||
<div>
|
||
<div class="fw-bold text-white"><?= $lang === 'zh' ? __('USDT') : 'USDT' ?></div>
|
||
<div class="text-white-50 small"><?= __('tether') ?></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('select_network') ?></label>
|
||
<div class="d-flex gap-2" id="networkSelectors">
|
||
<button type="button" class="btn btn-outline-primary active flex-fill py-2 rounded-3" onclick="selectNetwork('TRC20', '<?= $trc20_addr ?>')">TRC20</button>
|
||
<button type="button" class="btn btn-outline-secondary flex-fill py-2 rounded-3" onclick="selectNetwork('ERC20', '<?= $erc20_addr ?>')">ERC20</button>
|
||
<button type="button" class="btn btn-outline-secondary flex-fill py-2 rounded-3" onclick="selectNetwork('BEP20', '<?= $bep20_addr ?>')">BEP20</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('recharge_amount') ?></label>
|
||
<div class="input-group">
|
||
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="cryptoAmount" placeholder="0.00">
|
||
<span class="input-group-text bg-dark border-secondary text-white-50 fw-bold">USDT</span>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="button" class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-lg" onclick="confirmCryptoOrder(this, event)">
|
||
<?= __('confirm_order') ?>
|
||
</button>
|
||
|
||
<div class="mt-5 p-4 bg-black bg-opacity-20 rounded-4 border border-secondary border-opacity-50">
|
||
<h6 class="text-white fw-bold mb-3 d-flex align-items-center gap-2">
|
||
<i class="bi bi-info-circle text-info"></i> <?= __('recharge_steps') ?>
|
||
</h6>
|
||
<ul class="text-white-50 small mb-0 ps-3">
|
||
<li class="mb-2"><?= __('recharge_step1') ?></li>
|
||
<li class="mb-2"><?= __('recharge_step2') ?></li>
|
||
<li class="mb-2"><?= __('recharge_step3') ?></li>
|
||
<li><?= __('recharge_step4') ?></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="cryptoAddressContainer" style="display:none;">
|
||
<input type="text" id="cryptoAddress">
|
||
<img id="qrCode">
|
||
</div>
|
||
|
||
<style>
|
||
@media (max-width: 768px) {
|
||
.container { padding-left: 10px !important; padding-right: 10px !important; }
|
||
.card-body { padding: 1.25rem !important; }
|
||
.nav-pills .nav-link { padding: 10px 15px !important; font-size: 13px; }
|
||
.h4 { font-size: 1.25rem !important; }
|
||
}
|
||
</style>
|
||
|
||
<!-- Recharge Confirmation Modal -->
|
||
<div class="modal fade" id="rechargeModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1">
|
||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||
<div class="modal-content border-0 shadow-lg overflow-hidden" style="border-radius: 24px; background: #ffffff;">
|
||
<div class="modal-body p-0">
|
||
<div class="row g-0">
|
||
<!-- Left Side: Online Service (REMOVED) -->
|
||
|
||
<!-- Right Side: Account Matching -->
|
||
<div class="col-lg-12 p-4 p-lg-5 d-flex flex-column justify-content-center info-side position-relative overflow-hidden" style="background: #fff; border-radius: 24px;">
|
||
<div class="text-center text-lg-start position-relative" style="z-index: 2;">
|
||
<div class="mb-4 text-center">
|
||
<button type="button" class="btn-close position-absolute top-0 end-0 m-3 shadow-none" data-bs-dismiss="modal"></button>
|
||
<div class="d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill bg-primary bg-opacity-10 text-primary small fw-bold mb-3 border border-primary border-opacity-10" style="color: #ff4d94 !important; border-color: #ff4d94 !important;">
|
||
<span class="pulse-dot-pink"></span> <span style="letter-spacing: 1px;"><?= __('waiting_allocation') ?></span>
|
||
</div>
|
||
<h2 class="fw-bold text-dark mb-3" style="font-size: 2rem;"><?= __('matching_account') ?></h2>
|
||
<p class="text-muted fw-medium mb-0" style="font-size: 15px;">
|
||
<?= __('matching_desc') ?>
|
||
</p>
|
||
</div>
|
||
|
||
<div class="mb-4 py-4 px-4 rounded-4 border border-light shadow-sm" style="background: #fff0f5;">
|
||
<div class="row align-items-center text-center">
|
||
<div class="col-12 mb-3">
|
||
<div class="text-muted small mb-1 fw-bold"><?= __('waiting_countdown') ?></div>
|
||
<div class="display-5 fw-bold text-primary mb-0" id="modal-countdown" style="font-family: 'Monaco', 'Consolas', monospace; color: #ff4d94 !important;">30:00</div>
|
||
</div>
|
||
<div class="col-12 border-top border-white pt-3">
|
||
<div class="text-muted small mb-2 fw-bold"><?= __('secure_channel') ?></div>
|
||
<div class="d-flex justify-content-center gap-1">
|
||
<div class="rounded-pill" style="width: 25px; height: 6px; background: #ff4d94;"></div>
|
||
<div class="rounded-pill" style="width: 25px; height: 6px; background: #ff4d94;"></div>
|
||
<div class="rounded-pill" style="width: 25px; height: 6px; background: #ff4d94;"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="p-4 rounded-4 bg-light border border-light">
|
||
<h6 class="text-dark fw-bold mb-3 d-flex align-items-center gap-2">
|
||
<i class="bi bi-shield-lock-fill text-primary fs-5" style="color: #ff4d94 !important;"></i> <?= __('security_tips') ?>
|
||
</h6>
|
||
<div class="text-muted small lh-lg">
|
||
<div class="mb-2 d-flex gap-2">
|
||
<i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i>
|
||
<span><?= __('recharge_instruction_1') ?></span>
|
||
</div>
|
||
<div class="mb-2 d-flex gap-2">
|
||
<i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i>
|
||
<span><?= __('recharge_instruction_2') ?></span>
|
||
</div>
|
||
<div class="d-flex gap-2">
|
||
<i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i>
|
||
<span><?= __('recharge_instruction_3') ?></span>
|
||
</div>
|
||
</div>
|
||
<div class="mt-4">
|
||
<button type="button" class="btn btn-primary w-100 rounded-pill py-2 fw-bold opacity-50" disabled style="background: #ff4d94 !important; border: none;">
|
||
<?= __('waiting_system_allocation') ?>...
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.pulse-dot-pink {
|
||
width: 8px;
|
||
height: 8px;
|
||
background-color: #ff4d94;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
animation: dot-pulse-pink 1.5s infinite;
|
||
}
|
||
@keyframes dot-pulse-pink {
|
||
0% { transform: scale(0.95); opacity: 0.6; }
|
||
50% { transform: scale(1.3); opacity: 1; }
|
||
100% { transform: scale(0.95); opacity: 0.6; }
|
||
}
|
||
#modal-chat-messages::-webkit-scrollbar { width: 4px; }
|
||
#modal-chat-messages::-webkit-scrollbar-track { background: transparent; }
|
||
#modal-chat-messages::-webkit-scrollbar-thumb { background: #ff4d9422; border-radius: 10px; }
|
||
.msg-bubble { box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
|
||
@media (max-width: 992px) {
|
||
.chat-column { display: none !important; }
|
||
.info-side { width: 100% !important; border-radius: 24px !important; }
|
||
}
|
||
</style>
|
||
|
||
<style>
|
||
.vibrancy-bg {
|
||
background: linear-gradient(135deg, #1e1e1e 0%, #ff4d94 40%, #ff80ab 70%, #f48fb1 100%);
|
||
background-size: 400% 400%;
|
||
animation: gradientFlow 6s ease-in-out infinite;
|
||
}
|
||
@keyframes gradientFlow {
|
||
0% { background-position: 0% 50%; }
|
||
50% { background-position: 100% 50%; }
|
||
100% { background-position: 0% 50%; }
|
||
}
|
||
.text-shadow-ultra {
|
||
text-shadow: 0 0 10px rgba(0,0,0,0.8), 0 0 20px rgba(255,77,148,0.5), 0 4px 12px rgba(0,0,0,0.9);
|
||
letter-spacing: 0.5px;
|
||
}
|
||
.text-shadow-heavy {
|
||
text-shadow: 2px 2px 10px rgba(0,0,0,0.9), 0 0 5px rgba(0,0,0,0.7);
|
||
font-weight: 800 !important;
|
||
}
|
||
.text-shadow-medium {
|
||
text-shadow: 1px 1px 5px rgba(0,0,0,0.8);
|
||
font-weight: 600 !important;
|
||
}
|
||
.text-shadow-glow {
|
||
text-shadow: 0 0 20px rgba(255,77,148,0.7), 0 0 10px rgba(255,77,148,0.4), 2px 2px 4px rgba(0,0,0,0.9);
|
||
}
|
||
.text-shadow-glow-sm {
|
||
text-shadow: 0 0 10px rgba(255,77,148,0.7), 1px 1px 3px rgba(0,0,0,0.9);
|
||
}
|
||
.shadow-glow-green { box-shadow: 0 0 25px rgba(255,77,148,0.5); }
|
||
.shadow-2xl { box-shadow: 0 25px 60px -15px rgba(0, 0, 0, 0.8); }
|
||
|
||
.payment-item .h5, .payment-item .h4 {
|
||
letter-spacing: 0.5px;
|
||
}
|
||
|
||
.payment-item .btn-light {
|
||
background: rgba(255,255,255,0.9);
|
||
border: none;
|
||
color: #ff4d94;
|
||
}
|
||
.payment-item .btn-light:hover {
|
||
background: #ffffff;
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
.hover-scale-sm:hover { transform: translateX(5px); background: rgba(0,0,0,0.4) !important; }
|
||
|
||
.pulse-dot-white {
|
||
width: 8px;
|
||
height: 8px;
|
||
background-color: #fff;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
animation: dot-pulse-white 1.5s infinite;
|
||
box-shadow: 0 0 8px rgba(255,255,255,0.8);
|
||
}
|
||
@keyframes dot-pulse-white {
|
||
0% { transform: scale(0.95); opacity: 0.6; }
|
||
50% { transform: scale(1.3); opacity: 1; }
|
||
100% { transform: scale(0.95); opacity: 0.6; }
|
||
}
|
||
|
||
#modal-chat-messages::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
#modal-chat-messages::-webkit-scrollbar-track {
|
||
background: transparent;
|
||
}
|
||
#modal-chat-messages::-webkit-scrollbar-thumb {
|
||
background: rgba(255,77,148,0.3);
|
||
border-radius: 10px;
|
||
}
|
||
#modal-chat-messages::-webkit-scrollbar-thumb:hover {
|
||
background: rgba(255,77,148,0.5);
|
||
}
|
||
.modal-msg .msg-bubble {
|
||
backdrop-filter: blur(5px);
|
||
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
||
}
|
||
@media (max-width: 992px) {
|
||
.chat-column { display: none !important; }
|
||
.info-side {
|
||
width: 100% !important;
|
||
min-height: 100vh !important;
|
||
border-radius: 24px !important;
|
||
}
|
||
.modal-dialog { margin: 0; }
|
||
.modal-content { border-radius: 0; height: 100vh; }
|
||
}
|
||
|
||
/* Premium Desktop Styling */
|
||
.modal-content {
|
||
box-shadow: 0 10px 40px rgba(0,0,0,0.1), 0 0 20px rgba(255,77,148,0.1) !important;
|
||
background: #ffffff !important;
|
||
border: 1px solid #ff4d9422 !important;
|
||
border-radius: 30px !important;
|
||
}
|
||
.chat-column {
|
||
background: #fff0f5 !important;
|
||
}
|
||
.msg-bubble.bg-primary {
|
||
background: #ff4d94 !important;
|
||
}
|
||
.btn-primary {
|
||
background: #ff4d94 !important;
|
||
border: none !important;
|
||
box-shadow: 0 4px 12px rgba(255, 77, 148, 0.2) !important;
|
||
}
|
||
.text-primary {
|
||
color: #ff4d94 !important;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
let currentNetwork = 'TRC20';
|
||
let currentAddress = '<?= $trc20_addr ?>';
|
||
const userId = '<?= $user['uid'] ?? $user['id'] ?>';
|
||
const apiPath = (window.location.origin + window.location.pathname).split('/recharge.php')[0] + '/api/';
|
||
let rechargeCountdownInterval;
|
||
let modalChatLastIds = new Set();
|
||
let remainingSeconds = 1800;
|
||
let modalChatPolling = false;
|
||
|
||
function notify(icon, title, text = '') {
|
||
return Swal.fire({
|
||
icon: icon,
|
||
title: title,
|
||
text: text,
|
||
background: '#1e2329',
|
||
color: '#fff',
|
||
confirmButtonColor: '#0062ff',
|
||
confirmButtonText: '<?= __("confirm") ?>'
|
||
});
|
||
}
|
||
|
||
let exchangeRates = {};
|
||
|
||
async function updateRate() {
|
||
const select = document.getElementById('fiatCurrency');
|
||
const symbol = select.value;
|
||
|
||
// Try to get fresh rates
|
||
try {
|
||
const resp = await fetch(apiPath + 'exchange.php?v=' + Date.now());
|
||
const data = await resp.json();
|
||
if (data.success && data.rates) {
|
||
exchangeRates = data.rates;
|
||
}
|
||
} catch (e) {
|
||
console.error('Failed to fetch real-time rates:', e);
|
||
}
|
||
|
||
const rate = exchangeRates[symbol] || parseFloat(select.options[select.selectedIndex].getAttribute('data-rate'));
|
||
|
||
document.getElementById('selectedCurrencyLabel').innerText = symbol;
|
||
document.getElementById('currentRateText').innerText = `${rate.toFixed(4)} ${symbol}`;
|
||
|
||
// Update the data-rate attribute so calculateUSDT can use it too
|
||
select.options[select.selectedIndex].setAttribute('data-rate', rate);
|
||
|
||
calculateUSDT();
|
||
}
|
||
|
||
function calculateUSDT() {
|
||
const amount = parseFloat(document.getElementById('fiatAmount').value) || 0;
|
||
const select = document.getElementById('fiatCurrency');
|
||
const rate = parseFloat(select.options[select.selectedIndex].getAttribute('data-rate'));
|
||
const est = amount / rate;
|
||
document.getElementById('estUsdt').innerText = est.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' USDT';
|
||
}
|
||
|
||
function selectNetwork(net, addr) {
|
||
currentNetwork = net;
|
||
currentAddress = addr;
|
||
const btns = document.querySelectorAll('#networkSelectors button');
|
||
btns.forEach(btn => {
|
||
if (btn.innerText === net) {
|
||
btn.classList.add('active', 'btn-outline-primary');
|
||
btn.classList.remove('btn-outline-secondary');
|
||
} else {
|
||
btn.classList.remove('active', 'btn-outline-primary');
|
||
btn.classList.add('btn-outline-secondary');
|
||
}
|
||
});
|
||
document.getElementById('cryptoAddress').value = addr;
|
||
document.getElementById('qrCode').src = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${addr}`;
|
||
}
|
||
|
||
function saveRechargeState(state) {
|
||
localStorage.setItem('recharge_state', JSON.stringify({
|
||
...state,
|
||
timestamp: Date.now(),
|
||
remainingSeconds: remainingSeconds
|
||
}));
|
||
}
|
||
|
||
function clearRechargeState() {
|
||
localStorage.removeItem('recharge_state');
|
||
if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval);
|
||
if (window.statusPollingInterval) clearInterval(window.statusPollingInterval);
|
||
}
|
||
|
||
function finishTransfer() {
|
||
const state = JSON.parse(localStorage.getItem('recharge_state') || '{}');
|
||
const orderId = state.orderId;
|
||
if (orderId) {
|
||
const formData = new FormData();
|
||
formData.append('action', 'complete_transfer');
|
||
formData.append('order_id', orderId);
|
||
fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData })
|
||
.then(r => r.json())
|
||
.then(data => { if (data.success) renderRechargeUI({status: 'finished'}); });
|
||
} else {
|
||
notify('warning', '订单信息丢失,请刷新页面');
|
||
}
|
||
}
|
||
|
||
function finishTransferUI() {
|
||
clearRechargeState();
|
||
const modalEl = document.getElementById('rechargeModal');
|
||
const modalInstance = bootstrap.Modal.getInstance(modalEl);
|
||
if (modalInstance) modalInstance.hide();
|
||
notify('success', '<?= __("recharge_success_title") ?>', '<?= __("recharge_success_text") ?>');
|
||
}
|
||
|
||
function openRechargeModal(initialMessage, isRestore = false, orderId = null) {
|
||
const modalElement = document.getElementById('rechargeModal');
|
||
if (!modalElement) return;
|
||
const modal = new bootstrap.Modal(modalElement);
|
||
modal.show();
|
||
|
||
const currentOrderId = orderId || JSON.parse(localStorage.getItem('recharge_state') || '{}').orderId;
|
||
|
||
if (!isRestore) {
|
||
remainingSeconds = 1800;
|
||
saveRechargeState({ phase: 'pending', initialMessage, orderId: currentOrderId });
|
||
sendModalMessage(initialMessage); // Automatically notify admin about the new recharge request
|
||
}
|
||
|
||
if (currentOrderId) startStatusPolling(currentOrderId);
|
||
|
||
if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval);
|
||
rechargeCountdownInterval = setInterval(() => {
|
||
const display = document.querySelectorAll('#modal-countdown');
|
||
let mins = Math.floor(remainingSeconds / 60);
|
||
let secs = remainingSeconds % 60;
|
||
const timeStr = `${mins}:${secs < 10 ? '0' : ''}${secs}`;
|
||
display.forEach(d => d.innerText = timeStr);
|
||
|
||
const state = JSON.parse(localStorage.getItem('recharge_state') || '{}');
|
||
state.remainingSeconds = remainingSeconds;
|
||
localStorage.setItem('recharge_state', JSON.stringify(state));
|
||
if (--remainingSeconds < 0) clearInterval(rechargeCountdownInterval);
|
||
}, 1000);
|
||
|
||
if (!isRestore) renderRechargeUI({ status: 'pending' });
|
||
initModalChat();
|
||
}
|
||
|
||
function startStatusPolling(order_id) {
|
||
if (window.statusPollingInterval) clearInterval(window.statusPollingInterval);
|
||
const checkStatus = async () => {
|
||
const modalEl = document.getElementById('rechargeModal');
|
||
if (!modalEl || !modalEl.classList.contains('show')) return;
|
||
try {
|
||
const r = await fetch(apiPath + `recharge_status.php?id=${order_id}&v=${Date.now()}`);
|
||
const data = await r.json();
|
||
if (data.success) {
|
||
console.log('Order status update:', data.status, data);
|
||
// Ensure data status is treated as string for comparison
|
||
const currentStatus = String(data.status);
|
||
renderRechargeUI(data);
|
||
if (currentStatus === '3') clearInterval(window.statusPollingInterval);
|
||
}
|
||
} catch (e) { console.error('Status polling error:', e); }
|
||
};
|
||
checkStatus();
|
||
window.statusPollingInterval = setInterval(checkStatus, 3000);
|
||
}
|
||
|
||
function renderRechargeUI(data) {
|
||
const side = document.querySelector('.info-side');
|
||
if (!side) return;
|
||
const status = data.status;
|
||
if (status === '3') { finishTransferUI(); return; }
|
||
|
||
if (status === 'pending' || status === '0') {
|
||
side.innerHTML = `
|
||
<div class="text-center text-lg-start position-relative" style="z-index: 2;">
|
||
<div class="mb-4 text-center">
|
||
<div class="d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill bg-primary bg-opacity-10 text-primary small fw-bold mb-3 border border-primary border-opacity-10" style="color: #ff4d94 !important; border-color: #ff4d94 !important;">
|
||
<span class="pulse-dot-pink"></span> <span style="letter-spacing: 1px;">正在为您匹配充值账户</span>
|
||
</div>
|
||
<h2 class="fw-bold text-dark mb-3" style="font-size: 2rem;">正在为您匹配充值账户</h2>
|
||
<p class="text-muted fw-medium mb-0" style="font-size: 15px;">系统正在为您分配专属收款账户,请耐心等待。<br>匹配成功后,页面将自动更新收款信息。<br>请勿关闭当前页面。</p>
|
||
</div>
|
||
<div class="mb-4 py-4 px-4 rounded-4 border border-light shadow-sm" style="background: #fff0f5;">
|
||
<div class="row align-items-center text-center">
|
||
<div class="col-12 mb-3">
|
||
<div class="text-muted small mb-1 fw-bold"><?= __('waiting_countdown') ?></div>
|
||
<div class="display-5 fw-bold text-primary mb-0" id="modal-countdown" style="font-family: monospace; color: #ff4d94 !important;">30:00</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="p-4 rounded-4 bg-light border border-light">
|
||
<h6 class="text-dark fw-bold mb-3 d-flex align-items-center gap-2"><i class="bi bi-shield-lock-fill text-primary" style="color: #ff4d94 !important;"></i> <?= __('security_tips') ?></h6>
|
||
<div class="text-muted small lh-lg">
|
||
<div class="mb-2 d-flex gap-2"><i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i> <span><?= __('recharge_instruction_1') ?></span></div>
|
||
<div class="mb-2 d-flex gap-2"><i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i> <span><?= __('recharge_instruction_2') ?></span></div>
|
||
<div class="d-flex gap-2"><i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i> <span><?= __('recharge_instruction_3') ?></span></div>
|
||
</div>
|
||
<div class="mt-4"><button type="button" class="btn btn-primary w-100 rounded-pill py-2 fw-bold opacity-50" disabled style="background: #ff4d94 !important; border: none;">正在获取账户详情...</button></div>
|
||
</div>
|
||
</div>`;
|
||
} else if (status === 'matched' || status === '1') {
|
||
side.innerHTML = `
|
||
<div class="text-center text-lg-start position-relative" style="z-index: 2;">
|
||
<div class="mb-4 text-center">
|
||
<div class="d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill bg-success bg-opacity-10 text-success small fw-bold mb-3 border border-success border-opacity-10">
|
||
<i class="bi bi-check-circle-fill text-success"></i> 匹配成功
|
||
</div>
|
||
<h2 class="fw-bold text-dark mb-3" style="font-size: 2rem;">匹配成功</h2>
|
||
<p class="text-muted fw-medium mb-0" style="font-size: 15px;">您的充值订单已匹配成功。<br>客服正在为您发送收款账户信息,请稍候。<br>页面将自动显示收款账户,请勿刷新或关闭页面。</p>
|
||
</div>
|
||
<div class="mb-4 py-4 px-4 rounded-4 border border-light shadow-sm" style="background: #fff0f5;">
|
||
<div class="row align-items-center text-center">
|
||
<div class="col-12 mb-3">
|
||
<div class="text-muted small mb-1 fw-bold"><?= __('waiting_countdown') ?></div>
|
||
<div class="display-5 fw-bold text-primary mb-0" id="modal-countdown" style="font-family: monospace; color: #ff4d94 !important;">30:00</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="p-4 rounded-4 bg-light border border-light">
|
||
<h6 class="text-dark fw-bold mb-3 d-flex align-items-center gap-2"><i class="bi bi-shield-lock-fill text-primary" style="color: #ff4d94 !important;"></i> <?= __('security_tips') ?></h6>
|
||
<div class="mt-4"><button type="button" class="btn btn-primary w-100 rounded-pill py-2 fw-bold opacity-50" disabled style="background: #ff4d94 !important; border: none;">正在获取账户详情...</button></div>
|
||
</div>
|
||
</div>`;
|
||
} else if (status === 'account_sent' || status === '2') {
|
||
const bank = data.account_bank || '---';
|
||
const account = data.account_number || '---';
|
||
const name = data.account_name || '---';
|
||
side.innerHTML = `
|
||
<div class="text-center text-lg-start">
|
||
<div class="mb-4 text-center">
|
||
<div class="d-inline-flex align-items-center gap-2 px-3 py-1 rounded-pill bg-success bg-opacity-10 text-success small fw-bold mb-3 border border-success border-opacity-10"><i class="bi bi-check-circle-fill text-success"></i> 匹配成功</div>
|
||
<h2 class="fw-bold text-dark mb-2" style="font-size: 1.8rem;">请按照以下账户信息进行转账</h2>
|
||
</div>
|
||
<div class="mb-3 p-4 rounded-4 shadow-sm border border-light" style="background: #fff0f5;">
|
||
<div class="d-flex flex-column gap-3">
|
||
<div class="payment-item">
|
||
<div class="text-muted small mb-1 fw-bold text-start"><?= __("receiving_bank") ?>:</div>
|
||
<div class="d-flex justify-content-between align-items-center gap-2">
|
||
<div class="h6 mb-0 fw-bold text-dark text-start" style="word-break: break-all; font-size: 1.1rem;">${bank}</div>
|
||
<button class="btn btn-sm rounded-pill px-3 fw-bold flex-shrink-0" style="font-size: 10px; background: #ff4d94; color: white;" onclick="copyText('${bank}')"><?= __("copy") ?></button>
|
||
</div>
|
||
</div>
|
||
<div class="payment-item border-top border-white border-opacity-50 pt-2">
|
||
<div class="text-muted small mb-1 fw-bold text-start"><?= __("receiving_account") ?>:</div>
|
||
<div class="d-flex justify-content-between align-items-center gap-2">
|
||
<div class="h5 mb-0 fw-bold text-start" style="word-break: break-all; font-family: monospace; font-size: 1.3rem; color: #ff4d94;">${account}</div>
|
||
<button class="btn btn-sm rounded-pill px-3 fw-bold flex-shrink-0" style="font-size: 10px; background: #ff4d94; color: white;" onclick="copyText('${account}')"><?= __("copy") ?></button>
|
||
</div>
|
||
</div>
|
||
<div class="payment-item border-top border-white border-opacity-50 pt-2">
|
||
<div class="text-muted small mb-1 fw-bold text-start"><?= __("receiving_name") ?>:</div>
|
||
<div class="d-flex justify-content-between align-items-center gap-2">
|
||
<div class="h6 mb-0 fw-bold text-dark text-start" style="word-break: break-all; font-size: 1.1rem;">${name}</div>
|
||
<button class="btn btn-sm rounded-pill px-3 fw-bold flex-shrink-0" style="font-size: 10px; background: #ff4d94; color: white;" onclick="copyText('${name}')"><?= __("copy") ?></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mb-3 py-3 px-4 rounded-4 shadow-sm border border-light" style="background: #ffffff;">
|
||
<div class="row align-items-center text-center text-lg-start">
|
||
<div class="col-12 col-lg-7 mb-2 mb-lg-0">
|
||
<div class="text-muted small mb-0 fw-bold"><?= __("remaining_time") ?></div>
|
||
<div class="h2 fw-bold mb-0" id="modal-countdown" style="font-family: monospace; color: #ff4d94;">--:--</div>
|
||
</div>
|
||
<div class="col-12 col-lg-5 border-start-lg border-light ps-lg-3">
|
||
<div class="small fw-bold" style="color: #ff4d94;"><i class="bi bi-shield-check me-1"></i><?= __("secure_pay") ?></div>
|
||
<div class="text-muted" style="font-size: 10px;"><?= __("encrypted_channel") ?></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="p-2 text-center mb-3"><p class="text-muted small fw-bold mb-0">请严格按照页面展示的收款账户信息进行转账。<br>请勿分笔转账或修改信息,转账完成后,请点击“完成转账”按钮。<br>转账完成后请提交转账凭证给在线客服,方便第一时间为你确认到账。</p></div>
|
||
<button type="button" class="btn btn-primary w-100 rounded-pill py-3 fw-bold shadow-sm" onclick="finishTransfer()" style="background: #ff4d94 !important; border: none; color: white;">【完成转账】</button>
|
||
</div>`;
|
||
} else if (status === 'finished') {
|
||
side.innerHTML = `
|
||
<div class="text-center text-lg-start position-relative" style="z-index: 2;">
|
||
<div class="mb-4 text-center">
|
||
<div class="d-inline-flex align-items-center gap-2 px-3 py-2 rounded-pill bg-warning bg-opacity-10 text-warning small fw-bold mb-3 border border-warning border-opacity-10">
|
||
<span class="pulse-dot-pink"></span> <span style="letter-spacing: 1px;">等待审核中</span>
|
||
</div>
|
||
<h2 class="fw-bold text-dark mb-3" style="font-size: 2rem;">已提交,等待审核</h2>
|
||
<p class="text-muted fw-medium mb-0" style="font-size: 15px;">您的充值申请已成功提交,正在等待管理员核对资金。<br>审核通过后,资金将自动存入您的账户。<br>请耐心等待,通常需要 1-5 分钟。</p>
|
||
</div>
|
||
<div class="mb-4 py-4 px-4 rounded-4 border border-light shadow-sm" style="background: #fff0f5;">
|
||
<div class="row align-items-center text-center">
|
||
<div class="col-12 mb-3">
|
||
<div class="text-muted small mb-1 fw-bold">预计审核剩余时间</div>
|
||
<div class="display-6 fw-bold text-primary mb-0" style="font-family: monospace; color: #ff4d94 !important;">正在核对资金...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="p-4 rounded-4 bg-light border border-light">
|
||
<h6 class="text-dark fw-bold mb-3 d-flex align-items-center gap-2"><i class="bi bi-shield-lock-fill text-primary" style="color: #ff4d94 !important;"></i> 温馨提示</h6>
|
||
<div class="text-muted small lh-lg">
|
||
<div class="mb-2 d-flex gap-2"><i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i> <span>转账完成后,请务必保留转账截图凭证。</span></div>
|
||
<div class="mb-2 d-flex gap-2"><i class="bi bi-check2-circle text-primary" style="color: #ff4d94 !important;"></i> <span>如有任何疑问,请联系在线客服咨询。</span></div>
|
||
</div>
|
||
<div class="mt-4"><button type="button" class="btn btn-secondary w-100 rounded-pill py-2 fw-bold" onclick="location.reload()">确定并返回</button></div>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
// Sync countdown if exists
|
||
if (remainingSeconds > 0) {
|
||
let mins = Math.floor(remainingSeconds / 60), secs = remainingSeconds % 60;
|
||
const timeStr = `${mins}:${secs < 10 ? '0' : ''}${secs}`;
|
||
document.querySelectorAll('#modal-countdown').forEach(d => d.innerText = timeStr);
|
||
}
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', async () => {
|
||
updateRate();
|
||
const savedState = localStorage.getItem('recharge_state');
|
||
if (savedState) {
|
||
const state = JSON.parse(savedState);
|
||
const elapsed = Math.floor((Date.now() - state.timestamp) / 1000);
|
||
remainingSeconds = (state.remainingSeconds || 1800) - elapsed;
|
||
if (remainingSeconds > 0 && state.orderId) {
|
||
openRechargeModal(state.initialMessage, true, state.orderId);
|
||
try {
|
||
const r = await fetch(`api/recharge_status.php?id=${state.orderId}&_t=${Date.now()}`);
|
||
const data = await r.json();
|
||
if (data.success) {
|
||
renderRechargeUI(data);
|
||
}
|
||
} catch (e) {}
|
||
} else { localStorage.removeItem('recharge_state'); }
|
||
}
|
||
});
|
||
|
||
function initModalChat() {
|
||
if (modalChatPolling) return;
|
||
modalChatPolling = true;
|
||
const modalChatForm = document.getElementById('modal-chat-form'), modalChatInput = document.getElementById('modal-chat-input');
|
||
const modalChatUpload = document.getElementById('modal-chat-upload'), modalChatFile = document.getElementById('modal-chat-file');
|
||
if (!modalChatForm || !modalChatUpload || !modalChatFile) return;
|
||
|
||
modalChatUpload.onclick = () => modalChatFile.click();
|
||
modalChatFile.onchange = async () => {
|
||
if (!modalChatFile.files[0]) return;
|
||
const file = modalChatFile.files[0], tempId = 'modal_temp_img_' + Date.now(), localUrl = URL.createObjectURL(file);
|
||
appendModalMessage({ id: tempId, sender: 'user', message: `<img src="${localUrl}" class="img-fluid rounded" style="max-height: 250px; opacity: 0.6;">`, created_at: new Date().toISOString() });
|
||
scrollModalToBottom();
|
||
const formData = new FormData(); formData.append('file', file); formData.append('action', 'upload_image');
|
||
try {
|
||
const resp = await fetch(apiPath + 'chat.php?v=' + Date.now(), { method: 'POST', body: formData }), data = await resp.json();
|
||
document.querySelector(`[data-modal-id="${tempId}"]`)?.remove();
|
||
if (data.success) { appendModalMessage(data.message); scrollModalToBottom(); }
|
||
} catch (err) { console.error(err); }
|
||
modalChatFile.value = ''; setTimeout(() => URL.revokeObjectURL(localUrl), 5000);
|
||
};
|
||
modalChatForm.onsubmit = async (e) => {
|
||
e.preventDefault(); const msg = modalChatInput.value.trim(); if (!msg) return;
|
||
modalChatInput.value = ''; const tempId = 'modal_temp_msg_' + Date.now();
|
||
appendModalMessage({ id: tempId, sender: 'user', message: msg, created_at: new Date().toISOString() });
|
||
scrollModalToBottom();
|
||
try {
|
||
const resp = await fetch(apiPath + 'chat.php?action=send_message&v=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` });
|
||
const data = await resp.json();
|
||
document.querySelector(`[data-modal-id="${tempId}"]`)?.remove();
|
||
if (data.success) { appendModalMessage(data.message); scrollModalToBottom(); }
|
||
} catch (err) { console.error(err); }
|
||
};
|
||
const modalPoll = async () => {
|
||
if (!document.getElementById('rechargeModal').classList.contains('show')) {
|
||
modalChatPolling = false;
|
||
return;
|
||
}
|
||
try {
|
||
fetch(apiPath + `chat.php?action=ping&user_time=${encodeURIComponent(new Date().toLocaleString())}&v=` + Date.now());
|
||
const resp = await fetch(apiPath + 'chat.php?action=get_messages&v=' + Date.now()), data = await resp.json();
|
||
if (Array.isArray(data)) { data.forEach(m => { if (!modalChatLastIds.has(m.id)) { appendModalMessage(m); modalChatLastIds.add(m.id); scrollModalToBottom(); } }); }
|
||
} catch (err) {}
|
||
setTimeout(modalPoll, 2000);
|
||
};
|
||
modalPoll();
|
||
}
|
||
|
||
async function sendModalMessage(msg) {
|
||
try { await fetch(apiPath + 'chat.php?action=send_message&v=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` }); } catch (err) {}
|
||
}
|
||
|
||
function appendModalMessage(m) {
|
||
const container = document.getElementById('modal-chat-messages');
|
||
if (!container || document.querySelector(`[data-modal-id="${m.id}"]`)) return;
|
||
const sender = m.sender; let text = (m.message || '').toString(), displayMsg = text;
|
||
const isImage = text.includes('<img') || text.includes('/assets/images/chat/') || text.includes('data:image');
|
||
if (isImage && !displayMsg.includes('<img')) displayMsg = `<img src="${displayMsg.includes('assets/') ? '/'+displayMsg : displayMsg}" class="img-fluid rounded" style="max-height: 250px; cursor: zoom-in;" onclick="window.open(this.src)">`;
|
||
let timeStr = ''; try { const d = m.created_at ? (m.created_at.includes('-') ? new Date(m.created_at.replace(/-/g, "/")) : new Date(m.created_at)) : new Date(); timeStr = d.toLocaleTimeString('zh-CN', {hour:'2-digit', minute:'2-digit'}); } catch(e) { timeStr = '--:--'; }
|
||
const html = `
|
||
<div class="mb-3 d-flex flex-column ${sender === 'user' ? 'align-items-end' : 'align-items-start'} modal-msg" data-modal-id="${m.id}">
|
||
<div class="msg-bubble p-2 px-3 rounded-4 small ${sender === 'user' ? 'bg-primary text-white' : 'bg-dark text-white border border-secondary border-opacity-30'}" style="max-width: 85%; position: relative; padding-bottom: 22px !important;">
|
||
<div class="message-content">${displayMsg}</div>
|
||
<div style="font-size: 9px; opacity: 0.6; position: absolute; bottom: 4px; ${sender === 'user' ? 'right: 12px;' : 'left: 12px;'}">${timeStr}</div>
|
||
</div>
|
||
</div>`;
|
||
container.insertAdjacentHTML('beforeend', html); modalChatLastIds.add(m.id);
|
||
}
|
||
|
||
function copyText(text) {
|
||
const el = document.createElement('textarea'); el.value = text; document.body.appendChild(el); el.select(); document.execCommand('copy'); document.body.removeChild(el);
|
||
Swal.fire({ icon: 'success', title: '<?= __("copy_success") ?>', toast: true, position: 'top-end', showConfirmButton: false, timer: 2000 });
|
||
}
|
||
|
||
function scrollModalToBottom() { const c = document.getElementById('modal-chat-messages'); if (c) c.scrollTop = c.scrollHeight; }
|
||
|
||
function confirmFiatOrder(btn, event) {
|
||
if (event) event.preventDefault();
|
||
const amount = parseFloat(document.getElementById('fiatAmount').value), select = document.getElementById('fiatCurrency'), currency = select.value, rate = parseFloat(select.options[select.selectedIndex].getAttribute('data-rate'));
|
||
if (isNaN(amount) || amount <= 0) { notify('warning', '<?= __("enter_amount") ?>'); return; }
|
||
const originalText = btn.innerHTML; btn.disabled = true; btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${originalText}`;
|
||
const formData = new FormData(); formData.append('action', 'recharge'); formData.append('amount', amount / rate); formData.append('symbol', 'USDT'); formData.append('fiat_amount', amount); formData.append('fiat_currency', currency); formData.append('method', '<?= __("fiat_recharge") ?> (' + currency + ')');
|
||
fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData }).then(r => r.json()).then(data => {
|
||
btn.disabled = false; btn.innerHTML = originalText;
|
||
if (data.success) {
|
||
let msg = `<?= __("recharge_msg_fiat") ?>`;
|
||
const resAmount = (amount / rate).toFixed(2);
|
||
msg = msg.replace('%uid%', userId).replace('%amount%', amount).replace('%currency%', currency).replace('%res%', resAmount);
|
||
openRechargeModal(msg, false, data.id);
|
||
document.getElementById('fiatAmount').value = '';
|
||
}
|
||
else notify('error', data.error || '<?= __("request_failed") ?>');
|
||
}).catch(err => { btn.disabled = false; btn.innerHTML = originalText; notify('error', err.message); });
|
||
}
|
||
|
||
function confirmCryptoOrder(btn, event) {
|
||
if (event) event.preventDefault();
|
||
const amountInput = document.getElementById('cryptoAmount');
|
||
const amount = parseFloat(amountInput.value);
|
||
if (isNaN(amount) || amount <= 0) { notify('warning', '<?= __("enter_amount") ?>'); return; }
|
||
const originalText = btn.innerHTML; btn.disabled = true; btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${originalText}`;
|
||
const formData = new FormData(); formData.append('action', 'recharge'); formData.append('amount', amount); formData.append('symbol', 'USDT'); formData.append('method', currentNetwork);
|
||
fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData }).then(r => r.json()).then(data => {
|
||
btn.disabled = false; btn.innerHTML = originalText;
|
||
if (data.success) {
|
||
let msg = `<?= __("recharge_msg_crypto") ?>`;
|
||
msg = msg.replace('%uid%', userId).replace('%amount%', amount).replace('%network%', currentNetwork);
|
||
openRechargeModal(msg, false, data.id);
|
||
amountInput.value = '';
|
||
}
|
||
else notify('error', data.error || '<?= __("request_failed") ?>');
|
||
}).catch(err => { btn.disabled = false; btn.innerHTML = originalText; notify('error', err.message); });
|
||
}
|
||
|
||
function copyAddress() {
|
||
const addr = document.getElementById('cryptoAddress'); addr.select(); document.execCommand('copy');
|
||
Swal.fire({ icon: 'success', title: '<?= __("copy_success") ?>', toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, background: '#1e2329', color: '#fff' });
|
||
}
|
||
</script>
|
||
|
||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|