Skip stage works in studio but not in team test?

I have been having this problem for ages and I have no idea why this isn’t working. I have a skip stage button that works perfectly fine in studio when I am testing but does not work at all when I go to team test. I have API Services enabled. I have a donation leaderboard as well combined with the skip stage since you can only use the Process Receipt thing once. I’ll include the script in my skip stage button and the one for the donation/skip stage all together. Any help is appreciated.

local mps = game:GetService("MarketplaceService")

local skipStageID = 1388352883

local plr = game.Players.LocalPlayer

local button = script.Parent
local maxStage = #game.Workspace.Checkpoints:GetChildren()

button.MouseButton1Click:Connect(function()
	if game.Players.LocalPlayer.leaderstats.Stage.Value < maxStage then


		mps:PromptProductPurchase(game.Players.LocalPlayer, skipStageID)
	end

end)

Local Script inside my button in the StarterGui.

local DATA_KEY = "#&(DMD!)A!)@$"
local GUI_FACE = "Right"
local DISPLAY_AMOUNT = 25
local REFRESH_RATE = 60
local DONATION_OPTIONS = {
	{
		Amount = 5,
		Id = 1380706015
	},
	{
		Amount = 10,
		Id = 1380706409
	},
	{
		Amount = 50,
		Id = 1380706407
	},
	{
		Amount = 100,
		Id = 1380706406
	},
	{
		Amount = 250,
		Id = 1380706685
	},
	{
		Amount = 500,
		Id = 1380706684
	},
	{
		Amount = 1000,
		Id = 1380706683
	},
	{
		Amount = 5000,
		Id = 1380706831
	},
}

local skipStageID = 1388352883

-----------------------------------------------------------------------------------------------------------
--> Code starts here. Only edit if you're an experienced programmer!

local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local gui = script.Donations
local face = Enum.NormalId[GUI_FACE]

local eve = Instance.new("RemoteEvent")
eve.Name = "DonationEvent"
eve.Parent = ReplicatedStorage

local cache = {}

local tmType = Enum.ThumbnailType.HeadShot
local tmSize = Enum.ThumbnailSize.Size420x420

local donations = DataStoreService:GetOrderedDataStore("DONATIONS_" .. DATA_KEY)

if not face then error("Invalid GUI_FACE: " .. GUI_FACE) else gui.Face = face end

local function getName(id)
	for cachedId, name in pairs (cache) do
		if cachedId == id then
			return name
		end
	end
	local success, result = pcall(function()
		return Players:GetNameFromUserIdAsync(id)
	end)
	if success then
		cache[id] = result
		return result
	else
		warn(result .. "\nId: " .. id)
		return "N/A"
	end
end

local function findAmountById(id)
	for _, donationInfo in pairs (DONATION_OPTIONS) do
		if donationInfo.Id == id then
			print(donationInfo.Amount)
			return donationInfo.Amount
		end
	end
	warn("Couldn't find donation amount for product ID " .. id)
	return 0
end

local function clearList(list)
	for _, v in pairs (list:GetChildren()) do
		if v:IsA("Frame") then v:Destroy() end
	end
end

local function updateAllClients(page)
	eve:FireAllClients("update", page)
end

local function updateInternalBoard(updateClientsAfter)
	local sorted = donations:GetSortedAsync(false, math.clamp(DISPLAY_AMOUNT, 0, 250), 1)
	if sorted then
		local page = sorted:GetCurrentPage()
		local clientDataPacket = {}
		clearList(gui.Main.Leaderboard.List)
		for rank, data in ipairs(page) do
			local userId = data.key
			local username = getName(data.key)
			local icon, isReady = Players:GetUserThumbnailAsync(userId, tmType, tmSize)
			local amountDonated = data.value .. " robux"

			local clone = gui.Main.Leaderboard.Template:Clone()
			clone.Icon.Image = icon
			clone.Rank.Text = "#" .. rank
			clone.Robux.Text = amountDonated
			clone.Username.Text = username
			clone.LayoutOrder = rank
			clone.Visible = true
			clone.Parent = gui.Main.Leaderboard.List

			table.insert(clientDataPacket, {
				["name"] = username,
				["icon"] = icon,
				["amount"] = amountDonated,
				["rank"] = rank
			})
		end

		if updateClientsAfter then
			updateAllClients(clientDataPacket)
		end
	else
		warn("No data available for leaderboard refresh!")
	end
