165 lines
8.2 KiB
PHP
165 lines
8.2 KiB
PHP
<?php
|
|
session_start();
|
|
if (!isset($_SESSION["user_id"])) {
|
|
header("Location: login.php");
|
|
exit;
|
|
}
|
|
require_once 'db/config.php';
|
|
$db = db();
|
|
$project_name = $_SERVER['PROJECT_NAME'] ?? 'LPA Online';
|
|
|
|
// Fetch user's current credits
|
|
$stmt = $db->prepare("SELECT credits FROM users WHERE id = ?");
|
|
$stmt->execute([$_SESSION['user_id']]);
|
|
$current_credits = $stmt->fetchColumn() ?: 0;
|
|
|
|
// Fetch active packages
|
|
$packages = $db->query("SELECT * FROM credit_packages WHERE is_active = 1 ORDER BY price_amount ASC")->fetchAll();
|
|
|
|
// Fetch Stripe publishable key
|
|
$stripe_pk = $db->query("SELECT setting_value FROM stripe_config WHERE setting_key = 'stripe_publishable_key'")->fetchColumn();
|
|
|
|
// Fetch user invoices
|
|
$stmt = $db->prepare("SELECT * FROM invoices WHERE user_id = ? ORDER BY created_at DESC");
|
|
$stmt->execute([$_SESSION['user_id']]);
|
|
$invoices = $stmt->fetchAll();
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Purchase Credits — <?php echo htmlspecialchars($project_name); ?></title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<script src="https://js.stripe.com/v3/"></script>
|
|
<link href="assets/css/custom.css" rel="stylesheet">
|
|
</head>
|
|
<body class="bg-light">
|
|
<nav class="navbar navbar-expand-lg bg-white border-bottom shadow-sm">
|
|
<div class="container">
|
|
<a class="navbar-brand d-flex align-items-center" href="/dashboard.php">
|
|
<img src="assets/pasted-20260228-235417-eedda424.png" alt="<?php echo htmlspecialchars($project_name); ?>" height="40">
|
|
</a>
|
|
<div class="d-flex align-items-center">
|
|
<a href="/dashboard.php" class="btn btn-outline-primary btn-sm px-3 rounded-pill me-2">Back to Dashboard</a>
|
|
<a href="/logout.php" class="btn btn-outline-secondary btn-sm px-3 rounded-pill">Logout</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container py-5">
|
|
<div class="text-center mb-5">
|
|
<h1 class="fw-bold h2 mb-2">Refill LPA Credits</h1>
|
|
<p class="text-muted">Select the most appropriate package to continue creating your Lasting Power of Attorney documents.</p>
|
|
<div class="d-inline-block bg-white border rounded-pill px-4 py-2 mt-2 shadow-sm">
|
|
<span class="small text-muted me-2">Current Balance:</span>
|
|
<span class="fw-bold text-primary h5 mb-0"><?php echo $current_credits; ?> Credits</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 justify-content-center mb-5">
|
|
<?php foreach ($packages as $pkg): ?>
|
|
<div class="col-md-4">
|
|
<div class="card h-100 border-0 shadow-sm text-center p-4 rounded-4 transition-hover">
|
|
<div class="card-body">
|
|
<h4 class="fw-bold mb-3"><?php echo htmlspecialchars($pkg['name']); ?></h4>
|
|
<p class="text-muted small mb-4"><?php echo htmlspecialchars($pkg['description']); ?></p>
|
|
<div class="mb-4">
|
|
<span class="display-5 fw-bold"><?php echo ($pkg['price_currency'] === 'GBP' ? '£' : $pkg['price_currency']) . number_format($pkg['price_amount'], 2); ?></span>
|
|
</div>
|
|
<div class="p-3 bg-light rounded-3 mb-4">
|
|
<span class="h5 fw-bold mb-0 text-primary"><?php echo (int)$pkg['credits']; ?> LPA Credits</span>
|
|
</div>
|
|
<button onclick="checkout(<?php echo $pkg['id']; ?>)" class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-sm checkout-btn">
|
|
Select Package
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<?php if (!empty($invoices)): ?>
|
|
<div class="row justify-content-center">
|
|
<div class="col-lg-10">
|
|
<div class="card border-0 shadow-sm rounded-4 overflow-hidden">
|
|
<div class="card-header bg-white py-3 border-bottom-0">
|
|
<h5 class="fw-bold mb-0">Billing History</h5>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr class="small text-uppercase tracking-wider">
|
|
<th class="ps-4">Invoice #</th>
|
|
<th>Date</th>
|
|
<th>Amount</th>
|
|
<th>Status</th>
|
|
<th class="text-end pe-4">Receipt</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($invoices as $inv): ?>
|
|
<tr>
|
|
<td class="ps-4 fw-medium">#<?php echo htmlspecialchars($inv['invoice_number']); ?></td>
|
|
<td class="small text-muted"><?php echo date('M d, Y', strtotime($inv['created_at'])); ?></td>
|
|
<td class="fw-bold"><?php echo ($inv['currency'] === 'GBP' ? '£' : $inv['currency']) . number_format($inv['amount'], 2); ?></td>
|
|
<td>
|
|
<span class="badge rounded-pill <?php echo $inv['status'] === 'paid' ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'; ?>">
|
|
<?php echo ucfirst($inv['status']); ?>
|
|
</span>
|
|
</td>
|
|
<td class="text-end pe-4">
|
|
<?php if ($inv['status'] === 'paid'): ?>
|
|
<a href="api/generate_invoice_pdf.php?id=<?php echo $inv['id']; ?>" class="btn btn-sm btn-outline-secondary rounded-pill px-3">Download PDF</a>
|
|
<?php else: ?>
|
|
<span class="text-muted small">Pending</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<script>
|
|
const stripe = Stripe('<?php echo $stripe_pk; ?>');
|
|
|
|
function checkout(packageId) {
|
|
const btn = event.target;
|
|
const originalText = btn.innerHTML;
|
|
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Processing...';
|
|
btn.disabled = true;
|
|
|
|
fetch('api/create_checkout_session.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: 'package_id=' + packageId
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.id) {
|
|
return stripe.redirectToCheckout({ sessionId: data.id });
|
|
} else {
|
|
alert('Error: ' + (data.error || 'Failed to initialize checkout.'));
|
|
btn.innerHTML = originalText;
|
|
btn.disabled = false;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An unexpected error occurred.');
|
|
btn.innerHTML = originalText;
|
|
btn.disabled = false;
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|