0) {
$ar = mysqli_query($db, "SELECT users_role FROM ogp_users WHERE user_id = " . intval($actor_id) . " LIMIT 1");
if ($ar && mysqli_num_rows($ar) === 1) {
$arr = mysqli_fetch_assoc($ar);
if (strtolower((string)($arr['users_role'] ?? '')) === 'admin') {
$is_admin = true;
$_SESSION['website_user_role'] = 'admin';
}
}
} elseif (isset($_SESSION['website_username']) && !empty($_SESSION['website_username'])) {
$safe_un = mysqli_real_escape_string($db, $_SESSION['website_username']);
$ar = mysqli_query($db, "SELECT user_id, users_role FROM ogp_users WHERE users_login = '$safe_un' LIMIT 1");
if ($ar && mysqli_num_rows($ar) === 1) {
$arr = mysqli_fetch_assoc($ar);
if (strtolower((string)($arr['users_role'] ?? '')) === 'admin') {
$is_admin = true;
$_SESSION['website_user_role'] = 'admin';
$_SESSION['website_user_id'] = intval($arr['user_id'] ?? 0);
}
}
}
}
$orderId = (int)$_POST['create_free_for'];
if ($orderId > 0) {
// load invoice to verify ownership/price (invoice-first flow)
$stmt = $db->prepare("SELECT user_id, amount, status, qty, invoice_duration, service_id, home_name, ip, max_players, remote_control_password, ftp_password FROM " . $table_prefix . "billing_invoices WHERE invoice_id = ? LIMIT 1");
if ($stmt) {
$stmt->bind_param('i', $orderId);
$stmt->execute();
$stmt->bind_result($owner_id, $order_price, $prev_status, $order_qty, $order_invoice_duration, $service_id, $home_name, $ip, $max_players, $remote_control_password, $ftp_password);
$found = $stmt->fetch();
$stmt->close();
} else {
$found = false;
}
$audit_file = __DIR__ . '/logs/free_create_audit.log';
if ($found) {
$allowed = false;
$reason = '';
// Admin may force-create paid records for testing
if ($is_admin) {
$allowed = true;
$reason = 'admin_create';
}
// Owner may claim a free order if the price is zero
elseif ($actor_id > 0 && $actor_id === intval($owner_id) && floatval($order_price) == 0.0) {
$allowed = true;
$reason = 'user_claim_free';
}
if ($allowed) {
// Mark invoice as paid
$upd_inv = $db->prepare("UPDATE " . $table_prefix . "billing_invoices SET status = 'paid', paid_date = NOW() WHERE invoice_id = ? LIMIT 1");
if ($upd_inv) {
$upd_inv->bind_param('i', $orderId);
$upd_inv->execute();
$upd_inv->close();
}
// Now create the order record (invoice -> order after payment)
// Compute end_date: months based on invoice_duration and qty
$months = 0;
$q = intval($order_qty ?? 0);
$invdur = strtolower(trim($order_invoice_duration ?? ''));
if (strpos($invdur, 'year') !== false) {
$months = $q * 12;
} else {
// default to months for anything else (month, monthly, etc.)
$months = $q;
}
$end_date = null;
if ($months > 0) {
$dt = new DateTime('now');
$dt->modify('+' . intval($months) . ' months');
$end_date = $dt->format('Y-m-d H:i:s');
} else {
// if no months specified, set to now
$end_date = date('Y-m-d H:i:s');
}
// INSERT new order record (invoice->order after payment)
$esc_service_id = intval($service_id);
$esc_home_name = mysqli_real_escape_string($db, $home_name);
$esc_ip = intval($ip);
$esc_max_players = intval($max_players);
$esc_qty = intval($order_qty);
$esc_inv_dur = mysqli_real_escape_string($db, $order_invoice_duration);
$esc_price = floatval($order_price);
$esc_rc_pass = mysqli_real_escape_string($db, $remote_control_password);
$esc_ftp_pass = mysqli_real_escape_string($db, $ftp_password);
$esc_user_id = intval($owner_id);
$esc_end_date = mysqli_real_escape_string($db, $end_date);
$insert_sql = "INSERT INTO " . $table_prefix . "billing_orders
(user_id, service_id, home_name, ip, max_players, qty, invoice_duration, price, remote_control_password, ftp_password, status, end_date, payment_txid, paid_ts)
VALUES
({$esc_user_id}, {$esc_service_id}, '{$esc_home_name}', {$esc_ip}, {$esc_max_players}, {$esc_qty}, '{$esc_inv_dur}', {$esc_price}, '{$esc_rc_pass}', '{$esc_ftp_pass}', 'paid', '{$esc_end_date}', 'FREE-{$orderId}', NOW())";
$insert_res = mysqli_query($db, $insert_sql);
$new_order_id = 0;
if ($insert_res) {
$new_order_id = mysqli_insert_id($db);
// Update invoice with the new order_id
$upd_inv_order = $db->prepare("UPDATE " . $table_prefix . "billing_invoices SET order_id = ? WHERE invoice_id = ? LIMIT 1");
if ($upd_inv_order) {
$upd_inv_order->bind_param('ii', $new_order_id, $orderId);
$upd_inv_order->execute();
$upd_inv_order->close();
}
}
// write audit log (include end_date if set)
site_log_info('free_create', ['actor'=>$actor_id, 'role'=>$actor_role, 'action'=>$reason, 'invoice'=>$orderId, 'new_order'=>$new_order_id, 'owner'=>$owner_id, 'price'=>$order_price, 'prev_status'=>$prev_status, 'end_date'=>$end_date ?? '']);
// write a simulated webhook file (same behavior as previous admin flow)
$dataDir = (isset($SITE_DATA_DIR) && $SITE_DATA_DIR) ? $SITE_DATA_DIR : realpath(__DIR__ . '/') . DIRECTORY_SEPARATOR . 'data';
@mkdir($dataDir, 0775, true);
$rec = [
'event_type' => 'PAYMENT.CAPTURE.COMPLETED',
'status' => 'PAID',
'amount' => floatval($order_price),
'currency' => 'USD',
'payer' => $_SESSION['website_user_email'] ?? ($_SESSION['website_username'] ?? ''),
'invoice' => 'FREE-' . $orderId . '-' . time(),
// process_payment_record matches numeric custom values to order_id; use numeric order id here to ensure matching
'custom' => (string)$orderId,
'resource_id' => 'FREE-' . bin2hex(random_bytes(6)),
'items' => [],
'ts' => date('c'),
];
$fname = $dataDir . DIRECTORY_SEPARATOR . $rec['invoice'] . '.json';
file_put_contents($fname, json_encode($rec, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
// If available, process the payment record immediately so webhooks logic runs during creation
$ps = __DIR__ . '/payment_success.php';
if (is_file($ps)) {
try {
require_once($ps);
if (function_exists('process_payment_record')) {
process_payment_record($rec);
}
} catch (Exception $e) {
error_log('[cart create_free] process_payment_record failed: ' . $e->getMessage());
}
}
header('Location: return.php?invoice=' . urlencode($rec['invoice']));
exit;
} else {
// unauthorized attempt - log and continue
site_log_warn('unauthorized_free_create', ['actor'=>$actor_id, 'role'=>$actor_role, 'order'=>$orderId, 'owner'=>$owner_id, 'price'=>$order_price]);
}
}
}
}
// Include top bar and menu
include(__DIR__ . '/includes/top.php');
include(__DIR__ . '/includes/menu.php');
// Use session user_id where available
// Use session user_id where available; if not present but website_username exists, try to resolve it from DB
$user_id = intval($_SESSION['website_user_id'] ?? $_SESSION['user_id'] ?? 0);
if ($user_id <= 0 && isset($_SESSION['website_username']) && !empty($_SESSION['website_username'])) {
// try to resolve username to user_id in DB and persist into session
$safe_uname = mysqli_real_escape_string($db, $_SESSION['website_username']);
$qr = mysqli_query($db, "SELECT user_id FROM ogp_users WHERE users_login = '$safe_uname' LIMIT 1");
if ($qr && mysqli_num_rows($qr) === 1) {
$rr = mysqli_fetch_assoc($qr);
$user_id = intval($rr['user_id'] ?? 0);
if ($user_id > 0) {
$_SESSION['website_user_id'] = $user_id;
site_log_info('cart_resolved_user_id', ['username'=>$_SESSION['website_username'],'user_id'=>$user_id]);
// Resolve and persist the user's role to avoid extra DB lookups later
$role_q = mysqli_query($db, "SELECT users_role FROM ogp_users WHERE user_id = " . intval($user_id) . " LIMIT 1");
if ($role_q && mysqli_num_rows($role_q) === 1) {
$role_r = mysqli_fetch_assoc($role_q);
$_SESSION['website_user_role'] = $role_r['users_role'] ?? '';
}
}
} else {
site_log_warn('cart_resolve_user_failed', ['username'=>$_SESSION['website_username']]);
}
}
if ($user_id <= 0) {
echo "Please login to view your cart
";
mysqli_close($db);
echo "