T.ME/BIBIL_0DAY
CasperSecurity


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/cron/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/cron/sync_subscriptions_from_stripe.php
<?php
/**
 * Daily Subscription Sync from Stripe
 * 
 * This cron job syncs all active subscriptions from Stripe to the database.
 * It runs daily to catch any subscriptions that were missed due to webhook failures.
 * 
 * Usage: Run hourly via cron (for faster recovery)
 * 0 * * * * /usr/bin/php /home/gositeme/domains/soundstudiopro.com/public_html/cron/sync_subscriptions_from_stripe.php
 * 
 * Or run every 6 hours if hourly is too frequent:
 * 0 */6 * * * /usr/bin/php /home/gositeme/domains/soundstudiopro.com/public_html/cron/sync_subscriptions_from_stripe.php
 */

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../utils/subscription_helpers.php';
require_once __DIR__ . '/../config/subscription_plans.php';

$stripe_secret = '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';
$plans_config = require __DIR__ . '/../config/subscription_plans.php';

$pdo = getDBConnection();
$log_file = __DIR__ . '/../logs/subscription_sync.log';

// Log start
$log_entry = date('Y-m-d H:i:s') . " - Starting subscription sync from Stripe\n";
file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);

// Get all users with Stripe customer IDs
$stmt = $pdo->query("SELECT id, email, stripe_customer_id FROM users WHERE stripe_customer_id IS NOT NULL AND stripe_customer_id != ''");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);

$total_users = count($users);
$synced_count = 0;
$error_count = 0;

foreach ($users as $user) {
    try {
        $customer_id = $user['stripe_customer_id'];
        
        // 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);
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($http_code !== 200) {
            $error_count++;
            $log_entry = date('Y-m-d H:i:s') . " - Error fetching subscriptions for user {$user['id']} ({$user['email']}): HTTP {$http_code}\n";
            file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
            continue;
        }
        
        $subscriptions_data = json_decode($response, true);
        $subscriptions = $subscriptions_data['data'] ?? [];
        
        if (empty($subscriptions)) {
            continue; // No subscriptions for this user
        }
        
        // Process each subscription
        foreach ($subscriptions as $stripe_sub) {
            $stripe_sub_id = $stripe_sub['id'];
            $status = $stripe_sub['status'];
            
            // Only sync active/trialing subscriptions
            if (!in_array($status, ['active', 'trialing'])) {
                continue;
            }
            
            // Determine plan name
            $plan_name = 'essential'; // Default
            $price_id = null;
            
            // Primary: Get plan from price ID
            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 no match, try by price amount
                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;
                        }
                    }
                }
            }
            
            // Check if subscription exists in database
            $check_stmt = $pdo->prepare("SELECT id, plan_name, status FROM user_subscriptions WHERE stripe_subscription_id = ?");
            $check_stmt->execute([$stripe_sub_id]);
            $db_sub = $check_stmt->fetch(PDO::FETCH_ASSOC);
            
            $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 {
                if (!$db_sub) {
                    // Create new subscription record
                    $track_limit = $plans_config[$plan_name]['tracks_per_month'] ?? 5;
                    
                    $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
                    ]);
                    
                    $log_entry = date('Y-m-d H:i:s') . " - Created subscription for user {$user['id']}: {$plan_name} (Stripe: {$stripe_sub_id})\n";
                    file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
                } else {
                    // Update if status changed or plan updated
                    $needs_update = false;
                    $update_fields = [];
                    
                    if ($db_sub['status'] !== $status) {
                        $update_fields[] = "status = ?";
                        $needs_update = true;
                    }
                    if ($db_sub['plan_name'] !== $plan_name) {
                        $update_fields[] = "plan_name = ?";
                        $needs_update = true;
                    }
                    
                    if ($needs_update) {
                        $update_values = [];
                        if (in_array("status = ?", $update_fields)) {
                            $update_values[] = $status;
                        }
                        if (in_array("plan_name = ?", $update_fields)) {
                            $update_values[] = $plan_name;
                        }
                        $update_values[] = $stripe_sub_id;
                        
                        $update_sql = "UPDATE user_subscriptions SET " . implode(", ", $update_fields) . ", updated_at = NOW() WHERE stripe_subscription_id = ?";
                        $update_stmt = $pdo->prepare($update_sql);
                        $update_stmt->execute($update_values);
                        
                        $log_entry = date('Y-m-d H:i:s') . " - Updated subscription for user {$user['id']}: {$plan_name} (Stripe: {$stripe_sub_id})\n";
                        file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
                    }
                }
                
                // Update user plan if subscription is active
                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_count++;
                $log_entry = date('Y-m-d H:i:s') . " - Error syncing subscription {$stripe_sub_id} for user {$user['id']}: " . $e->getMessage() . "\n";
                file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
            }
        }
        
    } catch (Exception $e) {
        $error_count++;
        $log_entry = date('Y-m-d H:i:s') . " - Error processing user {$user['id']} ({$user['email']}): " . $e->getMessage() . "\n";
        file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
    }
}

// Log summary
$log_entry = date('Y-m-d H:i:s') . " - Sync complete. Users processed: {$total_users}, Subscriptions synced: {$synced_count}, Errors: {$error_count}\n";
file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);

echo "Sync complete. Check {$log_file} for details.\n";

CasperSecurity Mini