PHP WebShell

Текущая директория: /var/www/bitcardoApp/backyard/user/funding

Просмотр файла: paystack.php

<? 
include '../common/header.php'; 
require_once '../../models/paystack/paystack_client.php';

$ps_ngn     = null;
$ps_error   = null;

try {
    $ps_ngn = paystack_get_ngn_balance();
} catch (Throwable $e) {
    $ps_error = $e->getMessage();
}

/**
 * Helpers
 */
function dec_mul($a, $b, $scale = 18) {
    $a = (string)$a;
    $b = (string)$b;

    // Prefer BCMath for precision
    if (function_exists('bcmul')) {
        return bcmul($a, $b, $scale);
    }

    // Fallback (less precise)
    return (string)((float)$a * (float)$b);
}

/**
 * Round a decimal string to N dp using BCMath (true rounding).
 * If BCMath missing, falls back to float rounding.
 */
function round_decimal_str($num, $precision = 2) {
    $num = (string)$num;

    if ($num === '' || $num === null) return null;

    if (function_exists('bcadd') && function_exists('bccomp')) {
        $precision = (int)$precision;
        $guardScale = max($precision + 3, 6);

        // Determine sign
        $isNeg = (bccomp($num, '0', $guardScale) < 0);

        // 0.005 for 2dp, 0.0005 for 3dp, etc.
        $half = '0.' . str_repeat('0', max(0, $precision - 1)) . '5';

        // Add/subtract half unit then truncate to precision
        $adjusted = $isNeg
            ? bcsub($num, $half, $guardScale)
            : bcadd($num, $half, $guardScale);

        // Truncate at precision
        return bcadd($adjusted, '0', $precision);
    }

    // Float fallback
    return number_format((float)$num, $precision, '.', '');
}

/**
 * Display money with exactly 2 decimals (.00)
 */
function money_2dp($value) {
    if ($value === null || $value === '') return '';
    $rounded = round_decimal_str($value, 2);
    if ($rounded === null || $rounded === '') return '';
    // Ensure exactly 2dp string
    if (strpos($rounded, '.') === false) return $rounded . '.00';
    $parts = explode('.', $rounded, 2);
    $dec = $parts[1] ?? '00';
    $dec = substr($dec . '00', 0, 2);
    return $parts[0] . '.' . $dec;
}

function coingecko_ids_for_coins(array $coins): array {
    $map = [
        'BTC'  => 'bitcoin',
        'ETH'  => 'ethereum',
        'SOL'  => 'solana',
        'TRX'  => 'tron',
        'USDT' => 'tether',
        'USDC' => 'usd-coin',
        'BNB'  => 'binancecoin',
        'XRP'  => 'ripple',
        'DOGE' => 'dogecoin',
        'LTC'  => 'litecoin',
    ];

    $ids = [];
    foreach ($coins as $c) {
        $c = strtoupper(trim($c));
        if (isset($map[$c])) $ids[$c] = $map[$c];
    }
    return $ids;
}

function coingecko_fetch_usd_rates(array $coinToId): array {
    if (empty($coinToId)) return [];

    $ids = implode(',', array_values($coinToId));
    $url = "https://api.coingecko.com/api/v3/simple/price?ids=" . urlencode($ids) . "&vs_currencies=usd";

    $ctx = stream_context_create([
        'http' => [
            'timeout' => 8,
            'header'  => "Accept: application/json\r\nUser-Agent: Bitcardo/1.0\r\n",
        ]
    ]);

    $json = @file_get_contents($url, false, $ctx);
    if (!$json) return [];

    $data = json_decode($json, true);
    if (!is_array($data)) return [];

    $rates = [];
    foreach ($coinToId as $coin => $id) {
        if (isset($data[$id]['usd'])) {
            // keep as string for BCMath
            $rates[$coin] = (string)$data[$id]['usd'];
        }
    }
    return $rates;
}

/**
 * Load Central Wallets (platform wallets)
 * - Prefer `central_wallets` if present, else fallback to `cwallet`
 * - Display wallet address + raw balance (no formatting)
 */
$centralWallets = [];
$cwallet_error  = null;
$cwallet_table  = null;

