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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/fix_purchase_discrepancies.php
<?php
/**
 * Fix Purchase Discrepancies Script
 * 
 * Actually fixes missing purchases identified by reconciliation
 * Can fix specific payment intent or all discrepancies
 */

// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);

// Set error handler to catch fatal errors
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error !== NULL && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        http_response_code(500);
        echo "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>Error</title></head><body>";
        echo "<h1 style='color: red;'>Fatal Error</h1>";
        echo "<p><strong>File:</strong> " . htmlspecialchars($error['file']) . "</p>";
        echo "<p><strong>Line:</strong> " . htmlspecialchars($error['line']) . "</p>";
        echo "<p><strong>Message:</strong> " . htmlspecialchars($error['message']) . "</p>";
        echo "</body></html>";
    }
});

try {
    session_start();
} catch (Exception $e) {
    die("Session error: " . htmlspecialchars($e->getMessage()));
}

try {
    require_once 'config/database.php';
} catch (Exception $e) {
    die("Database config error: " . htmlspecialchars($e->getMessage()));
}

// Check if admin
if (!isset($_SESSION['is_admin']) || !$_SESSION['is_admin']) {
    die("Admin access required");
}

try {
    $pdo = getDBConnection();
} catch (Exception $e) {
    die("Database connection error: " . htmlspecialchars($e->getMessage()));
}

$payment_intent_id = $_GET['payment_intent_id'] ?? null;
$user_name = $_GET['user_name'] ?? null;
$auto_fix = $_GET['auto_fix'] ?? 'false';

