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
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).