try {
    // Detect which table exists
    $candidates = ['central_wallets', 'cwallet'];

    foreach ($candidates as $tbl) {
        $res = $conn->query("SHOW TABLES LIKE '" . $conn->real_escape_string($tbl) . "'");
        if ($res && $res->num_rows > 0) {
            $cwallet_table = $tbl;
            break;
        }
    }

    if ($cwallet_table) {
        $sql = "SELECT * FROM `$cwallet_table` ORDER BY coin ASC";
        $res = $conn->query($sql);

        if ($res) {
            while ($row = $res->fetch_assoc()) {
                // Flexible column mapping (supports varying schemas)
                $coin = $row['coin'] ?? $row['wallet_coin'] ?? $row['symbol'] ?? '';

                // Wallet address (your logs suggest wallet_add)
                $address =
                    $row['wallet_add'] ??
                    $row['address'] ??
                    $row['wallet_address'] ??
                    $row['wallet_address_id'] ??
                    '';

                // Balance (raw)
                $balance =
                    $row['wallet_balance'] ??
                    $row['balance'] ??
                    $row['available_balance'] ??
                    '0';

                $centralWallets[] = [
                    'coin'    => (string)$coin,
                    'address' => (string)$address,
                    'balance' => (string)$balance,
                ];
            }
        } else {
            $cwallet_error = "Query failed: " . $conn->error;
        }
    } else {
        $cwallet_error = "No central wallet table found (expected `central_wallets` or `cwallet`).";
    }
} catch (Throwable $e) {
    $cwallet_error = $e->getMessage();
}

/**
 * Fetch USD rates and compute USD values (USD shown in 2dp)
 * USD value is derived: raw_balance * live_usd_rate
 */
$coinsOnPage = [];
foreach ($centralWallets as $w) {
    if (!empty($w['coin'])) $coinsOnPage[] = strtoupper(trim($w['coin']));
}
$coinsOnPage = array_values(array_unique($coinsOnPage));

$coinToId = coingecko_ids_for_coins($coinsOnPage);
$usdRates = coingecko_fetch_usd_rates($coinToId);

// Stablecoins fallback (optional)
$usdRates['USDT'] = $usdRates['USDT'] ?? '1';
$usdRates['USDC'] = $usdRates['USDC'] ?? '1';

