diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 57cd0554..b97ca1fd 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -14,7 +14,7 @@
- `modules/` — panel modules (legacy `billing/` exists; its **schema** is authoritative for multi-remote, but the **pages** are deprecated).
- `includes/` — panel configuration and DB connectors.
- `ogp_api.php` — internal API entry point for panel-side actions.
-- `paypal/` — PayPal code if present in this branch.
+- `api/` — Payment-related API code if present in this branch (previously under `paypal/` or `payments/`).
## 2) No-Code Planning Mode (default)
- Do **not** emit PHP, SQL, XML, or shell commands unless a maintainer explicitly asks: **“Generate code now.”**
@@ -72,7 +72,7 @@
- **Licensing:** Preserve upstream notices and ensure our additions stay license-compatible.
## 7) Validation checklist (pre-PR / pre-merge)
-- Read `_website/`, `modules/config_games/server_configs/`, `modules/`, `includes/`, `paypal/` (if present), and `ogp_api.php` to anchor proposals to actual code.
+- Read `_website/`, `modules/config_games/server_configs/`, `modules/`, `includes/`, `api/` (if present), and `ogp_api.php` to anchor proposals to actual code.
- Catalog uses only the XML metadata; no hardcoded ports/params.
- Regions/nodes are read live from the panel DB; no duplicates on the website.
- Auth plan preserves panel compatibility and modernizes website hashing; **sessions remain separate**.
diff --git a/_website/cart.php b/_website/cart.php
deleted file mode 100644
index 0f46e69f..00000000
--- a/_website/cart.php
+++ /dev/null
@@ -1,329 +0,0 @@
-
-
-
-
-
- Shopping Cart - GameServers.World
-
-
- 0) {
- $stmt = $db->prepare("UPDATE ogp_billing_orders SET status = 'paid' WHERE order_id = ? LIMIT 1");
- if ($stmt) { $stmt->bind_param('i', $orderId); $stmt->execute(); $stmt->close(); }
-
- // write a simulated webhook file
- require_once(__DIR__ . '/includes/config.inc.php');
- $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' => 0.00,
- 'currency' => 'USD',
- 'payer' => $_SESSION['website_user_email'] ?? ($_SESSION['website_username'] ?? ''),
- 'invoice' => 'FREE-' . $orderId . '-' . time(),
- 'custom' => 'admin_free_create_order_' . $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));
- header('Location: return.php?invoice=' . urlencode($rec['invoice']));
- exit;
- }
- }
-}
-
-// Include top bar and menu
-include(__DIR__ . '/includes/top.php');
-include(__DIR__ . '/includes/menu.php');
-
-$user_id=$_SESSION['user_id'] ?? 0;
-$user_id = 186; // For testing purposes, set a default user ID
-
-if ($user_id <= 0) {
- echo "Please login to view your cart
";
- mysqli_close($db);
- echo "";
- return;
-}
-
-
-
-if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_single'])) {
- $order_id = intval($_POST['delete_single']);
- if ($order_id > 0) {
- // First, check if the status is 'renew'
- $stmt = $db->prepare("SELECT status FROM ogp_billing_orders WHERE order_id = ? AND user_id = ?");
- $stmt->bind_param("ii", $order_id, $user_id);
- $stmt->execute();
- $stmt->bind_result($status);
- if ($stmt->fetch() && strtolower($status) === 'renew') {
- $stmt->close();
- // Set status to 'expired' if currently 'renew'
- $update = $db->prepare("UPDATE ogp_billing_orders SET status = 'expired' WHERE order_id = ? AND user_id = ?");
- $update->bind_param("ii", $order_id, $user_id);
- $update->execute();
- $update->close();
- } else {
- $stmt->close();
- // Otherwise, delete the order
- $delete = $db->prepare("DELETE FROM ogp_billing_orders WHERE order_id = ? AND user_id = ?");
- $delete->bind_param("ii", $order_id, $user_id);
- $delete->execute();
- $delete->close();
- }
- }
-}
-
-if ($db){
- $carts = $db->query("SELECT * FROM ogp_billing_orders AS cart
- WHERE (status = 'in-cart' OR status = 'renew') AND user_id = " . $user_id . " ORDER BY order_id ASC");
-
-
-
-}
-
-?>
-
-
-
Your Cart
-
-
-
-
-
-
- |
- Server ID |
- Game Name |
- Location |
- Max Players |
- Price per Player |
- Months |
- Total |
-
-
-
- num_rows > 0) {
- while ($row = $carts->fetch_assoc()) {
- ?>
-
- |
-
- |
- |
- |
- |
- |
- $ |
- |
-
-
-
-
- |
-
- |
-
-
- $ |
-
-
-
-
-
- |
- Cart Total:
- |
-
- $
- |
-
-
-
- | No items in your cart. |
-
-
-
-
-
-
-'srv123','amount'=>9.99], ['serverID'=>'srv999','amount'=>14.50]]
-
-// --- Sanity + normalization ---
-if (!isset($grandTotal) || !is_numeric($grandTotal)) {
- $grandTotal = 0.00;
-}
-if (!isset($invoice) || !is_array($invoice)) {
- $invoice = [];
-}
-$currency = 'USD';
-$amount = number_format((float)$grandTotal, 2, '.', '');
-$lineItems = [];
-
-// Build PayPal-friendly items array (name, unit_amount, quantity, sku)
-foreach ($invoice as $i) {
- $sid = isset($i['serverID']) ? (string)$i['serverID'] : 'unknown';
- $amt = isset($i['amount']) && is_numeric($i['amount']) ? number_format((float)$i['amount'], 2, '.', '') : '0.00';
- $lineItems[] = [
- 'name' => "Server $sid",
- 'quantity' => '1',
- 'unit_amount' => ['currency_code' => $currency, 'value' => $amt],
- 'sku' => $sid
- ];
-}
-
-// Single overall invoice id for the order
-$invoiceId = 'INV-' . date('Ymd-His') . '-' . bin2hex(random_bytes(3));
-
-// A short custom reference derived from your line items (<= 127 chars for PayPal)
-$customHash = substr(strtoupper(sha1(json_encode($invoice))), 0, 16);
-$customId = "INVREF-$customHash";
-
-// Text on the PayPal side
-$description = 'Game server order (' . count($lineItems) . ' item' . (count($lineItems)===1?'': 's') . ')';
-
-// URLs
-$siteBase = 'https://panel.iaregamer.com';
-$returnUrl = $siteBase . '/_website/return.php?invoice=' . urlencode($invoiceId);
-$cancelUrl = $siteBase . '/_website/return.php?invoice=' . urlencode($invoiceId) . '&cancel=1';
-
-// API base (relative)
-$apiBase = '/_website/api';
-?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-