Files
myron 44a98eba15 Shade disabled payout methods when admin turns them off
- payout_methods list now includes admin_enabled flag via JOIN on admin_payout_settings
- Disabled methods appear at 45% opacity with UNAVAILABLE/DISABLED BY ADMIN badge
  in both the cashout radio list and profile payout tab; radio is disabled so they
  can't be selected, but the delete button remains
- Set Default button hidden on disabled methods
- cashout.php server-side guard rejects submissions using a disabled method type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 11:04:18 +00:00

159 lines
7.4 KiB
PHP

<?php
ob_start();
require_once __DIR__ . '/../../includes/auth.php';
ob_end_clean();
header('Content-Type: application/json');
if (!isLoggedIn()) { echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
$userId = (int)$_SESSION['user_id'];
$method = $_SERVER['REQUEST_METHOD'];
// ══════════════════════════════════════════════════════════
// GET — player's own requests (list, delete, update, lock)
// ══════════════════════════════════════════════════════════
if ($method === 'GET') {
$action = $_GET['action'] ?? 'list';
if ($action === 'list') {
$stmt = db()->prepare("
SELECT cr.*,
COALESCE(p.name, cr.platform_id) AS platform_name
FROM cashout_requests cr
LEFT JOIN platforms p ON cr.platform_id = p.slug
WHERE cr.user_id = ?
ORDER BY cr.created_at DESC
LIMIT 50
");
$stmt->execute([$userId]);
echo json_encode(['success'=>true, 'requests'=>$stmt->fetchAll()]);
exit;
}
if ($action === 'delete') {
$id = (int)($_GET['id'] ?? 0);
$chk = db()->prepare("SELECT id,tokens FROM cashout_requests WHERE id=? AND user_id=? AND status='pending'");
$chk->execute([$id, $userId]);
$row = $chk->fetch();
if (!$row) { echo json_encode(['success'=>false,'error'=>'Request not found or already locked']); exit; }
db()->prepare("UPDATE users SET tokens=tokens+? WHERE id=?")->execute([$row['tokens'], $userId]);
db()->prepare("DELETE FROM cashout_requests WHERE id=?")->execute([$id]);
$nb = db()->prepare("SELECT tokens FROM users WHERE id=?");
$nb->execute([$userId]);
echo json_encode(['success'=>true,'new_balance'=>(float)$nb->fetchColumn()]);
exit;
}
if ($action === 'update') {
$id = (int)($_GET['id'] ?? 0);
$tokens = (float)($_GET['tokens'] ?? 0);
$alias = substr(trim($_GET['alias'] ?? ''), 0, 100);
$chk = db()->prepare("SELECT id,tokens AS old_tokens FROM cashout_requests WHERE id=? AND user_id=? AND status='pending'");
$chk->execute([$id, $userId]);
$row = $chk->fetch();
if (!$row) { echo json_encode(['success'=>false,'error'=>'Request not found or already locked']); exit; }
if ($tokens < 1) { echo json_encode(['success'=>false,'error'=>'Minimum 1 token']); exit; }
$diff = $tokens - $row['old_tokens'];
if ($diff > 0) {
$balChk = db()->prepare("SELECT tokens FROM users WHERE id=?");
$balChk->execute([$userId]);
if ($diff > (float)$balChk->fetchColumn()) { echo json_encode(['success'=>false,'error'=>'Insufficient balance']); exit; }
}
db()->beginTransaction();
db()->prepare("UPDATE users SET tokens=tokens-? WHERE id=?")->execute([$diff, $userId]);
db()->prepare("UPDATE cashout_requests SET tokens=?,alias=? WHERE id=?")->execute([$tokens, $alias, $id]);
db()->commit();
echo json_encode(['success'=>true]);
exit;
}
if ($action === 'lock') {
$id = (int)($_GET['id'] ?? 0);
$chk = db()->prepare("SELECT id FROM cashout_requests WHERE id=? AND user_id=? AND status='pending'");
$chk->execute([$id, $userId]);
if (!$chk->fetch()) { echo json_encode(['success'=>false,'error'=>'Request not found']); exit; }
try {
db()->exec("ALTER TABLE cashout_requests MODIFY COLUMN status ENUM('pending','locked','sent','approved','rejected','deleted') DEFAULT 'pending'");
} catch (Exception $e) {}
db()->prepare("UPDATE cashout_requests SET status='locked' WHERE id=?")->execute([$id]);
echo json_encode(['success'=>true]);
exit;
}
echo json_encode(['success'=>false,'error'=>'Unknown action']);
exit;
}
// ══════════════════════════════════════════════════════════
// POST — submit new cashout request
// ══════════════════════════════════════════════════════════
if ($method !== 'POST') { echo json_encode(['success'=>false,'error'=>'Method not allowed']); exit; }
$data = json_decode(file_get_contents('php://input'), true);
$platformId = trim($data['platform_id'] ?? '');
$alias = trim($data['alias'] ?? '');
$tokens = (float)($data['tokens'] ?? 0);
$payoutMethodId = (int)($data['payout_method_id'] ?? 0);
$payoutMethodType = trim($data['payout_method_type'] ?? '');
$payoutHandle = trim($data['payout_handle'] ?? '');
// Validate platform
$platStmt = db()->prepare("SELECT slug FROM platforms WHERE slug=? AND is_active=1 LIMIT 1");
$platStmt->execute([$platformId]);
if (!$platStmt->fetch()) {
$platforms = json_decode(PLATFORMS, true);
if (empty(array_filter($platforms, fn($p) => $p['id'] === $platformId))) {
echo json_encode(['success'=>false,'error'=>'Invalid platform.']); exit;
}
}
if (empty($alias)) { echo json_encode(['success'=>false,'error'=>'Platform alias required.']); exit; }
if ($tokens < 1) { echo json_encode(['success'=>false,'error'=>'Minimum cashout is 1 token.']); exit; }
// Validate payout method
if ($payoutMethodId) {
$chk = db()->prepare("SELECT method_type,account_handle FROM payout_methods WHERE id=? AND user_id=?");
$chk->execute([$payoutMethodId, $userId]);
if ($pm = $chk->fetch()) {
$payoutMethodType = $pm['method_type'];
$payoutHandle = $pm['account_handle'];
}
}
// Reject if the payout method type is not currently admin-enabled
if ($payoutMethodType) {
$enaStmt = db()->prepare("SELECT is_enabled FROM admin_payout_settings WHERE method_key=?");
$enaStmt->execute([$payoutMethodType]);
$enaRow = $enaStmt->fetch();
if (!$enaRow || !$enaRow['is_enabled']) {
echo json_encode(['success'=>false,'error'=>'This payout method is no longer available. Please select a different method or add a new one.']); exit;
}
}
// Check balance
$balStmt = db()->prepare("SELECT tokens FROM users WHERE id=?");
$balStmt->execute([$userId]);
$balance = (float)$balStmt->fetchColumn();
if ($tokens > $balance) { echo json_encode(['success'=>false,'error'=>'Insufficient token balance.']); exit; }
// Deduct & create
db()->beginTransaction();
try {
db()->prepare("UPDATE users SET tokens=tokens-? WHERE id=?")->execute([$tokens, $userId]);
db()->prepare("INSERT INTO cashout_requests (user_id,platform_id,alias,tokens,payout_method_type,payout_handle) VALUES (?,?,?,?,?,?)")
->execute([$userId, $platformId, $alias, $tokens, $payoutMethodType, $payoutHandle]);
db()->commit();
} catch (Exception $e) {
db()->rollBack();
echo json_encode(['success'=>false,'error'=>'Request failed. Try again.']); exit;
}
$newBalStmt = db()->prepare("SELECT tokens FROM users WHERE id=?");
$newBalStmt->execute([$userId]);
$nb = (float)$newBalStmt->fetchColumn();
try { logActivity('cashout_request', $userId, null, 'cashout', 0, "Cashout: {$tokens} tokens via {$payoutMethodType}"); } catch(Exception $e){}
echo json_encode(['success'=>true, 'new_balance'=>$nb]);