338 lines
17 KiB
PHP
338 lines
17 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/header.php';
|
|
require_once __DIR__ . '/includes/exchange.php';
|
|
|
|
if (!$user) {
|
|
header('Location: /auth/login.php');
|
|
exit;
|
|
}
|
|
|
|
// 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()">
|
|
<?= __('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">
|
|
<div>
|
|
<div class="fw-bold text-white"><?= $lang === 'zh' ? __('USDT') : 'USDT' ?></div>
|
|
<div class="text-white-50 small"><?= $lang === 'zh' ? __('tether') : '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 text-center">
|
|
<div class="p-3 bg-white rounded-4 d-inline-block mb-3 shadow-sm">
|
|
<img id="qrCode" src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=<?= $trc20_addr ?>" width="150" height="150" alt="QR Code">
|
|
</div>
|
|
<div class="input-group">
|
|
<input type="text" id="cryptoAddress" class="form-control bg-dark border-secondary text-white text-center py-3" value="<?= $trc20_addr ?>" readonly>
|
|
<button class="btn btn-outline-primary px-4" type="button" onclick="copyAddress()"><?= __('copy') ?></button>
|
|
</div>
|
|
<p class="text-warning small mt-3 mb-0">
|
|
<i class="bi bi-exclamation-triangle-fill me-1"></i>
|
|
<?= __('crypto_recharge_warning') ?>
|
|
</p>
|
|
</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()">
|
|
<?= __('i_have_paid') ?>
|
|
</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>
|
|
|
|
<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>
|
|
|
|
<script>
|
|
let currentNetwork = 'TRC20';
|
|
let currentAddress = '<?= $trc20_addr ?>';
|
|
|
|
function updateRate() {
|
|
const select = document.getElementById('fiatCurrency');
|
|
const symbol = select.value;
|
|
const rate = select.options[select.selectedIndex].getAttribute('data-rate');
|
|
document.getElementById('selectedCurrencyLabel').innerText = symbol;
|
|
document.getElementById('currentRateText').innerText = `${rate} ${symbol}`;
|
|
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;
|
|
|
|
// Update UI
|
|
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}`;
|
|
}
|
|
|
|
const userId = '<?= $user['uid'] ?? $user['id'] ?>';
|
|
|
|
function confirmFiatOrder() {
|
|
const amountInput = document.getElementById('fiatAmount');
|
|
const amount = parseFloat(amountInput.value);
|
|
const select = document.getElementById('fiatCurrency');
|
|
const currency = select.value;
|
|
const rate = parseFloat(select.options[select.selectedIndex].getAttribute('data-rate'));
|
|
|
|
if (isNaN(amount) || amount <= 0) {
|
|
alert('<?= __("enter_amount") ?>');
|
|
return;
|
|
}
|
|
|
|
const estUsdt = amount / rate;
|
|
|
|
const formData = new FormData();
|
|
formData.append('action', 'recharge');
|
|
formData.append('amount', estUsdt);
|
|
formData.append('symbol', 'USDT');
|
|
formData.append('fiat_amount', amount);
|
|
formData.append('fiat_currency', currency);
|
|
formData.append('method', '<?= __('fiat_recharge') ?> (' + currency + ')');
|
|
|
|
fetch('/api/finance.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
let message = `<?= __('recharge_msg_fiat') ?>`;
|
|
const preciseRes = (amount / rate).toFixed(4);
|
|
message = message.replace('%uid%', userId)
|
|
.replace('%amount%', amount)
|
|
.replace('%currency%', currency)
|
|
.replace('%rate%', rate)
|
|
.replace('%res%', preciseRes);
|
|
sendToCS(message);
|
|
} else {
|
|
alert(data.error || '<?= __('request_failed') ?>');
|
|
}
|
|
});
|
|
}
|
|
|
|
function confirmCryptoOrder() {
|
|
const amountInput = document.getElementById('cryptoAmount');
|
|
const amount = parseFloat(amountInput.value);
|
|
|
|
if (isNaN(amount) || amount <= 0) {
|
|
alert('<?= __("enter_amount") ?>');
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append('action', 'recharge');
|
|
formData.append('amount', amount);
|
|
formData.append('symbol', 'USDT');
|
|
formData.append('method', currentNetwork);
|
|
|
|
fetch('/api/finance.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
let message = `<?= __('recharge_msg_crypto') ?>`;
|
|
message = message.replace('%uid%', userId)
|
|
.replace('%network%', currentNetwork)
|
|
.replace('%amount%', amount);
|
|
sendToCS(message);
|
|
} else {
|
|
alert(data.error || '<?= __('request_failed') ?>');
|
|
}
|
|
});
|
|
}
|
|
|
|
function sendToCS(message) {
|
|
const csBox = document.getElementById('cs-box');
|
|
if (csBox && csBox.classList.contains('d-none')) {
|
|
const toggle = document.getElementById('cs-toggle');
|
|
if (toggle) toggle.click();
|
|
}
|
|
|
|
const csInput = document.getElementById('cs-input');
|
|
if (csInput) {
|
|
csInput.value = message;
|
|
document.getElementById('cs-form').dispatchEvent(new Event('submit'));
|
|
alert('<?= __("request_sent") ?>');
|
|
} else {
|
|
alert('<?= __("cs_connect_fail") ?>');
|
|
}
|
|
}
|
|
|
|
function copyAddress() {
|
|
const addr = document.getElementById('cryptoAddress');
|
|
addr.select();
|
|
document.execCommand('copy');
|
|
alert('<?= __("copy_success") ?>');
|
|
}
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|