query("SHOW TABLES LIKE '" . $c->real_escape_string($name) . "'"); return $r && $r->num_rows > 0; }
foreach (array(
'client_accounts' => "CREATE TABLE IF NOT EXISTS client_accounts (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, client_id INT UNSIGNED NOT NULL, account_name VARCHAR(190) NOT NULL, currency VARCHAR(3) DEFAULT 'EUR', balance DECIMAL(18,2) DEFAULT 0, iban VARCHAR(40) DEFAULT NULL, account_type ENUM('courant','epargne','devise','titres') DEFAULT 'courant', status ENUM('active','blocked') DEFAULT 'active', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, KEY idx_client (client_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
'client_transfers' => "CREATE TABLE IF NOT EXISTS client_transfers (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, client_id INT UNSIGNED NOT NULL, from_account VARCHAR(190) DEFAULT NULL, to_account VARCHAR(190) DEFAULT NULL, beneficiary VARCHAR(190) DEFAULT NULL, amount DECIMAL(18,2) DEFAULT 0, currency VARCHAR(3) DEFAULT 'EUR', label VARCHAR(190) DEFAULT NULL, status ENUM('pending','approved','rejected') DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, KEY idx_client (client_id), KEY idx_status (status)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
'client_documents' => "CREATE TABLE IF NOT EXISTS client_documents (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, client_id INT UNSIGNED NOT NULL, doc_name VARCHAR(190) NOT NULL, doc_type VARCHAR(60) DEFAULT NULL, file_path VARCHAR(255) DEFAULT NULL, status ENUM('active','archived') DEFAULT 'active', uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, KEY idx_client (client_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
'client_settings' => "CREATE TABLE IF NOT EXISTS client_settings (client_id INT UNSIGNED PRIMARY KEY, twofa TINYINT(1) DEFAULT 1, alert_login TINYINT(1) DEFAULT 1, geo_restrict TINYINT(1) DEFAULT 0, co_bancaire TINYINT(1) DEFAULT 1, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
'client_cards' => "CREATE TABLE IF NOT EXISTS client_cards (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, client_id INT UNSIGNED NOT NULL, card_name VARCHAR(120) NOT NULL, card_brand VARCHAR(60) DEFAULT 'Visa Infinite', card_number VARCHAR(30) NOT NULL, card_exp VARCHAR(10) NOT NULL, card_cvv VARCHAR(10) DEFAULT NULL, card_type ENUM('credit','debit') DEFAULT 'credit', credit_limit DECIMAL(18,2) DEFAULT 0, balance_used DECIMAL(18,2) DEFAULT 0, status ENUM('active','blocked','expired') DEFAULT 'active', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, KEY idx_client (client_id), KEY idx_status (status)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
) as $tname => $sql) { if (!table_exists_c($c, $tname)) { $c->query($sql); } }
/* --- Envoi e-mail corrigé (RFC 2047) --- */
function send_mail_safe($to, $subject, $html) {
try {
$fromName = 'PRIVATE BANK SA';
$fromAddr = 'contact@polotkafinanz.online';
$encodedName = '=?UTF-8?B?' . base64_encode($fromName) . '?=';
$fromHeader = $encodedName . ' <' . $fromAddr . '>';
$headers = "MIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\n";
$headers .= "From: " . $fromHeader . "\r\nReply-To: " . $fromAddr . "\r\nReturn-Path: " . $fromAddr . "\r\nX-Mailer: PRIVATE-BANK-SA\r\n";
return @mail($to, '=?UTF-8?B?' . base64_encode($subject) . '?=', $html, $headers);
} catch (\Throwable $e) { return false; } catch (\Exception $e) { return false; }
}
function email_layout($title, $content) {
return '
'
. ''
. '| PRIVATE BANK SA |
'
. '' . htmlspecialchars((string)$title, ENT_QUOTES, 'UTF-8') . '' . $content . ' |
'
. '| PRIVATE BANK SA — polotkafinanz.online |
';
}
/* ============================================================
* ACTION : VIREMENT (sans bind_param)
* ============================================================ */
$flash = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$act = isset($_POST['act']) ? $_POST['act'] : '';
if ($act === 'transfer') {
$from = trim(isset($_POST['from_account']) ? $_POST['from_account'] : '');
$to = trim(isset($_POST['to_account']) ? $_POST['to_account'] : '');
$benef = trim(isset($_POST['beneficiary']) ? $_POST['beneficiary'] : '');
$amount = (float)(isset($_POST['amount']) ? $_POST['amount'] : 0);
$cur = trim(isset($_POST['currency']) ? $_POST['currency'] : 'EUR');
$label = trim(isset($_POST['label']) ? $_POST['label'] : 'Virement');
if ($amount <= 0) { $flash = array('error', 'Montant invalide.'); }
else {
$accRow = null;
if ($from !== '') {
$fromE = $c->real_escape_string($from);
$res = $c->query("SELECT * FROM client_accounts WHERE client_id = " . (int)$cid . " AND account_name = '" . $fromE . "' LIMIT 1");
$accRow = $res ? $res->fetch_assoc() : null;
}
if ($accRow && (float)$accRow['balance'] < $amount) { $flash = array('error', 'Fonds insuffisants sur « ' . $from . ' ».'); }
else {
$fromE = $c->real_escape_string($from);
$toE = $c->real_escape_string($to);
$benefE = $c->real_escape_string($benef);
$curE = $c->real_escape_string($cur);
$labelE = $c->real_escape_string($label);
$amtS = number_format($amount, 2, '.', '');
$sql = "INSERT INTO client_transfers (client_id, from_account, to_account, beneficiary, amount, currency, label, status)
VALUES (" . (int)$cid . ", '" . $fromE . "', '" . $toE . "', '" . $benefE . "', " . $amtS . ", '" . $curE . "', '" . $labelE . "', 'pending')";
if (!$c->query($sql)) { $flash = array('error', 'Erreur SQL : ' . $c->error); }
else {
$tid = (int)$c->insert_id;
if ($accRow) { $nb = (float)$accRow['balance'] - $amount; $c->query("UPDATE client_accounts SET balance = " . number_format($nb, 2, '.', '') . " WHERE id = " . (int)$accRow['id']); }
$flash = array('success', 'Virement #' . $tid . ' enregistré.');
$html = email_layout('🔄 Nouveau virement à valider',
'Virement client en attente.
'
. '| Client | ' . htmlspecialchars((string)$cname, ENT_QUOTES, 'UTF-8') . ' |
'
. '| Réf. | #' . $tid . ' |
'
. '| Montant | ' . number_format($amount,2,',',' ') . ' ' . htmlspecialchars((string)$cur, ENT_QUOTES, 'UTF-8') . ' |
'
. 'Examiner
');
send_mail_safe('contact@polotkafinanz.online', '🔄 Nouveau virement à valider', $html);
}
}
}
header('Location: client.php?tab=virements&ok=1'); exit;
}
}
/* ============================================================
* CHARGEMENT DES DONNÉES
* ============================================================ */
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'dashboard';
$okFlag = isset($_GET['ok']) ? (int)$_GET['ok'] : 0;
$accounts = array(); $transfers = array(); $docs = array(); $cards = array();
if (table_exists_c($c, 'client_accounts')) { $r = $c->query("SELECT * FROM client_accounts WHERE client_id = " . (int)$cid . " ORDER BY id"); $accounts = $r ? $r->fetch_all(MYSQLI_ASSOC) : array(); }
if (table_exists_c($c, 'client_transfers')) { $r = $c->query("SELECT * FROM client_transfers WHERE client_id = " . (int)$cid . " ORDER BY created_at DESC"); $transfers = $r ? $r->fetch_all(MYSQLI_ASSOC) : array(); }
if (table_exists_c($c, 'client_documents')) { $r = $c->query("SELECT * FROM client_documents WHERE client_id = " . (int)$cid . " AND status='active' ORDER BY uploaded_at DESC"); $docs = $r ? $r->fetch_all(MYSQLI_ASSOC) : array(); }
if (table_exists_c($c, 'client_cards')) { $r = $c->query("SELECT * FROM client_cards WHERE client_id = " . (int)$cid . " ORDER BY id"); $cards = $r ? $r->fetch_all(MYSQLI_ASSOC) : array(); }
$activeCards = 0; $totalLimit = 0; $totalUsed = 0;
foreach ($cards as $cc) { if ($cc['status'] === 'active') { $activeCards++; $totalLimit += (float)$cc['credit_limit']; $totalUsed += (float)$cc['balance_used']; } }
$sec = array('twofa'=>1,'alert_login'=>1,'geo_restrict'=>0,'co_bancaire'=>1);
if (table_exists_c($c, 'client_settings')) { $r = $c->query("SELECT * FROM client_settings WHERE client_id = " . (int)$cid . " LIMIT 1"); if ($r && $row = $r->fetch_assoc()) { $sec = $row; } }
$rates = array('EUR'=>1, 'USD'=>0.90, 'CHF'=>1.05);
$totalEur = 0; foreach ($accounts as $a) { if ($a['status']==='active') { $totalEur += (float)$a['balance'] * (isset($rates[$a['currency']]) ? $rates[$a['currency']] : 1); } }
$pendingCount = 0; foreach ($transfers as $t) { if ($t['status'] === 'pending') $pendingCount++; }
function cfmt($n) { return number_format((float)$n, 2, ',', ' '); }
?>
Espace Client — PRIVATE BANK SA
client.php — Responsive OK
Espace privé / "Tableau de bord",'comptes'=>"Comptes & soldes",'virements'=>"Virements",'cartes'=>"Cartes",'documents'=>"Documents",'securite'=>"Sécurité");
echo h($titles[$tab] ?? 'Tableau de bord');
?>
Connecté
✅ Virement enregistré.
Patrimoine net consolidé · EUR
€
comptes · virement(s)
Historique des opérations
Virements
Aucun virement.
| Date | Libellé | De | Vers | Montant | Statut |
| | | | | |
Nouveau virement
Validation conseillère
Ouvrez un compte d'abord.
🔒 Enregistré en « en attente ».
Historique des virements
en attente
Aucun virement.
Aucune carte pour le moment. Votre conseillère vous en attribuera une.
Résumé de vos cartes
active(s)
Vos documents
Sécurisé ·
Aucun document disponible.
Protection de l'accès
Gérée par votre conseillère
Double authentificationCode à usage unique
Votre session
Réglages définis par votre conseillère pour protéger votre compte.