![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/.cursor-server/data/User/History/24159f38/ |
<?php
session_start();
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
header('Location: /auth/login.php');
exit;
}
// Check if cart has items
if (empty($_SESSION['credit_cart'])) {
header('Location: /credits.php');
exit;
}
// Check cart contents and separate items
$creditItems = [];
$trackItems = [];
foreach ($_SESSION['credit_cart'] as $item) {
if (isset($item['type'])) {
if ($item['type'] === 'credit') {
$creditItems[] = $item;
} elseif ($item['type'] === 'track') {
$trackItems[] = $item;
}
} else {
// Legacy items without type - assume they're credits
$creditItems[] = $item;
}
}
// Log cart analysis
error_log("checkout.php: Credit items: " . count($creditItems) . ", Track items: " . count($trackItems));
require_once 'config/database.php';
$user = getUserById($_SESSION['user_id']);
// Use all items for display, but process credits and tracks separately
$cart = $_SESSION['credit_cart'];
// Debug: Log cart structure
error_log("checkout.php: Cart structure = " . json_encode($cart));
// Calculate totals
$total = 0;
$totalCredits = 0;
$totalTracks = 0;
foreach ($cart as $item) {
error_log("checkout.php: Processing item = " . json_encode($item));
$total += ($item['price'] ?? 0) * ($item['quantity'] ?? 1);
if (isset($item['credits'])) {
$totalCredits += $item['credits'] * $item['quantity'];
}
if (isset($item['type']) && $item['type'] === 'track') {
$totalTracks += $item['quantity'] ?? 1;
}
}
// Set page variables for header
$page_title = 'Checkout - SoundStudioPro';
$page_description = 'Complete your credit purchase securely.';
$current_page = 'checkout';
include 'includes/header.php';
if (isset($_GET['success'])) {
echo '<script>document.addEventListener("DOMContentLoaded", function() { showSuccessMessage("Payment successful! Your credits have been added to your account."); setTimeout(() => { window.location.href = "/credits.php"; }, 2000); });</script>';
}
?>
<style>
/* Premium Checkout Page Styles */
.checkout-container {
max-width: 1400px;
margin: 0 auto;
padding: 3rem 2rem;
position: relative;
min-height: 100vh;
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0a0a0a 100%);
}
.checkout-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
pointer-events: none;
}
.checkout-header {
text-align: center;
margin-bottom: 4rem;
position: relative;
z-index: 2;
}
.checkout-title {
font-size: 4rem;
font-weight: 800;
margin-bottom: 1.5rem;
background: linear-gradient(135deg, #ffffff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
line-height: 1.2;
}
.checkout-subtitle {
color: #a0aec0;
font-size: 1.8rem;
font-weight: 400;
max-width: 600px;
margin: 0 auto;
line-height: 1.5;
}
.checkout-content {
display: grid;
grid-template-columns: 1fr 500px;
gap: 4rem;
align-items: start;
position: relative;
z-index: 2;
}
/* Order Summary Styles */
.order-summary {
background: linear-gradient(135deg, rgba(20, 20, 20, 0.95) 0%, rgba(30, 30, 30, 0.95) 100%);
border: 2px solid;
border-image: linear-gradient(135deg, #667eea, #764ba2) 1;
border-radius: 24px;
padding: 3rem;
backdrop-filter: blur(30px);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
position: relative;
}
.order-summary::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
pointer-events: none;
border-radius: 24px;
}
.summary-title {
font-size: 2.4rem;
font-weight: 700;
margin-bottom: 2.5rem;
display: flex;
align-items: center;
gap: 1rem;
background: linear-gradient(135deg, #ffffff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
z-index: 2;
}
.summary-title i {
font-size: 2.2rem;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.cart-items {
margin-bottom: 3rem;
position: relative;
z-index: 2;
}
.cart-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(102, 126, 234, 0.1);
border-radius: 16px;
margin-bottom: 1.5rem;
transition: all 0.3s ease;
}
.cart-item:hover {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(102, 126, 234, 0.2);
transform: translateY(-2px);
}
.cart-item:last-child {
margin-bottom: 0;
}
.item-details h4 {
color: white;
margin-bottom: 0.5rem;
font-size: 1.8rem;
font-weight: 600;
background: linear-gradient(135deg, #ffffff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.item-details p {
color: #a0aec0;
font-size: 1.4rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.item-details p i {
color: #667eea;
font-size: 1.2rem;
}
.item-price {
color: white;
font-weight: 700;
font-size: 1.8rem;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.total-section {
border-top: 2px solid rgba(102, 126, 234, 0.2);
padding-top: 2rem;
margin-top: 2rem;
position: relative;
z-index: 2;
}
.total-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
font-size: 1.6rem;
}
.total-row span:first-child {
color: #a0aec0;
font-weight: 500;
}
.total-row span:last-child {
color: white;
font-weight: 600;
}
.total-row.final {
font-size: 2.2rem;
font-weight: 700;
color: white;
border-top: 2px solid rgba(102, 126, 234, 0.2);
padding-top: 1.5rem;
margin-top: 1.5rem;
}
.total-row.final span:last-child {
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Payment Methods Styles */
.payment-methods {
background: linear-gradient(135deg, rgba(20, 20, 20, 0.95) 0%, rgba(30, 30, 30, 0.95) 100%);
border: 2px solid;
border-image: linear-gradient(135deg, #667eea, #764ba2) 1;
border-radius: 24px;
padding: 3rem;
backdrop-filter: blur(30px);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
position: relative;
}
.payment-methods::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
pointer-events: none;
border-radius: 24px;
}
.payment-title {
font-size: 2.4rem;
font-weight: 700;
margin-bottom: 2.5rem;
display: flex;
align-items: center;
gap: 1rem;
background: linear-gradient(135deg, #ffffff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
z-index: 2;
}
.payment-title i {
font-size: 2.2rem;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.payment-options {
display: flex;
flex-direction: column;
gap: 1.5rem;
margin-bottom: 3rem;
position: relative;
z-index: 2;
}
.payment-option {
display: flex;
align-items: center;
gap: 1.5rem;
padding: 2rem;
background: rgba(255, 255, 255, 0.03);
border: 2px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.payment-option:hover {
border-color: rgba(102, 126, 234, 0.3);
background: rgba(255, 255, 255, 0.05);
transform: translateY(-2px);
}
.payment-option.selected {
border-color: #667eea;
background: rgba(102, 126, 234, 0.1);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.2);
}
.payment-option input[type="radio"] {
display: none;
}
.payment-icon {
font-size: 2.5rem;
color: #667eea;
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(102, 126, 234, 0.1);
border-radius: 12px;
}
.payment-info h4 {
color: white;
margin-bottom: 0.5rem;
font-size: 1.8rem;
font-weight: 600;
}
.payment-info p {
color: #a0aec0;
font-size: 1.4rem;
margin: 0;
}
.payment-info p {
color: #a0aec0;
font-size: 0.9rem;
}
.pay-button {
width: 100%;
padding: 2rem;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
border: none;
border-radius: 16px;
font-size: 1.6rem;
font-weight: 700;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
position: relative;
z-index: 2;
}
.pay-button:hover {
transform: translateY(-3px);
box-shadow: 0 12px 35px rgba(102, 126, 234, 0.5);
background: linear-gradient(135deg, #5a67d8, #6b46c1);
}
.pay-button:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.back-to-cart {
display: inline-flex;
align-items: center;
gap: 0.5rem;
color: #a0aec0;
text-decoration: none;
margin-bottom: 2rem;
transition: color 0.3s ease;
}
.back-to-cart:hover {
color: white;
}
.stripe-form-container {
margin-top: 1rem;
}
.card-element {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 1rem;
margin-bottom: 1rem;
min-height: 60px;
}
.card-errors {
color: #ff6b6b;
font-size: 0.9rem;
margin-bottom: 1rem;
min-height: 20px;
}
.payment-summary {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 2rem;
}
.summary-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.8rem;
color: #a0aec0;
}
.summary-row.total {
color: white;
font-weight: 600;
font-size: 1.1rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: 0.8rem;
margin-top: 0.8rem;
}
.payment-actions {
display: flex;
gap: 1rem;
}
.pay-button.secondary {
background: rgba(255, 255, 255, 0.1);
color: #a0aec0;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.pay-button.secondary:hover {
background: rgba(255, 255, 255, 0.15);
color: white;
transform: none;
box-shadow: none;
}
/* Responsive Design */
@media (max-width: 1024px) {
.checkout-content {
grid-template-columns: 1fr;
gap: 3rem;
}
.checkout-title {
font-size: 3rem;
}
.checkout-subtitle {
font-size: 1.5rem;
}
}
@media (max-width: 768px) {
.checkout-container {
padding: 2rem 1rem;
}
.checkout-title {
font-size: 2.5rem;
}
.checkout-subtitle {
font-size: 1.3rem;
}
.order-summary,
.payment-methods {
padding: 2rem;
}
.summary-title,
.payment-title {
font-size: 2rem;
}
.cart-item {
padding: 1.5rem;
}
.item-details h4 {
font-size: 1.5rem;
}
.item-details p {
font-size: 1.2rem;
}
.item-price {
font-size: 1.5rem;
}
.payment-actions {
flex-direction: column;
}
.pay-button {
padding: 1.5rem;
font-size: 1.4rem;
}
}
@media (max-width: 480px) {
.checkout-title {
font-size: 2rem;
}
.checkout-subtitle {
font-size: 1.1rem;
}
.order-summary,
.payment-methods {
padding: 1.5rem;
}
.summary-title,
.payment-title {
font-size: 1.8rem;
}
.cart-item {
padding: 1rem;
}
.payment-option {
padding: 1.5rem;
}
.payment-icon {
width: 50px;
height: 50px;
font-size: 2rem;
}
}
.success-message {
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 1rem 1.5rem;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(102, 126, 234, 0.3);
z-index: 10000;
animation: slideIn 0.3s ease-out;
}
.success-content {
display: flex;
align-items: center;
gap: 0.8rem;
}
.success-content i {
font-size: 1.2rem;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.btn-primary {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
</style>
<div class="checkout-container">
<div class="checkout-header">
<h1 class="checkout-title">Complete Your Purchase</h1>
<p class="checkout-subtitle">Secure payment processing with industry-leading encryption</p>
</div>
<div class="checkout-content">
<!-- Order Summary -->
<div class="order-summary">
<h2 class="summary-title">
<i class="fas fa-shopping-cart"></i>
Order Summary
</h2>
<div class="cart-items">
<!-- Debug: Show cart contents -->
<?php if (isset($_GET['debug']) || true): ?>
<div style="background: rgba(255,0,0,0.1); padding: 10px; margin: 10px 0; border: 1px solid red; color: white;">
<strong>DEBUG:</strong> Cart contains <?= count($cart) ?> items<br>
<?php foreach ($cart as $index => $item): ?>
Item <?= $index ?>: <?= json_encode($item) ?><br>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (empty($cart)): ?>
<div class="empty-cart">
<i class="fas fa-shopping-bag"></i>
<p>Your cart is empty</p>
</div>
<?php else: ?>
<?php foreach ($cart as $item): ?>
<div class="cart-item">
<div class="item-details">
<?php if (isset($item['type']) && $item['type'] === 'credit'): ?>
<h4><?= htmlspecialchars(ucfirst($item['package'])) ?> Package</h4>
<p>
<i class="fas fa-coins"></i>
<?= $item['credits'] ?> credits × <?= $item['quantity'] ?>
</p>
<?php elseif (isset($item['type']) && $item['type'] === 'track'): ?>
<h4><?= htmlspecialchars($item['title']) ?></h4>
<p>
<i class="fas fa-music"></i>
by <?= htmlspecialchars($item['artist']) ?> × <?= $item['quantity'] ?>
</p>
<?php else: ?>
<!-- Fallback for items without type (legacy support) -->
<h4><?= htmlspecialchars(ucfirst($item['package'] ?? 'Unknown')) ?> Package</h4>
<p>
<i class="fas fa-coins"></i>
<?= $item['credits'] ?? 0 ?> credits × <?= $item['quantity'] ?>
</p>
<?php endif; ?>
</div>
<div class="item-price">$<?= number_format($item['price'] * $item['quantity'], 2) ?></div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="total-section">
<?php if ($totalCredits > 0): ?>
<div class="total-row">
<span>Credits to Add:</span>
<span><?= $totalCredits ?> credits</span>
</div>
<?php endif; ?>
<?php if ($totalTracks > 0): ?>
<div class="total-row">
<span>Tracks to Purchase:</span>
<span><?= $totalTracks ?> tracks</span>
</div>
<?php endif; ?>
<div class="total-row">
<span>Subtotal:</span>
<span>$<?= number_format($total, 2) ?></span>
</div>
<div class="total-row">
<span>Tax:</span>
<span>$0.00</span>
</div>
<div class="total-row final">
<span>Total:</span>
<span>$<?= number_format($total, 2) ?></span>
</div>
</div>
</div>
<!-- Payment Methods -->
<div class="payment-methods" id="paymentMethodsSection">
<h2 class="payment-title">
<i class="fas fa-credit-card"></i>
Payment Method
</h2>
<div class="payment-options">
<label class="payment-option selected" onclick="selectPaymentMethod('stripe')">
<input type="radio" name="payment_method" value="stripe" checked>
<div class="payment-icon">
<i class="fas fa-credit-card"></i>
</div>
<div class="payment-info">
<h4>Credit Card</h4>
<p>Pay securely with Visa, Mastercard, American Express, or Discover</p>
</div>
</label>
<label class="payment-option" onclick="selectPaymentMethod('paypal')">
<input type="radio" name="payment_method" value="paypal">
<div class="payment-icon">
<i class="fab fa-paypal"></i>
</div>
<div class="payment-info">
<h4>PayPal</h4>
<p>Pay with your PayPal account or credit card</p>
</div>
</label>
</div>
<button class="pay-button" onclick="processPayment()">
<i class="fas fa-shield-alt"></i>
Pay Securely $<?= number_format($total, 2) ?>
</button>
</div>
<!-- Stripe Payment Form (Hidden by default) -->
<div class="payment-methods" id="stripePaymentForm" style="display: none;">
<h2 class="payment-title">
<i class="fas fa-credit-card"></i>
Credit Card Payment
</h2>
<div class="stripe-form-container">
<div id="card-element" class="card-element"></div>
<div id="card-errors" class="card-errors" role="alert"></div>
<div class="payment-summary">
<div class="summary-row">
<span>Subtotal:</span>
<span>$<?= number_format($total, 2) ?></span>
</div>
<div class="summary-row">
<span>Tax:</span>
<span>$0.00</span>
</div>
<div class="summary-row total">
<span>Total:</span>
<span>$<?= number_format($total, 2) ?></span>
</div>
</div>
<div class="payment-actions">
<button class="pay-button secondary" onclick="backToPaymentMethods()">
<i class="fas fa-arrow-left"></i>
Back
</button>
<button class="pay-button" id="stripe-pay-button" onclick="confirmStripePayment()">
<i class="fas fa-lock"></i>
Pay $<?= number_format($total, 2) ?>
</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripe = Stripe('pk_live_51Rn8TtD0zXLMB4gHMCZ5OMunyo0YtN6hBR30BoXFEiQxPG9I6U2tko6Axxwl0yJS21DCCykhC9PxAMdZoEfwJI0p00KlrZUR3w');
let selectedPaymentMethod = 'stripe';
let elements;
let cardElement;
let paymentIntent;
// Test Stripe loading
console.log('🎯 Stripe loaded:', !!stripe);
function selectPaymentMethod(method) {
selectedPaymentMethod = method;
// Update UI
document.querySelectorAll('.payment-option').forEach(option => {
option.classList.remove('selected');
});
event.currentTarget.classList.add('selected');
event.currentTarget.querySelector('input[type="radio"]').checked = true;
}
async function processPayment() {
const payButton = document.querySelector('.pay-button');
const originalText = payButton.innerHTML;
console.log('🎯 Starting payment process...');
console.log('🎯 Selected payment method:', selectedPaymentMethod);
console.log('🎯 Pay button clicked - about to show Stripe form');
try {
payButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Processing...';
payButton.disabled = true;
if (selectedPaymentMethod === 'stripe') {
console.log('🎯 Processing with Stripe...');
// Show Stripe payment form
await showStripePaymentForm();
// Reset button since we're showing the form
payButton.innerHTML = originalText;
payButton.disabled = false;
} else if (selectedPaymentMethod === 'paypal') {
console.log('🎯 Processing with PayPal...');
// Process with PayPal
// Format cart data to match backend expectations
const formattedCart = <?= json_encode($cart) ?>.map(item => ({
package: item.package,
quantity: item.quantity
}));
const response = await fetch('process_credit_payment.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'process_paypal_payment',
cart: formattedCart
})
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error);
}
// Redirect to PayPal
window.location.href = result.paypal_url;
}
} catch (error) {
console.error('Payment error:', error);
console.error('Error details:', error);
let errorMessage = 'Payment failed: ' + error.message;
// Try to get more specific error details
if (error.response) {
try {
const errorData = await error.response.json();
errorMessage = 'Payment failed: ' + (errorData.error || error.message);
} catch (e) {
errorMessage = 'Payment failed: HTTP ' + error.response.status;
}
}
alert(errorMessage);
payButton.innerHTML = originalText;
payButton.disabled = false;
}
}
async function showStripePaymentForm() {
console.log('🎯 showStripePaymentForm() called');
try {
console.log('🎯 Creating Stripe payment intent...');
// Create payment intent first
// Debug: Log the raw cart data
const rawCartData = <?= json_encode($cart) ?>;
console.log('🎯 Raw cart data:', rawCartData);
console.log('🎯 Raw cart data type:', typeof rawCartData);
console.log('🎯 Raw cart data length:', rawCartData ? rawCartData.length : 'null');
// Format cart data to match backend expectations
if (!rawCartData || !Array.isArray(rawCartData) || rawCartData.length === 0) {
throw new Error('Cart is empty or invalid');
}
// Separate credit and track items
const creditItems = [];
const trackItems = [];
rawCartData.forEach(item => {
console.log('🎯 Processing cart item:', item);
if (item.type === 'credit' || !item.type) {
creditItems.push({
package: item.package,
quantity: item.quantity || 1
});
} else if (item.type === 'track') {
// Check if track_id exists
if (!item.track_id) {
console.error('❌ Track item missing track_id:', item);
throw new Error('Track item missing track_id: ' + JSON.stringify(item));
}
trackItems.push({
track_id: item.track_id,
title: item.title,
artist: item.artist,
price: item.price,
quantity: item.quantity || 1
});
} else {
throw new Error('Unknown item type: ' + item.type);
}
});
console.log('🎯 Credit items:', creditItems);
console.log('🎯 Track items:', trackItems);
// For now, let's just process credits to get the form working
// TODO: Fix track processing later
const formattedCart = creditItems;
console.log('🎯 Formatted cart:', formattedCart);
const response = await fetch('process_credit_payment.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'process_cart_payment',
cart: formattedCart
})
});
console.log('🎯 API response status:', response.status);
console.log('🎯 API response headers:', response.headers);
const responseText = await response.text();
console.log('🎯 API response text:', responseText);
// Check if response is empty
if (!responseText || responseText.trim() === '') {
throw new Error('Empty response from server - this indicates a PHP error');
}
let result;
try {
result = JSON.parse(responseText);
} catch (parseError) {
console.error('❌ JSON parse error:', parseError);
console.error('❌ Response text:', responseText);
throw new Error('Invalid response from server: ' + responseText);
}
console.log('🎯 Payment intent response:', result);
if (!result.success) {
throw new Error(result.error || 'Unknown error');
}
paymentIntent = result.client_secret;
// Hide payment methods, show Stripe form
console.log('🎯 Switching to Stripe form...');
const paymentMethodsSection = document.getElementById('paymentMethodsSection');
const stripePaymentForm = document.getElementById('stripePaymentForm');
console.log('🎯 paymentMethodsSection found:', !!paymentMethodsSection);
console.log('🎯 stripePaymentForm found:', !!stripePaymentForm);
if (!paymentMethodsSection || !stripePaymentForm) {
throw new Error('Payment form elements not found');
}
paymentMethodsSection.style.display = 'none';
stripePaymentForm.style.display = 'block';
// Create Stripe Elements
console.log('🎯 Creating Stripe Elements...');
elements = stripe.elements();
cardElement = elements.create('card', {
style: {
base: {
color: '#ffffff',
fontSize: '16px',
'::placeholder': {
color: '#a0aec0',
},
backgroundColor: 'transparent',
},
invalid: {
color: '#ff6b6b',
},
},
});
console.log('🎯 Mounting card element...');
cardElement.mount('#card-element');
console.log('🎯 Card element mounted successfully!');
console.log('🎯 Stripe form ready!');
// Handle real-time validation errors
cardElement.addEventListener('change', function(event) {
const displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
} catch (error) {
console.error('Error showing Stripe form:', error);
console.error('Error details:', error);
let errorMessage = 'Error loading payment form: ' + error.message;
// Try to get more specific error details
if (error.response) {
try {
const errorData = await error.response.json();
errorMessage = 'Error loading payment form: ' + (errorData.error || error.message);
} catch (e) {
errorMessage = 'Error loading payment form: HTTP ' + error.response.status;
}
}
alert(errorMessage);
throw error; // Re-throw so the calling function can handle it
}
}
function backToPaymentMethods() {
document.getElementById('stripePaymentForm').style.display = 'none';
document.getElementById('paymentMethodsSection').style.display = 'block';
// Clean up Stripe Elements
if (cardElement) {
cardElement.destroy();
cardElement = null;
}
}
async function confirmStripePayment() {
if (!paymentIntent || !cardElement) {
alert('Payment form not ready. Please try again.');
return;
}
const payButton = document.getElementById('stripe-pay-button');
const originalText = payButton.innerHTML;
try {
payButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Processing...';
payButton.disabled = true;
const { error } = await stripe.confirmPayment({
elements: elements,
confirmParams: {
return_url: window.location.origin + '/checkout.php?success=1',
},
});
if (error) {
throw new Error(error.message);
}
// Payment successful - redirect will happen automatically
showSuccessMessage('Payment successful! Redirecting...');
} catch (error) {
console.error('Payment error:', error);
alert('Payment failed: ' + error.message);
payButton.innerHTML = originalText;
payButton.disabled = false;
}
}
function showSuccessMessage(message) {
const successDiv = document.createElement('div');
successDiv.className = 'success-message';
successDiv.innerHTML = `
<div class="success-content">
<i class="fas fa-check-circle"></i>
<p>${message}</p>
</div>
`;
document.body.appendChild(successDiv);
setTimeout(() => {
successDiv.remove();
}, 3000);
}
</script>
<?php include 'includes/footer.php'; ?>