foreach ($centralWallets as &$w) {
    $coin = strtoupper(trim((string)$w['coin']));
    $bal  = (string)($w['balance'] ?? '0');

    $rate = $usdRates[$coin] ?? null;

    $w['usd_rate']  = $rate; // stored for internal use/debug if needed
    $w['usd_value'] = ($rate === null) ? null : dec_mul($bal, $rate, 18);
}
unset($w);
?>

    <div class="nk-content nk-content-fluid">
        <div class="container-xl wide-lg">
            <div class="nk-content-body">
                <div class="nk-block-head">
                    <div class="nk-block-between-md g-4">
                        <div class="nk-block-head-content">
                            <h5 class="nk-block-title fw-normal">Paystack Funding</h5>
                            <div class="nk-block-des">
                                <p></p>
                            </div>
                        </div>
                        <div class="nk-block-head-content">
                            <ul class="nk-block-tools gx-3">
                                
                            </ul>
                        </div>
                    </div>
                </div>

                <div class="row g-gs">
                    <!-- Paystack funding account (NUBAN) + live balance -->
                    <div class="col-lg-6">
                        <div class="card card-bordered h-100">
                        <div class="card-inner">
                            <h6 class="title mb-3">Paystack Payout Funding</h6>

                            <div class="alert alert-info small mb-3">
                            Use this account to top up your Paystack balance for Bitcardo NGN withdrawals.
                            </div>

                            <dl class="row mb-3">
                            <dt class="col-5 small text-soft">Bank</dt>
                            <dd class="col-7 fw-bold">
                                <?= htmlspecialchars(PAYSTACK_FUNDING_BANK_NAME) ?>
                            </dd>

                            <dt class="col-5 small text-soft">Account Name</dt>
                            <dd class="col-7 fw-bold">
                                <?= htmlspecialchars(PAYSTACK_FUNDING_ACCOUNT_NAME) ?>
                            </dd>

                            <dt class="col-5 small text-soft">Account Number</dt>
                            <dd class="col-7 fw-bold">
                                <span class="fs-5">
                                <?= htmlspecialchars(PAYSTACK_FUNDING_ACCOUNT_NO) ?>
                                </span>
                            </dd>

                            <?php if (PAYSTACK_FUNDING_NOTE): ?>
                            <dt class="col-5 small text-soft">Note</dt>
                            <dd class="col-7 small text-muted">
                                <?= htmlspecialchars(PAYSTACK_FUNDING_NOTE) ?>
                            </dd>
                            <?php endif; ?>
                            </dl>

                            <hr>

                            <h6 class="title mb-2">Current Paystack NGN Balance</h6>

                            <?php if ($ps_error): ?>
                            <div class="alert alert-danger small mb-0">
                                Could not fetch balance: <?= htmlspecialchars($ps_error) ?>
                            </div>
                            <?php elseif (!$ps_ngn): ?>
                            <div class="small text-soft">No NGN balance data returned.</div>
                            <?php else: ?>
                            <div class="d-flex justify-content-between align-items-center mb-1">
                                <span class="small text-soft">Available</span>
                                <span class="fw-bold fs-5">
                                ₦<?= number_format($ps_ngn['available'], 2) ?>
                                </span>
                            </div>
                            <div class="d-flex justify-content-between align-items-center small text-soft">
                                <span>Pending</span>
                                <span>₦<?= number_format($ps_ngn['pending'], 2) ?></span>
                            </div>
                            <?php endif; ?>
                        </div>
                        </div>
                    </div>

                    <!-- Central Wallets (cwallet/central_wallets) -->
                    <div class="col-lg-6">
                        <div class="card card-bordered h-100">
                            <div class="card-inner">
                                <div class="d-flex justify-content-between align-items-center mb-2">
                                    <h6 class="title mb-0">Central Wallets</h6>
                                    <?php if ($cwallet_table): ?>
                                        <span class="badge bg-outline-secondary">
                                            Source: <?= htmlspecialchars($cwallet_table) ?>
                                        </span>
                                    <?php endif; ?>
                                </div>

                                <div class="alert alert-light small">
                                    Platform wallets showing wallet address, raw balance, and USD value (2dp).
                                </div>

                                <?php if ($cwallet_error): ?>
                                    <div class="alert alert-danger small mb-0">
                                        <?= htmlspecialchars($cwallet_error) ?>
                                    </div>
                                <?php elseif (empty($centralWallets)): ?>
                                    <div class="small text-soft">No wallets returned.</div>
                                <?php else: ?>
                                    <div class="table-responsive">
                                        <table class="table table-sm table-middle mb-0">
                                            <thead>
                                                <tr class="small text-soft">
                                                    <th>Coin</th>
                                                    <th>Wallet Address</th>
                                                    <th class="text-end">Balance (raw)</th>
                                                    <th class="text-end">USD</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <?php foreach ($centralWallets as $w): ?>
                                                    <tr>
                                                        <td class="fw-bold">
                                                            <?= htmlspecialchars($w['coin'] ?: '-') ?>
                                                        </td>
                                                        <td class="small text-break" style="max-width: 320px;">
                                                            <?= htmlspecialchars($w['address'] ?: '-') ?>
                                                        </td>
                                                        <td class="text-end">
                                                            <?= htmlspecialchars($w['balance']) ?>
                                                        </td>
                                                        <td class="text-end">
                                                            <?php if ($w['usd_value'] !== null && $w['usd_value'] !== ''): ?>
                                                                $<?= htmlspecialchars(money_2dp($w['usd_value'])) ?>
                                                            <?php else: ?>
                                                                -
                                                            <?php endif; ?>
                                                        </td>
                                                    </tr>
                                                <?php endforeach; ?>
                                            </tbody>
                                        </table>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>

                </div>

            </div>
        </div>
    </div>

<? include '../common/footer.php'; ?>

Выполнить команду


Для локальной разработки. Не используйте в интернете!