120 lines
3.9 KiB
PHP
120 lines
3.9 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
require_once '../db/config.php';
|
|
session_start();
|
|
|
|
if (!isset($_SESSION['user_id'])) {
|
|
echo json_encode(['success' => false, 'error' => 'User not logged in']);
|
|
exit;
|
|
}
|
|
|
|
$user_id = $_SESSION['user_id'];
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
|
|
// --- Input Validation ---
|
|
$pair = $data['pair'] ?? null;
|
|
$amount = (float)($data['amount'] ?? 0);
|
|
$direction = $data['direction'] ?? null;
|
|
$duration = (int)($data['duration'] ?? 0);
|
|
$rate = (float)($data['rate'] ?? 0); // Profit rate in percentage
|
|
|
|
if (empty($pair) || empty($direction) || $amount <= 0 || $duration <= 0 || $rate <= 0) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid order parameters.']);
|
|
exit;
|
|
}
|
|
|
|
// --- Server-Side Rules Validation ---
|
|
$valid_options = [
|
|
60 => ['rate' => 8, 'min' => 100],
|
|
90 => ['rate' => 12, 'min' => 5000],
|
|
120 => ['rate' => 15, 'min' => 30000],
|
|
180 => ['rate' => 20, 'min' => 100000],
|
|
300 => ['rate' => 32, 'min' => 300000],
|
|
];
|
|
|
|
if (!isset($valid_options[$duration]) || $valid_options[$duration]['rate'] != $rate) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid duration or profit rate selected.']);
|
|
exit;
|
|
}
|
|
|
|
$min_amount = $valid_options[$duration]['min'];
|
|
if ($amount < $min_amount) {
|
|
echo json_encode(['success' => false, 'error' => "Minimum amount for {$duration}s is {$min_amount} USDT."]);
|
|
exit;
|
|
}
|
|
|
|
// --- Securely Fetch Current Price from Binance API ---
|
|
function get_current_price($symbol) {
|
|
$url = "https://api.binance.com/api/v3/ticker/price?symbol=" . urlencode($symbol);
|
|
$ch = curl_init($url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
|
$response = curl_exec($ch);
|
|
curl_close($ch);
|
|
if ($response) {
|
|
$data = json_decode($response, true);
|
|
if (isset($data['price'])) {
|
|
return (float)$data['price'];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
$open_price = get_current_price($pair);
|
|
if ($open_price === null) {
|
|
echo json_encode(['success' => false, 'error' => 'Could not fetch current price for the pair. Please try again.']);
|
|
exit;
|
|
}
|
|
|
|
// --- Database Transaction ---
|
|
$pdo = db();
|
|
$pdo->beginTransaction();
|
|
|
|
try {
|
|
// 1. Lock user row and check balance
|
|
$stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ? FOR UPDATE");
|
|
$stmt->execute([$user_id]);
|
|
$user = $stmt->fetch();
|
|
|
|
if (!$user || $user['balance'] < $amount) {
|
|
$pdo->rollBack();
|
|
echo json_encode(['success' => false, 'error' => 'Insufficient balance.']);
|
|
exit;
|
|
}
|
|
|
|
// 2. Deduct balance
|
|
$new_balance = $user['balance'] - $amount;
|
|
$stmt = $pdo->prepare("UPDATE users SET balance = ? WHERE id = ?");
|
|
$stmt->execute([$new_balance, $user_id]);
|
|
|
|
// 3. Insert the new option order
|
|
$start_time = date('Y-m-d H:i:s');
|
|
$settle_at = date('Y-m-d H:i:s', time() + $duration);
|
|
$profit_rate_decimal = $rate / 100; // Store as decimal for calculation
|
|
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO option_orders (user_id, pair, amount, direction, duration, profit_rate, open_price, status, start_time, settle_at) " .
|
|
"VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)"
|
|
);
|
|
$stmt->execute([$user_id, $pair, $amount, $direction, $duration, $profit_rate_decimal, $open_price, $start_time, $settle_at]);
|
|
|
|
$order_id = $pdo->lastInsertId();
|
|
|
|
// 4. Commit the transaction
|
|
$pdo->commit();
|
|
|
|
// 5. Fetch the created order to return to the frontend
|
|
$stmt = $pdo->prepare("SELECT * FROM option_orders WHERE id = ?");
|
|
$stmt->execute([$order_id]);
|
|
$new_order = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
echo json_encode(['success' => true, 'order' => $new_order]);
|
|
|
|
} catch (Exception $e) {
|
|
if ($pdo->inTransaction()) {
|
|
$pdo->rollBack();
|
|
}
|
|
error_log("Option order failed: " . $e->getMessage());
|
|
echo json_encode(['success' => false, 'error' => 'An internal error occurred. Please try again later.']);
|
|
}
|
|
?>
|