function handle_claim_game($data) { if (empty($data['game_id']) || empty($data['user_email'])) { echo json_encode(['success' => false, 'error' => 'Game ID and user email required']); return; } $db = get_db_connection(DB_NAME_SPEEDOTS); if (!$db) { echo json_encode(['success' => false, 'error' => 'Database unavailable']); return; } try { // Create receipts table if doesn't exist $db->exec("CREATE TABLE IF NOT EXISTS receipts (\n id INT AUTO_INCREMENT PRIMARY KEY,\n receipt_token VARCHAR(64) UNIQUE NOT NULL,\n product_id VARCHAR(255) UNIQUE,\n game_id INT NOT NULL,\n user_email VARCHAR(255) NOT NULL,\n game_title VARCHAR(255),\n game_developer VARCHAR(255),\n amount_paid DECIMAL(10,2) DEFAULT 0.00,\n is_free BOOLEAN DEFAULT FALSE,\n transaction_id VARCHAR(255),\n claimed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n expires_at TIMESTAMP NULL,\n status VARCHAR(50) DEFAULT 'active',\n INDEX (receipt_token),\n INDEX (product_id),\n INDEX (user_email),\n INDEX (game_id)\n ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Add product_id column if it doesn't exist (for backwards compatibility) try { $db->exec("ALTER TABLE receipts ADD COLUMN IF NOT EXISTS product_id VARCHAR(255) UNIQUE"); } catch (PDOException $e) {} // Column already exists // Get game info $stmt = $db->prepare("SELECT title, developer, price FROM published_games WHERE id=? AND status='approved'"); $stmt->execute([$data['game_id']]); $game = $stmt->fetch(PDO::FETCH_ASSOC); if (!$game) { echo json_encode(['success' => false, 'error' => 'Game not found']); return; } // ONLY allow free games through this endpoint $is_free = ($game['price'] == 0 || $game['price'] < 0.01); if (!$is_free) { echo json_encode([ 'success' => false, 'error' => 'Paid games must be purchased through PayPal', 'requires_payment' => true, 'price' => $game['price'] ]); return; } // Check if user already owns this game $stmt = $db->prepare("SELECT receipt_token FROM receipts WHERE game_id=? AND user_email=? AND status='active'"); $stmt->execute([$data['game_id'], $data['user_email']]); $existing = $stmt->fetch(PDO::FETCH_ASSOC); if ($existing) { // Get game info again to include in response $stmt_game = $db->prepare("SELECT title, developer FROM published_games WHERE id=?"); $stmt_game->execute([$data['game_id']]); $game_info = $stmt_game->fetch(PDO::FETCH_ASSOC); echo json_encode([ 'success' => true, 'already_owned' => true, 'receipt_token' => $existing['receipt_token'], 'message' => 'You already own this game', 'game_title' => $game_info['title'] ?? 'N/A', 'game_developer' => $game_info['developer'] ?? 'N/A' ]); return; } // Generate unique receipt token and product_id $receipt_token = bin2hex(random_bytes(32)) . uniqid(true); error_log("DEBUG: Generated receipt_token: " . $receipt_token); $user_email = $data['user_email']; $game_id = $data['game_id']; $userHash = substr(md5($user_email), 0, 8); $timestamp = time(); $productId = "GAME{$game_id}_USER{$userHash}_FREE_TIME{$timestamp}"; // Insert receipt (FREE game only) $stmt = $db->prepare("INSERT INTO receipts (receipt_token, product_id, game_id, user_email, game_title, game_developer, amount_paid, is_free, status) VALUES (?, ?, ?, ?, ?, ?, 0.00, 1, 'active')"); $stmt->execute([ $receipt_token, $productId, $data['game_id'], $data['user_email'], $game['title'], $game['developer'] ]); // Increment download counter $stmt = $db->prepare("UPDATE published_games SET downloads = downloads + 1 WHERE id = ?"); $stmt->execute([$data['game_id']]); $receipt_id = $db->lastInsertId(); echo json_encode([ 'success' => true, 'receipt_id' => $receipt_id, 'receipt_token' => $receipt_token, 'product_id' => $productId, 'game_title' => $game['title'], 'developer' => $game['developer'], 'amount_paid' => 0.00, 'is_free' => true, 'claimed_at' => date('Y-m-d H:i:s'), 'message' => 'Free game claimed!' ]); } catch (PDOException $e) { error_log('Claim game error: ' . $e->getMessage()); echo json_encode(['success' => false, 'error' => 'Database error']); } }