Currently in this page:
https://create.roblox.com/docs/production/monetization/developer-products
There’s a section which is about handling developer product purchases. It’s right here:
However this script example here has a small issue. The variable “productID” was used as “productId” at line 33. Here’s the script:
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local productFunctions = {}
-- ProductId 123123 brings the player back to full health
productFunctions[123123] = function(receipt, player)
if player.Character and player.Character:FindFirstChild("Humanoid") then
player.Character.Humanoid.Health = player.Character.Humanoid.MaxHealth
-- Indicate a successful purchase
return true
end
end
-- ProductId 456456 awards 100 gold to the player
productFunctions[456456] = function(receipt, player)
local stats = player:FindFirstChild("leaderstats")
local gold = stats and stats:FindFirstChild("Gold")
if gold then
gold.Value = gold.Value + 100
return true
end
end
local function processReceipt(receiptInfo)
local userID = receiptInfo.PlayerId
local productID = receiptInfo.ProductId
local player = Players:GetPlayerByUserId(userID)
if player then
-- Get the handler function associated with the product ID and attempt to run it
local handler = productFunctions[productId] -- there's the issue!
local success, result = pcall(handler, receiptInfo, player)
if success then
-- The player has received their benefits!
-- return PurchaseGranted to confirm the transaction.
return Enum.ProductPurchaseDecision.PurchaseGranted
else
warn("Failed to process receipt:", receiptInfo, result)
end
end
-- the player's benefits couldn't be awarded.
-- return NotProcessedYet to try again next time the player joins.
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt