Hi. I have two remote functions. When I invoke the one in the code below all of it works, and when I invoke the other one, it prompts the marketplace service and reads the code on my other script. How is this possible? If I don’t get an answer on this I’m submitting a bug report.
local button = script.Parent
button.MouseButton1Click:Connect(function()
game.ReplicatedStorage.DevProducts.SpeedCoil:InvokeServer()
end)
local button = script.Parent
button.MouseButton1Click:Connect(function()
game.ReplicatedStorage.DevProducts.GravityCoil:InvokeServer() --Invokes speed coil despite it all being named Gravity Coil in the other script
end)
local MarketplaceService = game:GetService("MarketplaceService")
local toolFolder = game.ServerStorage:WaitForChild("Tools")
local TOOL_PRODUCT_ID = 1231231234 --Example
local TOOL_NAME = "SpeedCoil"
local function giveToolToPlayer(player)
local tool = toolFolder:FindFirstChild(TOOL_NAME)
if tool and not player.Backpack:FindFirstChild(TOOL_NAME) then
local clonedTool = tool:Clone()
clonedTool.Parent = player.Backpack
else
print("You already have the speed coil")
end
end
game.ReplicatedStorage.DevProducts.SpeedCoil.OnServerInvoke = function(player)
MarketplaceService:PromptProductPurchase(player, TOOL_PRODUCT_ID)
end
MarketplaceService.ProcessReceipt = function(receiptInfo)
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
if receiptInfo.ProductId == TOOL_PRODUCT_ID then
giveToolToPlayer(player)
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
I have two completely separate remote functions. They both do the exact same thing. One of them works. The other one doesn’t. The marketplace processes the purchase, takes your robux, and gives you absolutely nothing and doesn’t even read the code inside of the marketplace receipt yet somehow it still processes the purchase.
The other script is identical to this one, it is useless for me to paste the code here I’ve reviewed it multiple times. It’s the same exact everything just with different names and a different badge ID. Trust me when I tell you I am good at looking through code. I always spot small things. There’s nothing wrong with it. No errors. It returns no errors when you purchase the item. It refuses to work.
Actually, the fact that you said it’s identical already sets off alarms. MarketplaceService.ProcessReceipt, like RemoteFunction.OnServerInvoke is a callback. Unlike events, only a single function can be assigned as a callback. Depending on which script runs second, it will override the previous callback you assigned to ProcessReceipt, leading all developer product purchases to be put through that callback. This is why the other developer product fails as it can never match the single asset ID you’re checking against
local MarketplaceService = game:GetService("MarketplaceService")
local toolFolder = game.ServerStorage:WaitForChild("Tools")
local TOOL_PRODUCT_ID = 4324324321
local TOOL_NAME = "GravityCoil"
local function giveToolToPlayer(player)
local tool = toolFolder:FindFirstChild(TOOL_NAME)
if tool and not player.Backpack:FindFirstChild(TOOL_NAME) then
local clonedTool = tool:Clone()
clonedTool.Parent = player.Backpack
else
print("You already have the gravity coil")
end
end
game.ReplicatedStorage.DevProducts.GravityCoil.OnServerInvoke = function(player)
MarketplaceService:PromptProductPurchase(player, TOOL_PRODUCT_ID)
end
MarketplaceService.ProcessReceipt = function(receiptInfo)
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
if receiptInfo.ProductId == TOOL_PRODUCT_ID then
giveToolToPlayer(player)
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
You need to handle all developer products through a single callback. The documentation I referenced for MarketplaceService.ProcessReceipt shows you how to do that. I developed a pipeline for handling all things monetized in my game which demonstrates this. Feel free to take inspiration from it. You can fork the code here. I abstract my developer products, game-passes, and the like into ModuleScripts. I have found it more convenient to register them to the pipeline via a function so things stay connected with their relevant part of the codebase, but the pipeline version I’m giving you does not do this