![]() 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/public_html/ |
<?php
/**
* Unified Subscription Signup Page
* Handles all subscription tiers: Essential, Starter, Pro, Premium
*/
session_start();
require_once 'config/database.php';
require_once __DIR__ . '/includes/translations.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
header('Location: /auth/login.php?redirect=' . urlencode('/subscribe.php' . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '')));
exit;
}
$pdo = getDBConnection();
$plans_config = require __DIR__ . '/config/subscription_plans.php';
// Get plan from query string
$plan_key = $_GET['plan'] ?? 'essential';
if (!isset($plans_config[$plan_key])) {
$plan_key = 'essential';
}
$plan = $plans_config[$plan_key];
// Get user info
$stmt = $pdo->prepare("SELECT id, name, email, plan FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// Check if already subscribed
require_once __DIR__ . '/utils/subscription_helpers.php';
$existing_subscription = hasActiveSubscription($_SESSION['user_id']);
$stripe_secret = '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';
// Handle subscription creation
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_subscription'])) {
// Check if price ID is configured
$price_id = $plan['stripe_price_id'] ?? '';
$is_placeholder = (
empty($price_id) ||
$price_id === 'price_essential_monthly' ||
strpos($price_id, 'YOUR_PRICE_ID') !== false ||
strpos($price_id, 'price_') === false ||
strlen($price_id) < 20 // Real Stripe price IDs are longer
);
if ($is_placeholder) {
$error_message = t('subscribe.setup_required', ['plan' => $plan['name']]);
error_log("Subscription error: Price ID not configured for plan '{$plan_key}'. Current value: '{$price_id}'");
} else {
try {
// Get existing Stripe customer ID if available (optional - Stripe will create one if needed)
$customer_id = !empty($user['stripe_customer_id']) ? $user['stripe_customer_id'] : null;
// Build checkout session parameters
// Stripe requires line_items as array format
$checkout_params = [
'mode' => 'subscription',
'line_items[0][price]' => $price_id,
'line_items[0][quantity]' => 1,
'success_url' => 'https://soundstudiopro.com/subscription_success.php?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => 'https://soundstudiopro.com/subscribe.php?plan=' . urlencode($plan_key) . '&canceled=1',
'metadata[user_id]' => (string)$user['id'],
'metadata[plan]' => $plan_key
];
// Debug logging
error_log("=== SUBSCRIPTION DEBUG ===");
error_log("Plan Key: {$plan_key}");
error_log("Plan Name: {$plan['name']}");
error_log("Plan Price: \${$plan['price']}");
error_log("Price ID: {$price_id}");
error_log("User ID: {$user['id']}");
error_log("========================");
// Only add customer if we already have one (optional)
if ($customer_id) {
$checkout_params['customer'] = $customer_id;
} else {
// Customer email - Stripe will create customer automatically if customer_id not provided
$checkout_params['customer_email'] = $user['email'];
}
// Create Stripe Checkout Session for subscription
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.stripe.com/v1/checkout/sessions');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $stripe_secret]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($checkout_params));
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code === 200) {
$session = json_decode($response, true);
// Debug: Log what Stripe returned
error_log("Stripe Checkout Session Created:");
error_log("Session ID: " . ($session['id'] ?? 'N/A'));
error_log("URL: " . ($session['url'] ?? 'N/A'));
if (isset($session['line_items']['data'][0]['price'])) {
error_log("Price in session: " . $session['line_items']['data'][0]['price']['id']);
error_log("Amount in session: $" . ($session['line_items']['data'][0]['price']['unit_amount'] / 100));
}
if (isset($session['url'])) {
header('Location: ' . $session['url']);
exit;
} else {
throw new Exception('Invalid response from Stripe: ' . $response);
}
} else {
$error_data = json_decode($response, true);
$error_message = t('subscribe.failed_to_create');
if (isset($error_data['error']['message'])) {
$error_message = $error_data['error']['message'];
} elseif (isset($error_data['error'])) {
$error_message = is_string($error_data['error']) ? $error_data['error'] : 'Stripe API error';
}
// Log the full error for debugging
error_log("Stripe subscription error (HTTP $http_code): " . $response);
error_log("Plan: $plan_key, Price ID: " . ($plan['stripe_price_id'] ?? 'NOT SET'));
throw new Exception($error_message);
}
} catch (Exception $e) {
error_log("Subscription creation error: " . $e->getMessage());
$error_message = $e->getMessage();
}
}
}
/**
* Translate a plan feature string
*/
function translateFeature($feature) {
// Extract number from "X tracks per month" format
if (preg_match('/^(\d+)\s+tracks\s+per\s+month$/i', $feature, $matches)) {
return t('plan.feature.tracks_per_month', ['count' => $matches[1]]);
}
// Map exact feature strings to translation keys
$featureMap = [
'Monthly reset' => 'plan.feature.monthly_reset',
'Basic AI models' => 'plan.feature.basic_ai_models',
'Advanced AI models' => 'plan.feature.advanced_ai_models',
'Standard generation speed' => 'plan.feature.standard_speed',
'High-speed generation' => 'plan.feature.high_speed',
'Priority queue access' => 'plan.feature.priority_queue',
'Highest priority queue' => 'plan.feature.highest_priority',
'Personal use license' => 'plan.feature.personal_license',
'Commercial use license' => 'plan.feature.commercial_license',
'Unlimited downloads' => 'plan.feature.unlimited_downloads',
'API access' => 'plan.feature.api_access',
'Full API access' => 'plan.feature.full_api_access',
'Dedicated support' => 'plan.feature.dedicated_support',
'White-label options' => 'plan.feature.white_label',
'Dedicated account manager' => 'plan.feature.account_manager',
'Custom integrations' => 'plan.feature.custom_integrations',
'SLA guarantee' => 'plan.feature.sla_guarantee',
'Cancel anytime' => 'plan.feature.cancel_anytime',
];
// Return translated feature if mapping exists, otherwise return original
if (isset($featureMap[$feature])) {
return t($featureMap[$feature]);
}
// Fallback to original if no translation found
return $feature;
}
$page_title = t('subscribe.page_title', ['plan' => $plan['name']]);
include 'includes/header.php';
?>
<main style="max-width: 800px; margin: 40px auto; padding: 20px;">
<div style="background: #2a2a2a; border-radius: 12px; padding: 40px; text-align: center;">
<h1 style="color: white; margin-bottom: 10px;">🎵 <?= t('subscribe.plan', ['plan' => htmlspecialchars($plan['name'])]) ?></h1>
<p style="color: #a0aec0; font-size: 1.2rem; margin-bottom: 30px;"><?= htmlspecialchars($plan['target_audience']) ?></p>
<?php if ($existing_subscription): ?>
<div style="background: #2d5016; padding: 20px; border-radius: 8px; margin-bottom: 30px;">
<p style="color: #48bb78; font-size: 1.1rem;">✅ <?= t('subscribe.already_subscribed') ?></p>
<p style="color: white; margin-top: 10px;"><?= t('subscribe.current_plan') ?> <strong><?= ucfirst($existing_subscription['plan_name']) ?></strong></p>
<p style="color: white;"><?= t('subscribe.status') ?> <strong><?= ucfirst($existing_subscription['status']) ?></strong></p>
<p style="color: white;"><?= t('subscribe.renews') ?> <strong><?= date('M j, Y', strtotime($existing_subscription['current_period_end'])) ?></strong></p>
<a href="/manage_subscription.php" style="display: inline-block; margin-top: 15px; padding: 10px 20px; background: #667eea; color: white; text-decoration: none; border-radius: 5px;"><?= t('subscribe.manage_subscription') ?></a>
</div>
<?php else: ?>
<?php if (isset($error_message)): ?>
<div style="background: #5a1a1a; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
<p style="color: #e53e3e;">❌ <?= t('subscribe.error') ?> <?= htmlspecialchars($error_message) ?></p>
</div>
<?php endif; ?>
<div style="background: #1a1a1a; padding: 30px; border-radius: 8px; margin-bottom: 30px;">
<div style="font-size: 3rem; color: <?= $plan['color'] ?>; font-weight: bold; margin-bottom: 10px;">
$<?= number_format($plan['price'], 2) ?><span style="font-size: 1.5rem; color: #a0aec0;"><?= t('subscribe.per_month') ?></span>
</div>
<div style="font-size: 1.5rem; color: white; margin-bottom: 30px;">
<?= $plan['tracks_per_month'] ?> <?= t('subscribe.tracks_per_month') ?>
</div>
<ul style="text-align: left; color: white; list-style: none; padding: 0; margin: 20px 0;">
<?php foreach ($plan['features'] as $feature): ?>
<li style="padding: 10px 0; border-bottom: 1px solid #333;">✅ <?= htmlspecialchars(translateFeature($feature)) ?></li>
<?php endforeach; ?>
</ul>
<form method="POST" style="margin-top: 30px;">
<button type="submit" name="create_subscription" value="1" style="padding: 15px 40px; background: <?= $plan['color'] ?>; color: white; border: none; border-radius: 8px; font-size: 1.2rem; cursor: pointer; width: 100%;">
<?= t('subscribe.subscribe_now', ['price' => number_format($plan['price'], 2)]) ?>
</button>
</form>
<p style="color: #a0aec0; font-size: 0.9rem; margin-top: 15px;">
<?= t('subscribe.stripe_redirect') ?>
</p>
</div>
<?php endif; ?>
<div style="margin-top: 30px; padding-top: 30px; border-top: 1px solid #333;">
<a href="/pricing.php" style="color: #667eea; text-decoration: none; margin-right: 20px;"><?= t('subscribe.view_all_plans') ?></a>
<a href="/account_settings.php" style="color: #667eea; text-decoration: none;"><?= t('subscribe.account_settings') ?></a>
</div>
</div>
</main>
<?php include 'includes/footer.php'; ?>