false, 'error' => __('unauthorized')]); exit; } $symbol = $_POST['symbol'] ?? 'BTC'; $side = $_POST['side'] ?? 'buy'; $price = (float)($_POST['price'] ?? 0); $amount = (float)($_POST['amount'] ?? 0); $type = $_POST['type'] ?? 'limit'; if ($amount <= 0) { echo json_encode(['success' => false, 'error' => __('invalid_amount')]); exit; } $db->beginTransaction(); try { // Check balance $total_cost = ($side === 'buy') ? ($price * $amount) : $amount; $pay_symbol = ($side === 'buy') ? 'USDT' : $symbol; $stmt = $db->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = ?"); $stmt->execute([$user_id, $pay_symbol]); $bal = $stmt->fetchColumn() ?: 0; if ($bal < $total_cost) { throw new Exception(__('insufficient_balance')); } // Deduct balance $db->prepare("UPDATE user_balances SET available = available - ? WHERE user_id = ? AND symbol = ?") ->execute([$total_cost, $user_id, $pay_symbol]); // Insert order (auto-fill for spot if price matches) // For this simple implementation, we mark as filled immediately $stmt = $db->prepare("INSERT INTO spot_orders (user_id, symbol, side, price, amount, filled, status) VALUES (?, ?, ?, ?, ?, ?, 'filled')"); $stmt->execute([$user_id, $symbol, $side, $price, $amount, $amount]); // Add target balance $target_symbol = ($side === 'buy') ? $symbol : 'USDT'; $target_amount = ($side === 'buy') ? $amount : ($price * $amount); // Check if target balance exists, if not create $stmt = $db->prepare("SELECT id FROM user_balances WHERE user_id = ? AND symbol = ?"); $stmt->execute([$user_id, $target_symbol]); if (!$stmt->fetch()) { $db->prepare("INSERT INTO user_balances (user_id, symbol, available) VALUES (?, ?, 0)") ->execute([$user_id, $target_symbol]); } $db->prepare("UPDATE user_balances SET available = available + ? WHERE user_id = ? AND symbol = ?") ->execute([$target_amount, $user_id, $target_symbol]); // Record transaction $db->prepare("INSERT INTO transactions (user_id, type, amount, symbol, status) VALUES (?, ?, ?, ?, 'completed')") ->execute([$user_id, 'spot_trade', $total_cost, $pay_symbol]); $db->commit(); echo json_encode(['success' => true]); } catch (Exception $e) { $db->rollBack(); echo json_encode(['success' => false, 'error' => $e->getMessage()]); }