Cannot prompt purchase free bundles

This script checks for the AssetID and finds the Bundle and prompts the purchase of the bundle.

However, free bundles tend to say that the item is currently not for sale, instead of prompting the purchase properly.

Code (ServerScriptService):


-- SERVICES --

local AvatarEditorService = game:GetService('AvatarEditorService')
local MarketplaceService = game:GetService('MarketplaceService')
local Players = game:GetService('Players')
local HttpService = game:GetService('HttpService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')

-- VARIABLES --

local BundleCaches = {}
local BundleParts = {17, 27, 28, 29, 30, 31, 48, 49, 50, 51, 52, 53, 54, 55, 79}
local PurchaseDebounce = {}
local CheckOwnershipDebounce = {}

local BundleLink = 'https://catalog.roproxy.com/v1/assets/%d/bundles'

local SaveOutfitsEvent = ReplicatedStorage.Signals.Events.SaveOutfits
local SaveOutfitsFunction = ReplicatedStorage.Signals.Functions.SaveOutfits

-- FUNCTIONS --

local function CacheBundle(ItemId)
	
	local BundleInfo
	local Success, Error = pcall(function()
		BundleInfo = HttpService:JSONDecode(HttpService:GetAsync(string.format(BundleLink, ItemId)))
	end)

	if BundleInfo and BundleInfo.data and #BundleInfo.data >= 1 then
		BundleCaches[tostring(ItemId)] = BundleInfo.data[1].id
		return BundleInfo.data[1].id, 'Bundle'
	end
	
end

-- Get details of an item
local function GetPurchasableId(ItemId)
	
	-- If cache already exists, return cached id
	if BundleCaches[tostring(ItemId)] then
		return BundleCaches[tostring(ItemId)], 'Bundle'
	end
	
	-- Get the product info
	local ProductInfo
	pcall(function()
		ProductInfo = MarketplaceService:GetProductInfo(ItemId, Enum.InfoType.Asset)
	end)
	
	-- Check if item is a body part or an animation
	if ProductInfo then
		if table.find(BundleParts, ProductInfo.AssetTypeId) then
			return CacheBundle(ItemId)
		end
	end
	
	return ItemId
	
end

-- Check the ownership of an item
local function CheckOwnership(Player, ItemId)
	
	local IsOwned
	
	-- Check if cache exists
	if BundleCaches[tostring(ItemId)] then
		pcall(function()
			IsOwned = MarketplaceService:PlayerOwnsBundle(Player, BundleCaches[tostring(ItemId)])
		end)
	end
	
	-- Get the product info
	local ProductInfo
	pcall(function()
		ProductInfo = MarketplaceService:GetProductInfo(ItemId, Enum.InfoType.Asset)
	end)

	-- Check if body part or animation is owned
	if ProductInfo then
		
		if table.find(BundleParts, ProductInfo.AssetTypeId) then
			local ToCheckId = CacheBundle(ItemId)
			if ToCheckId then
				pcall(function()
					IsOwned = MarketplaceService:PlayerOwnsBundle(Player, ToCheckId)
				end)
			end
		end
		
	end
	
	-- Check if accessory or clothing is owned
	pcall(function()
		IsOwned = MarketplaceService:PlayerOwnsAsset(Player, ItemId)
	end)
	
	return IsOwned
	
end

-- EVENTS -- 

SaveOutfitsEvent.OnServerEvent:Connect(function(Player, Request, ...)
	
	if Request == 'PurchaseItem' then
		
		if PurchaseDebounce[Player] then
			return
		end
		
		PurchaseDebounce[Player] = true
		
		-- Set the variables
		local ItemId = ...
		
		-- Verify the variables
		if typeof(ItemId) ~= 'number' then
			return
		end
		
		-- Purchase the item
		local PurchasableId, Type = GetPurchasableId(ItemId)
		
		if PurchasableId then
			
			if Type == 'Bundle' then
				
				MarketplaceService:PromptBundlePurchase(Player, PurchasableId)
				
				PurchaseDebounce[Player] = nil
				return
					
			end
			
			MarketplaceService:PromptPurchase(Player, PurchasableId)
			
		end
		
		task.wait(1)
		
		PurchaseDebounce[Player] = nil
		
	elseif Request == 'SetupAvatarModel' then
		
		local AvatarModel = ...
		
		if AvatarModel and AvatarModel:IsA('Model') and AvatarModel.Name == 'Model' then
			
			local HumanoidDescription = Players:GetHumanoidDescriptionFromUserId(Player.UserId)
			AvatarModel:WaitForChild('Humanoid'):ApplyDescriptionReset(HumanoidDescription)
			
		end
		
	end
	
end)

SaveOutfitsFunction.OnServerInvoke = function(Player, Request, Variable1)
	
	if Request == 'CheckOwnership' then
		
		if CheckOwnershipDebounce[Player] then
			repeat
				task.wait()
			until not CheckOwnershipDebounce[Player]
		end
		
		CheckOwnershipDebounce[Player] = true
		
		-- Set variables
		local Items = Variable1
		
		-- Verify variables
		if typeof(Items) ~= 'table' then
			return
		end
		
		local ToReturn = {
			Owned = {};
			Unowned = {};
		}
		
		-- Check the ownership of each variable
		for _, ItemId in pairs(Items) do
			
			if typeof(ItemId) == 'number' then
				
				local IsOwned = CheckOwnership(Player, ItemId)
				if IsOwned then
					table.insert(ToReturn.Owned, ItemId)
				else
					table.insert(ToReturn.Unowned, ItemId)
				end
			
			end
			
		end
		
		task.spawn(function()
			task.wait(1)
			CheckOwnershipDebounce[Player] = nil
		end)
		
		return ToReturn
		
	end
	
end