Panel/modules/billing/payment_success.php
copilot-swe-agent[bot] a945b613ed
chore: polish docs url constants and provisioning log clarity
Agent-Logs-Url: https://github.com/GameServerPanel/GSP/sessions/020b5f73-a6ca-4a45-a4cb-eeef59cb26a8

Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com>
2026-05-09 00:53:29 +00:00

266 lines
9.8 KiB
PHP

<?php
/**
* Payment Success Page
* Shows order confirmation after successful PayPal payment
* Standalone billing module - uses only standard PHP mysqli
*/
session_start();
require_once(__DIR__ . '/includes/config_loader.php');
// Variables from config.inc.php (helps IDEs understand scope)
/** @var string $db_host Database host */
/** @var string $db_user Database user */
/** @var string $db_pass Database password */
/** @var string $db_name Database name */
/** @var string $table_prefix Table prefix for database tables */
// Get PayPal order ID from URL
$paypal_order_id = isset($_GET['order_id']) ? trim($_GET['order_id']) : '';
// Get user ID from session
$user_id = isset($_SESSION['website_user_id']) ? intval($_SESSION['website_user_id']) :
(isset($_SESSION['user_id']) ? intval($_SESSION['user_id']) : 0);
// Connect to database
$db = mysqli_connect($db_host, $db_user, $db_pass, $db_name, isset($db_port) ? (int)$db_port : null);
$orders = [];
$total_paid = 0;
function billing_payment_success_provision_state(array $order): array
{
$homeId = intval($order['home_id'] ?? 0);
$hasHome = intval($order['has_home'] ?? 0) > 0;
$ipPortCount = intval($order['ip_port_count'] ?? 0);
$modCount = intval($order['mod_count'] ?? 0);
if ($homeId <= 0) {
return ['label' => 'PENDING', 'message' => 'Server record is queued for provisioning.', 'class' => 'status-badge status-pending'];
}
// home_id exists but server_homes row does not: orphaned consistency failure.
if (!$hasHome) {
return ['label' => 'FAILED', 'message' => 'Provisioning error: billing order references a missing server home.', 'class' => 'status-badge status-failed'];
}
if ($ipPortCount <= 0 || $modCount <= 0) {
return ['label' => 'PENDING', 'message' => 'Server created; install is pending final IP/mod setup.', 'class' => 'status-badge status-pending'];
}
return ['label' => 'INSTALL STARTED', 'message' => 'Server created and install/update trigger has been started or queued.', 'class' => 'status-badge'];
}
if ($db && $user_id > 0) {
// Get recent orders for this user (just paid)
$query = "SELECT o.*, s.service_name,
CASE WHEN sh.home_id IS NULL THEN 0 ELSE 1 END AS has_home,
(SELECT COUNT(*) FROM {$table_prefix}home_ip_ports hip WHERE hip.home_id = o.home_id) AS ip_port_count,
(SELECT COUNT(*) FROM {$table_prefix}game_mods gm WHERE gm.home_id = o.home_id) AS mod_count
FROM {$table_prefix}billing_orders o
LEFT JOIN {$table_prefix}billing_services s ON o.service_id = s.service_id
LEFT JOIN {$table_prefix}server_homes sh ON sh.home_id = o.home_id
WHERE o.user_id = $user_id
AND o.status = 'Active'
ORDER BY o.order_date DESC
LIMIT 10";
$result = mysqli_query($db, $query);
if ($result) {
while ($row = mysqli_fetch_assoc($result)) {
$row['provision_state'] = billing_payment_success_provision_state($row);
$orders[] = $row;
$total_paid += floatval($row['price']);
}
}
mysqli_close($db);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Successful - Game Server Panel</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f5f5f5;
margin: 0;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.success-header {
text-align: center;
padding: 30px 0;
border-bottom: 2px solid #28a745;
margin-bottom: 30px;
}
.success-icon {
font-size: 64px;
color: #28a745;
margin-bottom: 20px;
}
h1 {
color: #28a745;
margin: 0 0 10px 0;
}
.subtitle {
color: #666;
font-size: 1.1em;
}
.info-box {
background: #e7f3ff;
border-left: 4px solid #007bff;
padding: 20px;
margin: 30px 0;
border-radius: 4px;
}
.info-box h3 {
margin-top: 0;
color: #007bff;
}
.info-box ul {
margin: 10px 0;
padding-left: 20px;
}
.info-box li {
margin: 8px 0;
line-height: 1.6;
}
.orders-table {
width: 100%;
border-collapse: collapse;
margin: 30px 0;
}
.orders-table th {
background: #f8f9fa;
padding: 12px;
text-align: left;
border-bottom: 2px solid #dee2e6;
font-weight: 600;
}
.orders-table td {
padding: 15px 12px;
border-bottom: 1px solid #dee2e6;
}
.status-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 0.85em;
font-weight: 600;
background: #28a745;
color: white;
}
.status-pending {
background: #f0ad4e;
}
.status-failed {
background: #d9534f;
}
.btn {
display: inline-block;
padding: 12px 24px;
margin: 10px 10px 10px 0;
background: #007bff;
color: white;
text-decoration: none;
border-radius: 5px;
font-weight: 600;
}
.btn:hover {
background: #0056b3;
}
.btn-secondary {
background: #6c757d;
}
.btn-secondary:hover {
background: #545b62;
}
.actions {
text-align: center;
margin-top: 40px;
padding-top: 30px;
border-top: 2px solid #dee2e6;
}
</style>
</head>
<body>
<div class="container">
<div class="success-header">
<div class="success-icon">✓</div>
<h1>Payment Successful!</h1>
<p class="subtitle">Your payment has been processed successfully</p>
<?php if ($paypal_order_id): ?>
<p style="color: #999; font-size: 0.9em; margin-top: 10px;">
Transaction ID: <?php echo htmlspecialchars($paypal_order_id); ?>
</p>
<?php endif; ?>
</div>
<div class="info-box">
<h3>What Happens Next?</h3>
<ul>
<li><strong>✓ Payment Confirmed:</strong> Your payment has been captured by PayPal</li>
<li><strong>⚙️ Server Provisioning:</strong> Your game server(s) are queued for automatic install now; if a node is unavailable they remain clearly marked as pending install</li>
<li><strong>📧 Email Notification:</strong> You'll receive a confirmation email with your order details</li>
<li><strong>🎮 Access Your Servers:</strong> Log into the Game Server Panel to manage your new servers</li>
</ul>
</div>
<?php if (count((array)$orders) > 0): ?>
<h2>Your Orders</h2>
<table class="orders-table">
<thead>
<tr>
<th>Order ID</th>
<th>Server Name</th>
<th>Game</th>
<th>Duration</th>
<th>Status</th>
<th title="Server Setup Status" aria-label="Server Setup Status">Provisioning</th>
<th style="text-align: right;">Price</th>
</tr>
</thead>
<tbody>
<?php foreach ((array)$orders as $order): ?>
<tr>
<td>#<?php echo htmlspecialchars($order['order_id']); ?></td>
<td><?php echo htmlspecialchars($order['home_name']); ?></td>
<td><?php echo htmlspecialchars($order['service_name'] ?? 'Game Server'); ?></td>
<td><?php echo htmlspecialchars($order['qty']); ?>x <?php echo htmlspecialchars($order['invoice_duration']); ?></td>
<td><span class="status-badge">PAID</span></td>
<td>
<span class="<?php echo htmlspecialchars($order['provision_state']['class'] ?? 'status-badge'); ?>">
<?php echo htmlspecialchars($order['provision_state']['label'] ?? 'PENDING'); ?>
</span>
<div style="margin-top:6px;color:#555;font-size:0.9em;">
<?php echo htmlspecialchars($order['provision_state']['message'] ?? 'Provisioning state unavailable.'); ?>
</div>
</td>
<td style="text-align: right; font-weight: 600; color: #28a745;">
$<?php echo number_format(floatval($order['price']), 2); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<div class="info-box" style="background: #fff3cd; border-left-color: #856404;">
<p><strong>Note:</strong> Your orders are being processed. If you don't see them listed above, please log into your account or contact support.</p>
</div>
<?php endif; ?>
<div class="actions">
<a href="/my_account.php" class="btn">View My Account</a>
<a href="/order.php" class="btn btn-secondary">Order Another Server</a>
<a href="/index.php" class="btn btn-secondary">Back to Home</a>
</div>
</div>
</body>
</html>