![]() 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/domains/soundstudiopro.com/private_html/ |
<?php
session_start();
// Check if user is logged in
$is_logged_in = isset($_SESSION['user_id']);
// If not logged in, show checkout with login/register options instead of redirecting
if (!$is_logged_in) {
// Allow guest checkout or show login/register options
$guest_checkout = true;
} else {
$guest_checkout = false;
}
// 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';
require_once 'includes/site_settings_helper.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'])) {
// Send confirmation email if payment was successful
if (isset($_SESSION['user_id']) && isset($_SESSION['last_payment_data'])) {
require_once 'config/email.php';
$user = getUserById($_SESSION['user_id']);
$payment_data = $_SESSION['last_payment_data'];
if ($user && $payment_data) {
// Generate and send confirmation email
$email_data = generateOrderConfirmationEmail(
$user['name'],
$payment_data['order_details'],
$payment_data['billing_address']
);
$email_sent = sendEmail(
$payment_data['billing_address']['billing_email'],
$user['name'],
$email_data['subject'],
$email_data['html'],
$email_data['text']
);
if ($email_sent) {
error_log("Confirmation email sent successfully to: " . $payment_data['billing_address']['billing_email']);
} else {
error_log("Failed to send confirmation email to: " . $payment_data['billing_address']['billing_email']);
}
// Clear the payment data from session
unset($_SESSION['last_payment_data']);
}
}
echo '<script>document.addEventListener("DOMContentLoaded", function() { showSuccessMessage("Payment successful! Your credits have been added to your account. Check your email for confirmation."); setTimeout(() => { window.location.href = "/credits.php"; }, 3000); });</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;
}
/* Coupon Section Styles */
.coupon-section {
margin: 2rem 0;
padding: 2rem;
background: rgba(102, 126, 234, 0.1);
border-radius: 16px;
border: 1px solid rgba(102, 126, 234, 0.3);
}
.coupon-input {
display: flex;
gap: 1rem;
margin-bottom: 1rem;
}
.coupon-input-field {
flex: 1;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 1.2rem 1.5rem;
color: white;
font-size: 1.4rem;
transition: all 0.3s ease;
}
.coupon-input-field::placeholder {
color: #a0aec0;
}
.coupon-input-field:focus {
outline: none;
border-color: #667eea;
background: rgba(255, 255, 255, 0.15);
}
.coupon-message {
font-size: 1.3rem;
font-weight: 600;
min-height: 2rem;
}
.coupon-message.success {
color: #48bb78;
}
.coupon-message.error {
color: #f56565;
}
/* Authentication Section Styles */
.checkout-auth-section {
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);
margin-bottom: 2rem;
}
.auth-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;
}
.auth-tabs {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 1rem;
}
.auth-tab {
background: transparent;
border: 2px solid rgba(102, 126, 234, 0.3);
color: #a0aec0;
padding: 1rem 2rem;
border-radius: 12px;
font-size: 1.4rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.8rem;
}
.auth-tab:hover {
border-color: #667eea;
color: #667eea;
transform: translateY(-2px);
}
.auth-tab.active {
background: linear-gradient(135deg, #667eea, #764ba2);
border-color: #667eea;
color: white;
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
}
.auth-content {
display: none;
}
.auth-content.active {
display: block;
}
.auth-form {
margin-bottom: 2rem;
}
.auth-divider {
text-align: center;
margin: 2rem 0;
position: relative;
}
.auth-divider::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
background: rgba(255, 255, 255, 0.2);
}
.auth-divider span {
background: #1a1a1a;
padding: 0 2rem;
color: #a0aec0;
font-size: 1.4rem;
}
.social-login {
display: flex;
flex-direction: column;
gap: 1rem;
}
.btn-social {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
color: white;
padding: 1.2rem 2rem;
border-radius: 12px;
font-size: 1.4rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
}
.btn-social:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-2px);
}
.btn-google:hover {
background: linear-gradient(135deg, #ea4335, #fbbc05);
}
.btn-facebook:hover {
background: linear-gradient(135deg, #1877f2, #42a5f5);
}
.guest-info {
text-align: center;
margin-bottom: 2rem;
padding: 2rem;
background: rgba(102, 126, 234, 0.1);
border-radius: 16px;
border: 1px solid rgba(102, 126, 234, 0.3);
}
.guest-info i {
font-size: 4rem;
color: #667eea;
margin-bottom: 1rem;
}
.guest-info h3 {
font-size: 2rem;
color: white;
margin-bottom: 1rem;
}
.guest-info p {
color: #a0aec0;
font-size: 1.4rem;
margin-bottom: 1.5rem;
line-height: 1.6;
}
.guest-info ul {
list-style: none;
padding: 0;
text-align: left;
max-width: 300px;
margin: 0 auto;
}
.guest-info li {
color: #a0aec0;
font-size: 1.3rem;
margin-bottom: 0.5rem;
padding-left: 1.5rem;
position: relative;
}
.guest-info li::before {
content: '✓';
position: absolute;
left: 0;
color: #48bb78;
font-weight: bold;
}
/* Billing Address Styles */
.billing-address {
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;
margin-bottom: 2rem;
}
.billing-address::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;
}
.billing-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;
}
.billing-title i {
font-size: 2.2rem;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.address-form {
position: relative;
z-index: 2;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin-bottom: 1.5rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
color: #ffffff;
font-weight: 600;
font-size: 1rem;
}
.form-group input,
.form-group select {
width: 100%;
padding: 1rem 1.2rem;
background: rgba(255, 255, 255, 0.05);
border: 2px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
color: #ffffff;
font-size: 1rem;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #667eea;
background: rgba(255, 255, 255, 0.08);
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-group input::placeholder {
color: #a0aec0;
}
.form-group select option {
background: #1a1a1a;
color: #ffffff;
}
/* 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">
<?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_name'] ?? $item['artist'] ?? 'Unknown 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>
<!-- Coupon Code Section -->
<div class="coupon-section">
<div class="coupon-input">
<input type="text" id="couponCode" placeholder="Have a coupon? Enter code here" class="coupon-input-field">
<button type="button" onclick="applyCoupon()" class="btn btn-secondary">
<i class="fas fa-tag"></i>
Apply
</button>
</div>
<div id="couponMessage" class="coupon-message"></div>
</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>
<?php if (!$is_logged_in): ?>
<!-- Login/Registration Section -->
<div class="checkout-auth-section" id="checkoutAuthSection">
<h2 class="auth-title">
<i class="fas fa-user"></i>
Account Options
</h2>
<div class="auth-options">
<div class="auth-tabs">
<button class="auth-tab active" onclick="switchAuthTab('login')">
<i class="fas fa-sign-in-alt"></i>
Returning Customer
</button>
<button class="auth-tab" onclick="switchAuthTab('register')">
<i class="fas fa-user-plus"></i>
Create Account
</button>
<button class="auth-tab" onclick="switchAuthTab('guest')">
<i class="fas fa-shopping-cart"></i>
Guest Checkout
</button>
</div>
<!-- Login Form -->
<div class="auth-content active" id="loginContent">
<form class="auth-form" id="loginForm">
<div class="form-group">
<label for="login_email">Email Address</label>
<input type="email" id="login_email" name="login_email" required>
</div>
<div class="form-group">
<label for="login_password">Password</label>
<input type="password" id="login_password" name="login_password" required>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-sign-in-alt"></i>
Login & Continue
</button>
</form>
<div class="auth-divider">
<span>or</span>
</div>
<div class="social-login">
<button class="btn btn-social btn-google">
<i class="fab fa-google"></i>
Continue with Google
</button>
<button class="btn btn-social btn-facebook">
<i class="fab fa-facebook"></i>
Continue with Facebook
</button>
</div>
</div>
<!-- Registration Form -->
<div class="auth-content" id="registerContent">
<form class="auth-form" id="registerForm">
<div class="form-row">
<div class="form-group">
<label for="register_first_name">First Name</label>
<input type="text" id="register_first_name" name="register_first_name" required>
</div>
<div class="form-group">
<label for="register_last_name">Last Name</label>
<input type="text" id="register_last_name" name="register_last_name" required>
</div>
</div>
<div class="form-group">
<label for="register_email">Email Address</label>
<input type="email" id="register_email" name="register_email" required>
</div>
<div class="form-group">
<label for="register_password">Password</label>
<input type="password" id="register_password" name="register_password" required>
</div>
<div class="form-group">
<label for="register_confirm_password">Confirm Password</label>
<input type="password" id="register_confirm_password" name="register_confirm_password" required>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-user-plus"></i>
Create Account & Continue
</button>
</form>
</div>
<!-- Guest Checkout -->
<div class="auth-content" id="guestContent">
<div class="guest-info">
<i class="fas fa-info-circle"></i>
<h3>Guest Checkout</h3>
<p>Complete your purchase without creating an account. You can create an account later to access your purchases.</p>
<ul>
<li>✓ Quick checkout process</li>
<li>✓ No account required</li>
<li>✓ Secure payment processing</li>
<li>✓ Email confirmation</li>
</ul>
</div>
<button type="button" class="btn btn-primary" onclick="proceedAsGuest()">
<i class="fas fa-shopping-cart"></i>
Continue as Guest
</button>
</div>
</div>
</div>
<?php endif; ?>
<!-- Billing Address -->
<div class="billing-address" id="billingAddressSection" <?= !$is_logged_in ? 'style="display: none;"' : '' ?>>
<h2 class="billing-title">
<i class="fas fa-map-marker-alt"></i>
Billing Address
</h2>
<div class="address-form">
<div class="form-row">
<div class="form-group">
<label for="billing_first_name">First Name *</label>
<input type="text" id="billing_first_name" name="billing_first_name" required>
</div>
<div class="form-group">
<label for="billing_last_name">Last Name *</label>
<input type="text" id="billing_last_name" name="billing_last_name" required>
</div>
</div>
<div class="form-group">
<label for="billing_email">Email Address *</label>
<input type="email" id="billing_email" name="billing_email" value="<?= htmlspecialchars($user['email'] ?? '') ?>" required>
</div>
<div class="form-group">
<label for="billing_address">Street Address *</label>
<input type="text" id="billing_address" name="billing_address" required>
</div>
<div class="form-row">
<div class="form-group">
<label for="billing_city">City *</label>
<input type="text" id="billing_city" name="billing_city" required>
</div>
<div class="form-group">
<label for="billing_state">State/Province *</label>
<input type="text" id="billing_state" name="billing_state" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="billing_zip">ZIP/Postal Code *</label>
<input type="text" id="billing_zip" name="billing_zip" required>
</div>
<div class="form-group">
<label for="billing_country">Country *</label>
<select id="billing_country" name="billing_country" required>
<option value="">Select Country</option>
<option value="US" selected>United States</option>
<option value="CA">Canada</option>
<option value="GB">United Kingdom</option>
<option value="AU">Australia</option>
<option value="DE">Germany</option>
<option value="FR">France</option>
<option value="JP">Japan</option>
<option value="MX">Mexico</option>
<option value="BR">Brazil</option>
<option value="IN">India</option>
<option value="CN">China</option>
<option value="KR">South Korea</option>
<option value="IT">Italy</option>
<option value="ES">Spain</option>
<option value="NL">Netherlands</option>
<option value="SE">Sweden</option>
<option value="NO">Norway</option>
<option value="DK">Denmark</option>
<option value="FI">Finland</option>
<option value="CH">Switzerland</option>
<option value="AT">Austria</option>
<option value="BE">Belgium</option>
<option value="IE">Ireland</option>
<option value="NZ">New Zealand</option>
<option value="SG">Singapore</option>
<option value="HK">Hong Kong</option>
<option value="TW">Taiwan</option>
<option value="IL">Israel</option>
<option value="ZA">South Africa</option>
<option value="AR">Argentina</option>
<option value="CL">Chile</option>
<option value="CO">Colombia</option>
<option value="PE">Peru</option>
<option value="VE">Venezuela</option>
<option value="UY">Uruguay</option>
<option value="PY">Paraguay</option>
<option value="BO">Bolivia</option>
<option value="EC">Ecuador</option>
<option value="GY">Guyana</option>
<option value="SR">Suriname</option>
<option value="GF">French Guiana</option>
<option value="FK">Falkland Islands</option>
<option value="GS">South Georgia</option>
<option value="BV">Bouvet Island</option>
<option value="HM">Heard Island</option>
<option value="TF">French Southern Territories</option>
<option value="AQ">Antarctica</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="CX">Christmas Island</option>
<option value="CC">Cocos Islands</option>
<option value="NF">Norfolk Island</option>
<option value="NC">New Caledonia</option>
<option value="PF">French Polynesia</option>
<option value="YT">Mayotte</option>
<option value="RE">Réunion</option>
<option value="BL">Saint Barthélemy</option>
<option value="MF">Saint Martin</option>
<option value="PM">Saint Pierre and Miquelon</option>
<option value="WF">Wallis and Futuna</option>
<option value="AW">Aruba</option>
<option value="CW">Curaçao</option>
<option value="SX">Sint Maarten</option>
<option value="BQ">Caribbean Netherlands</option>
<option value="AI">Anguilla</option>
<option value="BM">Bermuda</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="KY">Cayman Islands</option>
<option value="FK">Falkland Islands</option>
<option value="GI">Gibraltar</option>
<option value="MS">Montserrat</option>
<option value="PN">Pitcairn Islands</option>
<option value="SH">Saint Helena</option>
<option value="TC">Turks and Caicos Islands</option>
<option value="VG">British Virgin Islands</option>
<option value="VI">U.S. Virgin Islands</option>
<option value="PR">Puerto Rico</option>
<option value="GU">Guam</option>
<option value="MP">Northern Mariana Islands</option>
<option value="AS">American Samoa</option>
<option value="UM">U.S. Minor Outlying Islands</option>
<option value="PS">Palestine</option>
<option value="EH">Western Sahara</option>
<option value="SS">South Sudan</option>
<option value="XK">Kosovo</option>
<option value="AX">Åland Islands</option>
<option value="FO">Faroe Islands</option>
<option value="GL">Greenland</option>
<option value="IS">Iceland</option>
<option value="LI">Liechtenstein</option>
<option value="MC">Monaco</option>
<option value="SM">San Marino</option>
<option value="VA">Vatican City</option>
<option value="AD">Andorra</option>
<option value="MT">Malta</option>
<option value="CY">Cyprus</option>
<option value="GR">Greece</option>
<option value="PT">Portugal</option>
<option value="LU">Luxembourg</option>
<option value="SI">Slovenia</option>
<option value="SK">Slovakia</option>
<option value="CZ">Czech Republic</option>
<option value="PL">Poland</option>
<option value="HU">Hungary</option>
<option value="RO">Romania</option>
<option value="BG">Bulgaria</option>
<option value="HR">Croatia</option>
<option value="RS">Serbia</option>
<option value="ME">Montenegro</option>
<option value="BA">Bosnia and Herzegovina</option>
<option value="MK">North Macedonia</option>
<option value="AL">Albania</option>
<option value="MD">Moldova</option>
<option value="UA">Ukraine</option>
<option value="BY">Belarus</option>
<option value="LT">Lithuania</option>
<option value="LV">Latvia</option>
<option value="EE">Estonia</option>
<option value="RU">Russia</option>
<option value="KZ">Kazakhstan</option>
<option value="UZ">Uzbekistan</option>
<option value="KG">Kyrgyzstan</option>
<option value="TJ">Tajikistan</option>
<option value="TM">Turkmenistan</option>
<option value="AF">Afghanistan</option>
<option value="PK">Pakistan</option>
<option value="BD">Bangladesh</option>
<option value="LK">Sri Lanka</option>
<option value="NP">Nepal</option>
<option value="BT">Bhutan</option>
<option value="MV">Maldives</option>
<option value="MM">Myanmar</option>
<option value="TH">Thailand</option>
<option value="LA">Laos</option>
<option value="KH">Cambodia</option>
<option value="VN">Vietnam</option>
<option value="MY">Malaysia</option>
<option value="ID">Indonesia</option>
<option value="PH">Philippines</option>
<option value="BN">Brunei</option>
<option value="TL">East Timor</option>
<option value="PG">Papua New Guinea</option>
<option value="FJ">Fiji</option>
<option value="VU">Vanuatu</option>
<option value="NC">New Caledonia</option>
<option value="PF">French Polynesia</option>
<option value="TO">Tonga</option>
<option value="WS">Samoa</option>
<option value="KI">Kiribati</option>
<option value="TV">Tuvalu</option>
<option value="NR">Nauru</option>
<option value="PW">Palau</option>
<option value="MH">Marshall Islands</option>
<option value="FM">Micronesia</option>
<option value="CK">Cook Islands</option>
<option value="NU">Niue</option>
<option value="TK">Tokelau</option>
<option value="AS">American Samoa</option>
<option value="GU">Guam</option>
<option value="MP">Northern Mariana Islands</option>
<option value="PW">Palau</option>
<option value="MH">Marshall Islands</option>
<option value="FM">Micronesia</option>
<option value="KI">Kiribati</option>
<option value="TV">Tuvalu</option>
<option value="NR">Nauru</option>
<option value="TO">Tonga</option>
<option value="WS">Samoa</option>
<option value="VU">Vanuatu</option>
<option value="FJ">Fiji</option>
<option value="PG">Papua New Guinea</option>
<option value="TL">East Timor</option>
<option value="BN">Brunei</option>
<option value="PH">Philippines</option>
<option value="ID">Indonesia</option>
<option value="MY">Malaysia</option>
<option value="VN">Vietnam</option>
<option value="KH">Cambodia</option>
<option value="LA">Laos</option>
<option value="TH">Thailand</option>
<option value="MM">Myanmar</option>
<option value="MV">Maldives</option>
<option value="BT">Bhutan</option>
<option value="NP">Nepal</option>
<option value="LK">Sri Lanka</option>
<option value="BD">Bangladesh</option>
<option value="PK">Pakistan</option>
<option value="AF">Afghanistan</option>
<option value="TM">Turkmenistan</option>
<option value="TJ">Tajikistan</option>
<option value="KG">Kyrgyzstan</option>
<option value="UZ">Uzbekistan</option>
<option value="KZ">Kazakhstan</option>
<option value="RU">Russia</option>
<option value="EE">Estonia</option>
<option value="LV">Latvia</option>
<option value="LT">Lithuania</option>
<option value="BY">Belarus</option>
<option value="UA">Ukraine</option>
<option value="MD">Moldova</option>
<option value="AL">Albania</option>
<option value="MK">North Macedonia</option>
<option value="BA">Bosnia and Herzegovina</option>
<option value="ME">Montenegro</option>
<option value="RS">Serbia</option>
<option value="HR">Croatia</option>
<option value="BG">Bulgaria</option>
<option value="RO">Romania</option>
<option value="HU">Hungary</option>
<option value="PL">Poland</option>
<option value="CZ">Czech Republic</option>
<option value="SK">Slovakia</option>
<option value="SI">Slovenia</option>
<option value="LU">Luxembourg</option>
<option value="PT">Portugal</option>
<option value="GR">Greece</option>
<option value="CY">Cyprus</option>
<option value="MT">Malta</option>
<option value="AD">Andorra</option>
<option value="VA">Vatican City</option>
<option value="SM">San Marino</option>
<option value="MC">Monaco</option>
<option value="LI">Liechtenstein</option>
<option value="IS">Iceland</option>
<option value="FO">Faroe Islands</option>
<option value="AX">Åland Islands</option>
<option value="XK">Kosovo</option>
<option value="SS">South Sudan</option>
<option value="EH">Western Sahara</option>
<option value="PS">Palestine</option>
<option value="UM">U.S. Minor Outlying Islands</option>
<option value="AS">American Samoa</option>
<option value="MP">Northern Mariana Islands</option>
<option value="GU">Guam</option>
<option value="FK">Falkland Islands</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="GF">French Guiana</option>
<option value="SR">Suriname</option>
<option value="GY">Guyana</option>
<option value="EC">Ecuador</option>
<option value="BO">Bolivia</option>
<option value="PY">Paraguay</option>
<option value="UY">Uruguay</option>
<option value="VE">Venezuela</option>
<option value="PE">Peru</option>
<option value="CO">Colombia</option>
<option value="CL">Chile</option>
<option value="AR">Argentina</option>
<option value="ZA">South Africa</option>
<option value="IL">Israel</option>
<option value="TW">Taiwan</option>
<option value="HK">Hong Kong</option>
<option value="SG">Singapore</option>
<option value="NZ">New Zealand</option>
<option value="IE">Ireland</option>
<option value="BE">Belgium</option>
<option value="AT">Austria</option>
<option value="CH">Switzerland</option>
<option value="FI">Finland</option>
<option value="NO">Norway</option>
<option value="SE">Sweden</option>
<option value="NL">Netherlands</option>
<option value="ES">Spain</option>
<option value="IT">Italy</option>
<option value="KR">South Korea</option>
<option value="CN">China</option>
<option value="IN">India</option>
<option value="BR">Brazil</option>
<option value="MX">Mexico</option>
<option value="JP">Japan</option>
<option value="FR">France</option>
<option value="DE">Germany</option>
<option value="AU">Australia</option>
<option value="GB">United Kingdom</option>
<option value="CA">Canada</option>
</select>
</div>
</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">
<?php if (isStripeEnabled()): ?>
<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>
<?php endif; ?>
<?php if (isPayPalEnabled()): ?>
<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>
<?php endif; ?>
</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 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('🎯 Validating billing address...');
// Validate billing address fields
const billingFields = [
'billing_first_name',
'billing_last_name',
'billing_email',
'billing_address',
'billing_city',
'billing_state',
'billing_zip',
'billing_country'
];
const billingData = {};
for (const field of billingFields) {
const element = document.getElementById(field);
if (!element) {
throw new Error(`Billing field not found: ${field}`);
}
if (!element.value.trim()) {
element.focus();
throw new Error(`Please fill in your ${field.replace('billing_', '').replace('_', ' ')}`);
}
billingData[field] = element.value.trim();
}
console.log('🎯 Billing address validated:', billingData);
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_name || 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);
// Send the full mixed cart structure to the backend
const formattedCart = {
credits: creditItems,
tracks: trackItems
};
console.log('🎯 Formatted cart (mixed):', 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,
billing_address: billingData
})
});
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);
}
if (!result.success) {
throw new Error(result.error || 'Unknown error from backend');
}
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({
clientSecret: paymentIntent,
});
// Create Payment Element instead of Card Element
const paymentElement = elements.create('payment');
console.log('🎯 Mounting payment element...');
paymentElement.mount('#card-element');
console.log('🎯 Payment element mounted successfully!');
console.log('🎯 Stripe form ready!');
// Store payment element reference
window.paymentElement = paymentElement;
} 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 (window.paymentElement) {
window.paymentElement.destroy();
window.paymentElement = null;
}
}
async function confirmStripePayment() {
if (!paymentIntent || !window.paymentElement) {
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);
}
// Authentication Functions
function switchAuthTab(tab) {
// Update tab buttons
document.querySelectorAll('.auth-tab').forEach(btn => {
btn.classList.remove('active');
});
event.currentTarget.classList.add('active');
// Update content
document.querySelectorAll('.auth-content').forEach(content => {
content.classList.remove('active');
});
document.getElementById(tab + 'Content').classList.add('active');
}
function proceedAsGuest() {
// Hide auth section and show billing address
document.getElementById('checkoutAuthSection').style.display = 'none';
document.getElementById('billingAddressSection').style.display = 'block';
// Show success message
if (typeof window.showNotification === 'function') {
window.showNotification('🎉 Guest checkout enabled!', 'success');
}
}
// Login form handler
document.addEventListener('DOMContentLoaded', function() {
const loginForm = document.getElementById('loginForm');
if (loginForm) {
loginForm.addEventListener('submit', async function(e) {
e.preventDefault();
const formData = new FormData(this);
const loginData = {
email: formData.get('login_email'),
password: formData.get('login_password')
};
try {
const response = await fetch('/auth/login.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(loginData)
});
const result = await response.json();
if (result.success) {
// Login successful - reload page to show logged-in state
window.location.reload();
} else {
alert('Login failed: ' + (result.error || 'Invalid credentials'));
}
} catch (error) {
console.error('Login error:', error);
alert('Login failed: ' + error.message);
}
});
}
// Registration form handler
const registerForm = document.getElementById('registerForm');
if (registerForm) {
registerForm.addEventListener('submit', async function(e) {
e.preventDefault();
const formData = new FormData(this);
const registerData = {
first_name: formData.get('register_first_name'),
last_name: formData.get('register_last_name'),
email: formData.get('register_email'),
password: formData.get('register_password'),
confirm_password: formData.get('register_confirm_password')
};
// Validate passwords match
if (registerData.password !== registerData.confirm_password) {
alert('Passwords do not match');
return;
}
try {
const response = await fetch('/auth/register.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(registerData)
});
const result = await response.json();
if (result.success) {
// Registration successful - reload page to show logged-in state
window.location.reload();
} else {
alert('Registration failed: ' + (result.error || 'Please try again'));
}
} catch (error) {
console.error('Registration error:', error);
alert('Registration failed: ' + error.message);
}
});
}
// Social login handlers
const googleBtn = document.querySelector('.btn-google');
if (googleBtn) {
googleBtn.addEventListener('click', function(e) {
e.preventDefault();
alert('Google login integration coming soon!');
});
}
const facebookBtn = document.querySelector('.btn-facebook');
if (facebookBtn) {
facebookBtn.addEventListener('click', function(e) {
e.preventDefault();
alert('Facebook login integration coming soon!');
});
}
});
// Coupon functionality
async function applyCoupon() {
const couponCode = document.getElementById('couponCode').value.trim();
const couponMessage = document.getElementById('couponMessage');
if (!couponCode) {
couponMessage.textContent = 'Please enter a coupon code';
couponMessage.className = 'coupon-message error';
return;
}
try {
const response = await fetch('/api/apply_coupon.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
coupon_code: couponCode,
cart_total: <?= $total ?>
})
});
const result = await response.json();
if (result.success) {
couponMessage.textContent = `🎉 Coupon applied! ${result.discount_type === 'percentage' ? result.discount + '%' : '$' + result.discount} discount`;
couponMessage.className = 'coupon-message success';
// Update total display
const totalElement = document.querySelector('.total-row.final span:last-child');
if (totalElement) {
const newTotal = (<?= $total ?> - result.discount_amount).toFixed(2);
totalElement.textContent = `$${newTotal}`;
}
// Disable coupon input
document.getElementById('couponCode').disabled = true;
document.querySelector('.coupon-input button').disabled = true;
} else {
couponMessage.textContent = result.error || 'Invalid coupon code';
couponMessage.className = 'coupon-message error';
}
} catch (error) {
console.error('Coupon error:', error);
couponMessage.textContent = 'Error applying coupon. Please try again.';
couponMessage.className = 'coupon-message error';
}
}
// Allow Enter key to apply coupon
document.addEventListener('DOMContentLoaded', function() {
const couponInput = document.getElementById('couponCode');
if (couponInput) {
couponInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
applyCoupon();
}
});
}
});
</script>
<?php include 'includes/footer.php'; ?>