end

local function createButtonsInternal()
	for pos, donationInfo in pairs (DONATION_OPTIONS) do
		local clone = gui.Main.Donate.Template:Clone()

		clone.Id.Value = donationInfo.Id
		clone.Info.Text = "<b>" .. donationInfo.Amount .. "</b> robux"

		clone.Visible = true
		clone.LayoutOrder = pos

		clone.Parent = gui.Main.Donate.List
	end
end

local function processReceipt(receiptInfo)
	local plrPurchased = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not plrPurchased then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	if receiptInfo.ProductId == skipStageID then
		if tonumber(plrPurchased.leaderstats.Stage.Value) < #game.workspace.Checkpoints:GetChildren() - 1 then
			plrPurchased.leaderstats.Stage.Value = plrPurchased.leaderstats.Stage.Value + 1	
		else
			plrPurchased.leaderstats.Stage.Value = "End"
		end

		plrPurchased:LoadCharacter()

		return Enum.ProductPurchaseDecision.PurchaseGranted
	end

	local donatedAmount = findAmountById(receiptInfo.ProductId)
	local id = receiptInfo.PlayerId

	local success, err = pcall(function()
		donations:UpdateAsync(id, function(previousData)
			if previousData then
				return previousData + donatedAmount
			else
				return donatedAmount
			end
		end)
	end)

	local player = Players:GetPlayerByUserId(id)

	if not success then
		if player then
			eve:FireClient(player, "Error", "There was an error processing your purchase. You have not been charged. Error: " .. err)
		end
		warn("Error handling " .. id .. "'s purchase: " .. err)
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	if player then
		eve:FireClient(player, "Success", "Thanks for your generous donation!")
	end

	return Enum.ProductPurchaseDecision.PurchaseGranted
end

local function onPlayerAdded(plr)
	local pGui = plr:WaitForChild("PlayerGui", 5)
	if pGui then
		for _, board in pairs (script.Parent:GetChildren()) do
			if board.Name == "Board" then
				local clone = gui:Clone()
				clone.Adornee = board
				clone.Parent = pGui
			end
		end 
		return true
	end
	warn("Couldn't find PlayerGui for " .. plr.Name .. ":" .. plr.UserId)
end



createButtonsInternal()
updateInternalBoard(false)
MarketplaceService.ProcessReceipt = processReceipt

for _, plr in pairs (Players:GetPlayers()) do
	onPlayerAdded(plr)
end
Players.PlayerAdded:Connect(onPlayerAdded)

while true do
	wait(REFRESH_RATE)
	updateInternalBoard(true)
end

Script for donation/skip stage. This script is located in the workspace.

There is also no script errors or anything showing up in the output so not sure what the problem is.

1 Like

Brosky do be using ChatGPT to help users here.

Anyways, for whatever reason - developer products do not work in team test, but don’t worry about that, they do work in game and in yk normal studio.

It was been reported years ago as engine bug, but I doubt roblox will do something about it as its there probably for a reason? Who knows.

1 Like

So if I publish the game, the skip stage should work? That’s so strange that it doesn’t work in team test omg. Thank you so much for helping me out! I literally kept on looking this up for answers and never found one :sweat_smile:

If it works when you hit “Play” - not team test one - then yes

1 Like

That’s so relieving to hear. You are legit a life saver. Thank you for helping me and out giving me peace of mind.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.