echo "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>Fix Purchase Discrepancies</title></head><body>";
echo "<h2>🔧 Fix Purchase Discrepancies</h2>";
echo "<style>
    body { font-family: Arial; padding: 20px; background: #1a1a1a; color: white; }
    table { border-collapse: collapse; width: 100%; margin: 20px 0; background: #2a2a2a; }
    th, td { border: 1px solid #444; padding: 10px; text-align: left; }
    th { background: #667eea; color: white; }
    .success { color: #48bb78; }
    .error { color: #e53e3e; }
    .warning { color: #ffc107; }
    .info { color: #667eea; }
    .section { margin: 30px 0; padding: 20px; background: #2a2a2a; border-radius: 8px; }
    button { padding: 10px 20px; background: #667eea; color: white; border: none; border-radius: 5px; cursor: pointer; margin: 5px; }
    button:hover { background: #5568d3; }
    .fixed { background: #2d5016; }
    .failed { background: #5a1a1a; }
</style>";

// If specific payment intent provided, fix it
if ($payment_intent_id) {
    echo "<div class='section'>";
    echo "<h3>Fixing Payment Intent: {$payment_intent_id}</h3>";
    
    // Get Stripe payment intent data
    try {
        $stripe_secret = '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';
        $ch = curl_init();
        
        if ($ch === false) {
            throw new Exception("Failed to initialize cURL");
        }
        
        curl_setopt($ch, CURLOPT_URL, 'https://api.stripe.com/v1/payment_intents/' . urlencode($payment_intent_id));
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $stripe_secret]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        
        $stripe_response = curl_exec($ch);
        $curl_error = curl_error($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($curl_error) {
            throw new Exception("cURL error: " . $curl_error);
        }
        
        if ($http_code !== 200) {
            $error_data = json_decode($stripe_response, true);
            $error_msg = $error_data['error']['message'] ?? "HTTP Error: {$http_code}";
            throw new Exception("Stripe API error: {$error_msg}");
        }
        
        if (empty($stripe_response)) {
            throw new Exception("Empty response from Stripe API");
        }
        
        $payment = json_decode($stripe_response, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("JSON decode error: " . json_last_error_msg());
        }
        
        if (!isset($payment['id'])) {
            throw new Exception("Invalid payment intent response from Stripe");
        }
        
        $metadata = $payment['metadata'] ?? [];
        $user_id = $metadata['user_id'] ?? null;
        
    } catch (Exception $e) {
        die("<p class='error'>Error fetching payment intent: " . htmlspecialchars($e->getMessage()) . "</p>");
    }
    
    if (!$user_id) {
        die("<p class='error'>No user_id found in payment intent metadata. Metadata: " . htmlspecialchars(json_encode($metadata)) . "</p>");
    }
    
    // Get user info
    try {
        $stmt = $pdo->prepare("SELECT id, name, email FROM users WHERE id = ?");
        $stmt->execute([$user_id]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$user) {
            die("<p class='error'>User not found with ID: {$user_id}</p>");
        }
    } catch (Exception $e) {
        die("<p class='error'>Database error: " . htmlspecialchars($e->getMessage()) . "</p>");
    }
    
    echo "<p><strong>User:</strong> {$user['name']} (ID: {$user_id})</p>";
    
    // Parse cart items
    $cart_items_json = $metadata['cart_items'] ?? '[]';
    $cart_items = is_string($cart_items_json) ? json_decode($cart_items_json, true) : $cart_items_json;
    
    if (!is_array($cart_items)) {
        $cart_items = [];
    }
    
    // Get expected tracks
    $expected_tracks = [];
    foreach ($cart_items as $item) {
        if (isset($item['type']) && $item['type'] === 'track' && isset($item['track_id'])) {
            $expected_tracks[] = [
                'track_id' => $item['track_id'],
                'title' => $item['title'] ?? 'Unknown',
                'price' => ($item['amount'] ?? 0) / 100
            ];
        }
    }
    
    // Also check for single track purchase
    if (isset($metadata['track_id']) && !empty($metadata['track_id'])) {
        $expected_tracks[] = [
            'track_id' => $metadata['track_id'],
            'title' => $metadata['track_title'] ?? 'Unknown',
            'price' => ($payment['amount'] ?? 0) / 100
        ];
    }
    
    echo "<p><strong>Expected Tracks:</strong> " . count($expected_tracks) . "</p>";
    
    // Get current purchases with this payment intent
    $stmt = $pdo->prepare("
        SELECT 
            tp.id,
            tp.track_id,
            tp.user_id,
            tp.price_paid,
            mt.title as track_title
        FROM track_purchases tp
        JOIN music_tracks mt ON tp.track_id = mt.id
        WHERE tp.stripe_payment_intent_id = ?
    ");
    $stmt->execute([$payment_intent_id]);
    $current_purchases = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    echo "<p><strong>Current Purchases:</strong> " . count($current_purchases) . "</p>";
    
    // Find missing tracks
    $current_track_ids = array_column($current_purchases, 'track_id');
    $expected_track_ids = array_column($expected_tracks, 'track_id');
    $missing_tracks = [];
    
    foreach ($expected_tracks as $expected) {
        if (!in_array($expected['track_id'], $current_track_ids)) {
            $missing_tracks[] = $expected;
        }
    }
    
    // Find wrong tracks (in DB but not in expected)
    $wrong_tracks = [];
    foreach ($current_purchases as $purchase) {
        if (!in_array($purchase['track_id'], $expected_track_ids)) {
            $wrong_tracks[] = $purchase;
        }
    }
    
    if (empty($missing_tracks) && empty($wrong_tracks)) {
        echo "<p class='success'>✅ No discrepancies found. All purchases are correct!</p>";
        echo "</div>";
    } else {
        echo "<div class='section'>";
        echo "<h3>Discrepancies Found</h3>";
        
        if (!empty($missing_tracks)) {
            echo "<p class='error'><strong>Missing Tracks (" . count($missing_tracks) . "):</strong></p>";
            echo "<ul>";
            foreach ($missing_tracks as $missing) {
                echo "<li>Track ID: {$missing['track_id']} - {$missing['title']} (\${$missing['price']})</li>";
            }
            echo "</ul>";
        }
        
        if (!empty($wrong_tracks)) {
            echo "<p class='warning'><strong>Wrong Tracks (" . count($wrong_tracks) . "):</strong></p>";
            echo "<ul>";
            foreach ($wrong_tracks as $wrong) {
                echo "<li>Purchase ID: {$wrong['id']} - Track ID: {$wrong['track_id']} - {$wrong['track_title']} (\${$wrong['price_paid']})</li>";
            }
            echo "</ul>";
        }
        
        // Auto-fix if requested
        if ($auto_fix === 'yes' || isset($_POST['fix'])) {
            echo "<div class='section'>";
            echo "<h3>🔧 Applying Fixes...</h3>";
            
            $fixed = [];
            $failed = [];
            
            // Remove wrong purchases
            foreach ($wrong_tracks as $wrong) {
                try {
                    $pdo->beginTransaction();
                    
                    // Delete from track_purchases
                    $stmt = $pdo->prepare("DELETE FROM track_purchases WHERE id = ?");
                    $stmt->execute([$wrong['id']]);
                    
                    // Delete from user_library
                    $stmt = $pdo->prepare("DELETE FROM user_library WHERE user_id = ? AND track_id = ?");
                    $stmt->execute([$user_id, $wrong['track_id']]);
                    
                    // Delete from sales
                    $stmt = $pdo->prepare("DELETE FROM sales WHERE buyer_id = ? AND track_id = ?");
                    $stmt->execute([$user_id, $wrong['track_id']]);
                    
                    $pdo->commit();
                    
                    $fixed[] = [
                        'action' => 'removed',
                        'purchase_id' => $wrong['id'],
                        'track_id' => $wrong['track_id'],
                        'track_title' => $wrong['track_title']
                    ];
                } catch (Exception $e) {
                    $pdo->rollBack();
                    $failed[] = [
                        'action' => 'remove_failed',
                        'purchase_id' => $wrong['id'],
                        'error' => $e->getMessage()
                    ];
                }
            }
            
            // Add missing purchases
            foreach ($missing_tracks as $missing) {
                try {
                    // Check if track exists
                    $stmt = $pdo->prepare("SELECT id, title, price, user_id as artist_id, status FROM music_tracks WHERE id = ?");
                    $stmt->execute([$missing['track_id']]);
                    $track = $stmt->fetch(PDO::FETCH_ASSOC);
                    
                    if (!$track) {
                        $failed[] = [
                            'action' => 'add_failed',
                            'track_id' => $missing['track_id'],
                            'error' => 'Track not found in database'
                        ];
                        continue;
                    }
                    
                    if ($track['status'] !== 'complete') {
                        $failed[] = [
                            'action' => 'add_failed',
                            'track_id' => $missing['track_id'],
                            'error' => 'Track status is not complete'
                        ];
                        continue;
                    }
                    
                    $pdo->beginTransaction();
                    
                    // Check if already purchased (shouldn't be, but check anyway)
                    $stmt = $pdo->prepare("SELECT id FROM track_purchases WHERE user_id = ? AND track_id = ?");
                    $stmt->execute([$user_id, $missing['track_id']]);
                    if ($stmt->fetch()) {
                        $pdo->rollBack();
                        $failed[] = [
                            'action' => 'add_failed',
                            'track_id' => $missing['track_id'],
                            'error' => 'Track already purchased'
                        ];
                        continue;
                    }
                    
                    // Determine revenue recipient
                    $artist_stmt = $pdo->prepare("SELECT plan FROM users WHERE id = ?");
                    $artist_stmt->execute([$track['artist_id']]);
                    $artist = $artist_stmt->fetch(PDO::FETCH_ASSOC);
                    $is_free_user_track = ($artist && strtolower($artist['plan']) === 'free');
                    $revenue_recipient = $is_free_user_track ? 'platform' : 'artist';
                    $recipient_id = $is_free_user_track ? 1 : $track['artist_id'];
                    
                    // Record sale
                    $stmt = $pdo->prepare("
                        INSERT INTO sales (
                            track_id, buyer_id, artist_id, amount, quantity, 
                            revenue_recipient, recipient_id, is_free_user_track, 
                            created_at
                        ) VALUES (?, ?, ?, ?, 1, ?, ?, ?, NOW())
                    ");
                    $stmt->execute([
                        $missing['track_id'],
                        $user_id,
                        $track['artist_id'],
                        $track['price'],
                        $revenue_recipient,
                        $recipient_id,
                        $is_free_user_track ? 1 : 0
                    ]);
                    
                    // Record purchase
                    $stmt = $pdo->prepare("
                        INSERT INTO track_purchases (
                            user_id, track_id, price_paid, credits_used, 
                            payment_method, stripe_payment_intent_id, purchase_date
                        ) VALUES (?, ?, ?, 0, 'stripe', ?, NOW())
                    ");
                    $stmt->execute([
                        $user_id,
                        $missing['track_id'],
                        $track['price'],
                        $payment_intent_id
                    ]);
                    
                    // Add to library
                    $stmt = $pdo->prepare("
                        INSERT IGNORE INTO user_library (user_id, track_id, purchase_date)
                        VALUES (?, ?, NOW())
                    ");
                    $stmt->execute([$user_id, $missing['track_id']]);
                    
                    $pdo->commit();
                    
                    $fixed[] = [
                        'action' => 'added',
                        'track_id' => $missing['track_id'],
                        'track_title' => $track['title'],
                        'price' => $track['price']
                    ];
                } catch (Exception $e) {
                    if ($pdo->inTransaction()) {
                        $pdo->rollBack();
                    }
                    $failed[] = [
                        'action' => 'add_failed',
                        'track_id' => $missing['track_id'],
                        'error' => $e->getMessage()
                    ];
                }
            }
            
            // Display results
            if (!empty($fixed)) {
                echo "<p class='success'><strong>✅ Fixed (" . count($fixed) . "):</strong></p>";
                echo "<table class='fixed'>";
                echo "<tr><th>Action</th><th>Track ID</th><th>Details</th></tr>";
                foreach ($fixed as $fix) {
                    $track_title_or_id = isset($fix['track_title']) ? $fix['track_title'] : (isset($fix['purchase_id']) ? $fix['purchase_id'] : 'N/A');
                    echo "<tr>";
                    echo "<td>{$fix['action']}</td>";
                    echo "<td>{$fix['track_id']}</td>";
                    echo "<td>" . htmlspecialchars($track_title_or_id) . "</td>";
                    echo "</tr>";
                }
                echo "</table>";
            }
            
            if (!empty($failed)) {
                echo "<p class='error'><strong>❌ Failed (" . count($failed) . "):</strong></p>";
                echo "<table class='failed'>";
                echo "<tr><th>Action</th><th>Track ID</th><th>Error</th></tr>";
                foreach ($failed as $fail) {
                    $track_or_purchase_id = isset($fail['track_id']) ? $fail['track_id'] : (isset($fail['purchase_id']) ? $fail['purchase_id'] : 'N/A');
                    echo "<tr>";
                    echo "<td>{$fail['action']}</td>";
                    echo "<td>{$track_or_purchase_id}</td>";
                    echo "<td>" . htmlspecialchars($fail['error']) . "</td>";
                    echo "</tr>";
                }
                echo "</table>";
            }
            
            echo "</div>";
        } else {
            // Show fix button
            echo "<form method='POST' style='margin-top: 20px;'>";
            echo "<button type='submit' name='fix' value='1' style='background: #48bb78;'>🔧 Fix All Discrepancies</button>";
            echo "</form>";
            echo "<p class='warning'>⚠️ This will remove wrong purchases and add missing ones. Make sure you've reviewed the discrepancies above.</p>";
        }
        
        echo "</div>";
    }
    
    echo "</div>";
} else {
    // Show form to search
    echo "<div class='section'>";
    echo "<h3>Search for Payment Intent</h3>";
    echo "<form method='GET'>";
    echo "<p><label>Payment Intent ID: <input type='text' name='payment_intent_id' style='padding: 8px; width: 400px;' placeholder='pm_1SW5taD0zXLMB4gHVB9lJWVz'></label></p>";
    echo "<p><label>User Name (optional): <input type='text' name='user_name' style='padding: 8px; width: 300px;' placeholder='Stephan Bergeron'></label></p>";
    echo "<p><button type='submit'>Search</button></p>";
    echo "</form>";
    echo "</div>";
    
    // If user name provided, find their payment intents
    if ($user_name) {
        $stmt = $pdo->prepare("SELECT id, name FROM users WHERE name LIKE ? LIMIT 5");
        $stmt->execute(['%' . $user_name . '%']);
        $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        if (!empty($users)) {
            echo "<div class='section'>";
            echo "<h3>Found Users:</h3>";
            foreach ($users as $user) {
                echo "<p><a href='?user_id={$user['id']}' style='color: #667eea;'>{$user['name']} (ID: {$user['id']})</a></p>";
            }
            echo "</div>";
        }
    }
}

echo "<hr>";
echo "<p><a href='/admin.php' style='color: #667eea;'>← Back to Admin</a> | ";
echo "<a href='/reconcile_stripe_purchases.php' style='color: #667eea;'>Run Reconciliation</a></p>";
echo "</body></html>";
?>


CasperSecurity Mini