Improvements
Use WaitForChild to make sure a part / instance exists before using it
Use GetService for the Players Service
Use GetPlayers instead of GetChildren when getting the players in the game (in case an object that is not a player is added to the folder
"userId" should be capitalized to UserId
the done variable is not required since the return statement would go to the end of the function without running again, only the first valid player checked would have any changes
You can access the player without a loop using receiptInfo and the code:
game:GetService("Players"):GetPlayerByUserId(receiptInfo.PlayerId)
Issues
receiptInfo has a ProductId but not a "ProductId1"
Your "or" statements will not check the ProductId matching the second and third values since the variable they are being compared to is not compared to them after the "or" statement
When running through :GetChildren() the players would be the value (v) of the table, not the index (i)
Initial Solution
local MarketPlaceService = game:GetService("MarketplaceService")
local function processReceipt(receiptInfo)
local players = game:GetService("Players"):GetPlayers()
local currency = "Stage"
local debounce = false
for index, player in pairs(players) do
local stage = player:WaitForChild("leaderstats"):WaitForChild("Stage")
if player.UserId == receiptInfo.PlayerId and debounce == false then
if receiptInfo.ProductId == 976013381 or receiptInfo.ProductId == 976013480 or receiptInfo.ProductId == 976016228 then
debounce = true
stage.Value = stage.Value + 1
player.Character:WaitForChild("Humanoid").Health = 0
debounce = false
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
end
end
MarketPlaceService.ProcessReceipt = processReceipt
Improved Solution
Server Script in ServerScriptService
local MarketplaceService = game:GetService("MarketplaceService")
local function processReceipt(receiptInfo)
local player = game:GetService("Players"):GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
if receiptInfo.ProductId == 976013381 or receiptInfo.ProductId == 976013480 or receiptInfo.ProductId == 976016228 then
local stage = player:WaitForChild("leaderstats"):WaitForChild("Stage")
stage.Value = stage.Value + 1
player.Character:WaitForChild("Humanoid").Health = 0
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
MarketplaceService.ProcessReceipt = processReceipt
Server Script in Workspace or ServerScriptService
local MarketplaceService = game:GetService("MarketplaceService")
local id = 976013381
for index, player in pairs(game:GetService("Players"):GetPlayers()) do
MarketplaceService:PromptProductPurchase(player, id)
end
used in order to access the processReceipt function
the loop above would prompt the purchase of the given product for all players in the game when the code is run
In the previous response, your issue on Line 10 was a syntactic error (Lua is case sensitive)
In your initial script you defined the ProcessReceipt as the given function but since ProcessReceipt is already a function, the definition would not override it. In my above edits, the definition of the Receipt and its function are kept separate to remove any confusion with it.