Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why does this developer product only work sometimes?

This is my script for purchasing currency in my game... But players are complaining that this doesn't work sometimes... Why?

local MarketplaceService = game:GetService("MarketplaceService")
 
MarketplaceService.ProcessReceipt = function(receiptInfo)
	if receiptInfo.ProductId == 25740543 then--1000
	local players = game.Players:GetChildren()
	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId  then
			players[i].leaderstats["Tokens"].Value = players[i].leaderstats["Tokens"].Value + 1000
			local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
			gui.TextLabel.Text = (players[i].Name.." just bought $1,000 Tokens")
			gui.Parent = game.Workspace.game.Gui			
			
		end
	end
	elseif receiptInfo.ProductId == 25740553 then--7500 
	local players = game.Players:GetChildren()
	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId  then
			players[i].leaderstats["Tokens"].Value = players[i].leaderstats["Tokens"].Value + 7500
			local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
			gui.TextLabel.Text = (players[i].Name.." just bought $7,500 Tokens")
			gui.Parent = game.Workspace.game.Gui			
			
		end
	end	
		
	elseif receiptInfo.ProductId == 25740591 then--20,000 
	local players = game.Players:GetChildren()
	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId  then
			players[i].leaderstats["Tokens"].Value = players[i].leaderstats["Tokens"].Value + 20000
			local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
			gui.TextLabel.Text = (players[i].Name.." just bought $20,000 Tokens")
			gui.Parent = game.Workspace.game.Gui			
			
		end
	end	
	elseif receiptInfo.ProductId == 25740608 then -- 1,000,000
	local players = game.Players:GetChildren()
	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId  then
			players[i].leaderstats["Tokens"].Value = players[i].leaderstats["Tokens"].Value + 1000000
			local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
			gui.TextLabel.Text = (players[i].Name.." just bought $1,000,000 Tokens")
			gui.Parent = game.Workspace.game.Gui			
			
		end
	end		

	elseif receiptInfo.ProductId == 27658062 then -- 1,000,000
	local players = game.Players:GetChildren()
	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId  then
			local gueeeee = game.ServerStorage.assets.Trail:Clone()
			gueeeee.Parent = players[i].PlayerGui.GUI
			local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
			gui.TextLabel.Text = (players[i].Name.." just bought a custom trail!")
			gui.Parent = game.Workspace.game.Gui			
			
		end
	end		
		
		
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted		
end

1 answer

✓ Accepted answer

First, clean up your code. You repeat yourself a ton.

Make a function to get a Player object from their userId instead of repeating all of this code inside of a loop.

Use a structure of some kind (e.g., a dictionary) to map ProductId into amount of tokens.


Something like this is much cleaner:

EDIT: PlayerById isn't necessary -- it's built into the Players service.

local MarketplaceService = game:GetService("MarketplaceService")

local TokenAwards = {
	[25740543] = 1000,
	[25740553] = 7500,
	[25740591] = 20000,
	[25740608] = 1000000,
}

function awardTokens(player, amount)
	if player:FindFirstChild("leaderstats") and player.leaderstats:FindFirstChild("Tokens") then
		player.leaderstats.Tokens.Value = player.leaderstats.Tokens.Value + amoutn
		local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
		gui.TextLabel.Text = player.Name .. " just bought $" .. amount .. " Tokens"
		gui.Parent = workspace.game.Gui
	end
end

MarketplaceService.ProcessReceipt = function(receiptInfo)
	local player = game.Players:PlayerByUserId(receiptInfo.PlayerId)
	if not player then
		return -- No such player
	end
	local tokenAward = TokenAwards[receiptInfo.ProductId]
	if tokenAward then
		-- Is a token purchase
		awardTokens(player, tokenAward)
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end

	if receiptInfo.ProductId == 27658062 then
		local trail = game.ServerStorage.assets.Trail:Clone()
		trail.Parent = player.PlayerGui.GUI
		local gui = game.ServerStorage.assets.EXTRAINFO:Clone()
		gui.TextLabel.Text = player.Name .. " just bought a custom trail!"
		gui.Parent = workspace.game.Gui
		
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
	print("Unknown product ", receiptInfo.ProductId)
end

Your original code had little error handling. You should test every purchase and make sure that you have the IDs correct. You should also make sure there is never a case when, for example, workspace.game doesn't exist (e.g., is there a moment between rounds where it's deleted and then added? If so, make sure you :WaitForChild instead).

This discussion is preserved as it was. New answers, comments, and votes are closed.