![]() 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/utils/ |
<?php
/**
* Sync User Subscription from Stripe
*
* Immediately syncs a user's subscription from Stripe to database.
* Called when subscription sync is needed (non-blocking).
*
* @param int $user_id User ID to sync
* @param string|null $customer_id Optional Stripe customer ID (if not provided, fetched from DB)
* @return array ['success' => bool, 'message' => string, 'synced' => int]
*/
function syncUserSubscriptionFromStripe($user_id, $customer_id = null) {
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/subscription_helpers.php';
require_once __DIR__ . '/../config/subscription_plans.php';
$stripe_secret = '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';
$plans_config = require __DIR__ . '/../config/subscription_plans.php';
try {
$pdo = getDBConnection();
// Get customer ID if not provided
if (!$customer_id) {
$stmt = $pdo->prepare("SELECT stripe_customer_id FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
$customer_id = $user['stripe_customer_id'] ?? null;
}
if (!$customer_id) {
return ['success' => false, 'message' => 'No Stripe customer ID found', 'synced' => 0];
}
// Fetch subscriptions from Stripe
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.stripe.com/v1/subscriptions?customer=" . urlencode($customer_id) . "&limit=10&status=all");
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $stripe_secret]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 5 second timeout
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code !== 200) {
return ['success' => false, 'message' => "Stripe API error: HTTP {$http_code}", 'synced' => 0];
}
$subscriptions_data = json_decode($response, true);
$subscriptions = $subscriptions_data['data'] ?? [];
if (empty($subscriptions)) {
return ['success' => true, 'message' => 'No subscriptions found in Stripe', 'synced' => 0];
}
$synced_count = 0;
// Process each active subscription
foreach ($subscriptions as $stripe_sub) {
if (!in_array($stripe_sub['status'], ['active', 'trialing'])) {
continue;
}
$stripe_sub_id = $stripe_sub['id'];
$status = $stripe_sub['status'];
// Determine plan name
$plan_name = 'essential';
$price_id = null;
if (!empty($stripe_sub['items']['data'][0]['price']['id'])) {
$price_id = $stripe_sub['items']['data'][0]['price']['id'];
foreach ($plans_config as $plan_key => $plan_data) {
if (isset($plan_data['stripe_price_id']) && $plan_data['stripe_price_id'] === $price_id) {
$plan_name = $plan_key;
break;
}
}
if ($plan_name === 'essential') {
$price_amount = $stripe_sub['items']['data'][0]['price']['unit_amount'] ?? 0;
$price_amount = $price_amount / 100;
foreach ($plans_config as $plan_key => $plan_data) {
if (abs($plan_data['price'] - $price_amount) < 0.01) {
$plan_name = $plan_key;
break;
}
}
}
}
$track_limit = $plans_config[$plan_name]['tracks_per_month'] ?? 5;
$period_start = date('Y-m-d H:i:s', $stripe_sub['current_period_start']);
$period_end = date('Y-m-d H:i:s', $stripe_sub['current_period_end']);
$pdo->beginTransaction();
try {
// Check if exists
$check_stmt = $pdo->prepare("SELECT id FROM user_subscriptions WHERE stripe_subscription_id = ?");
$check_stmt->execute([$stripe_sub_id]);
$db_sub = $check_stmt->fetch(PDO::FETCH_ASSOC);
if (!$db_sub) {
// Create new
$stmt = $pdo->prepare("
INSERT INTO user_subscriptions (
user_id, stripe_subscription_id, stripe_customer_id, plan_name, status,
current_period_start, current_period_end, created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, NOW())
");
$stmt->execute([
$user_id,
$stripe_sub_id,
$customer_id,
$plan_name,
$status,
$period_start,
$period_end
]);
$subscription_id = $pdo->lastInsertId();
// Initialize monthly track usage
$year_month = date('Y-m', $stripe_sub['current_period_start']);
$usage_stmt = $pdo->prepare("
INSERT INTO monthly_track_usage (
user_id, subscription_id, subscription_period_start,
`year_month`, tracks_created, track_limit, reset_at
)
VALUES (?, ?, ?, ?, 0, ?, NOW())
ON DUPLICATE KEY UPDATE
track_limit = VALUES(track_limit),
reset_at = NOW()
");
$usage_stmt->execute([
$user_id,
$subscription_id,
$period_start,
$year_month,
$track_limit
]);
} else {
// Update if needed
$update_stmt = $pdo->prepare("
UPDATE user_subscriptions
SET status = ?, plan_name = ?,
current_period_start = ?, current_period_end = ?,
updated_at = NOW()
WHERE stripe_subscription_id = ?
");
$update_stmt->execute([
$status,
$plan_name,
$period_start,
$period_end,
$stripe_sub_id
]);
}
// Update user plan
if (in_array($status, ['active', 'trialing'])) {
$user_plan_stmt = $pdo->prepare("UPDATE users SET plan = ? WHERE id = ?");
$user_plan_stmt->execute([$plan_name, $user_id]);
}
$pdo->commit();
$synced_count++;
} catch (Exception $e) {
$pdo->rollBack();
error_log("Error syncing subscription {$stripe_sub_id} for user {$user_id}: " . $e->getMessage());
}
}
return ['success' => true, 'message' => "Synced {$synced_count} subscription(s)", 'synced' => $synced_count];
} catch (Exception $e) {
error_log("syncUserSubscriptionFromStripe error for user {$user_id}: " . $e->getMessage());
return ['success' => false, 'message' => $e->getMessage(), 'synced' => 0];
}
}