I’m making 2 developer products for my game and they’re very broken
What do you want to achieve?
Have something happen when a product is bought
What is the issue?
Only 1 product is working at a time (when i try to buy the controller product, the asteroid one does not work at all and vice-versa)
If one of the 2 products do work, one of two things will happen: it will work or not do anything at all.
What solutions have you tried so far?
I’ve looked for answers but all i found is that i had to merge 2 scripts into 1 in order to work, but even that didnt work
Please help, im not the best at scripting.
-- Reference to MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Developer Product ID
local PRODUCT_ID = 1863487307
-- Function to handle product purchases
local function onProductPurchased1(receiptInfo)
-- Find the player who made the purchase
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Player not found, postpone receipt handling
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Check if the purchased product is the one we're interested in
if receiptInfo.ProductId == PRODUCT_ID then
print("purchase sucessful")
for i,v in ipairs(game:GetService("Players"):GetPlayers()) do
local startergui = v:WaitForChild("PlayerGui")
local label = startergui:FindFirstChild("Summoned"):FindFirstChild("Frame"):FindFirstChild("TextLabel")
label.Text = "omg ".. player.Name .." summoned a asteroid😃😃👍"
end
local asteroid = game.ReplicatedStorage.disasterfolder.asteroid:Clone()
asteroid.Parent = workspace
wait(60)
for i,v in ipairs(game:GetService("Players"):GetPlayers()) do
local startergui = v:WaitForChild("PlayerGui")
local label = startergui:FindFirstChild("Summoned"):FindFirstChild("Frame"):FindFirstChild("TextLabel")
label.Text = "controller is choosing"
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- For other products, return PurchaseGranted as well
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Set the ProcessReceipt callback
MarketplaceService.ProcessReceipt = onProductPurchased1
local PRODUCT_ID2 = 1863487886
-- Function to handle product purchases
local function onProductPurchased2(receiptInfo)
-- Find the player who made the purchase
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Player not found, postpone receipt handling
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Check if the purchased product is the one we're interested in
if receiptInfo.ProductId == PRODUCT_ID then
print("purchase sucessful")
_G.nextController = player
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- For other products, return PurchaseGranted as well
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Set the ProcessReceipt callback
MarketplaceService.ProcessReceipt = onProductPurchased2
ProcessReceipt is in charge of handling all of the purchases in your game Only set it once, with one function, that one function, should handle all of the purchases.
-- Reference to MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Developer Product ID
local PRODUCT_ID = 1863487307
local PRODUCT_ID2 = 1863487886
-- Function to handle product purchases
local function onProductPurchased1(receiptInfo)
-- Find the player who made the purchase
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Player not found, postpone receipt handling
return Enum.ProductPurchaseDecision.NotProcessedYet
end
if receiptInfo.ProductId == PRODUCT_ID2 then
print("purchase sucessful")
_G.nextController = player
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Check if the purchased product is the one we're interested in
if receiptInfo.ProductId == PRODUCT_ID then
print("purchase sucessful")
for i,v in ipairs(game:GetService("Players"):GetPlayers()) do
local startergui = v:WaitForChild("PlayerGui")
local label = startergui:FindFirstChild("Summoned"):FindFirstChild("Frame"):FindFirstChild("TextLabel")
label.Text = "omg ".. player.Name .." summoned a asteroid😃😃👍"
end
local asteroid = game.ReplicatedStorage.disasterfolder.asteroid:Clone()
asteroid.Parent = workspace
wait(60)
for i,v in ipairs(game:GetService("Players"):GetPlayers()) do
local startergui = v:WaitForChild("PlayerGui")
local label = startergui:FindFirstChild("Summoned"):FindFirstChild("Frame"):FindFirstChild("TextLabel")
label.Text = "controller is choosing"
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- For other products, return PurchaseGranted as well
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Set the ProcessReceipt callback
MarketplaceService.ProcessReceipt = onProductPurchased1
Like the others said, you should only be assigning ProcessReceipt once. I’d recommend following the structure on the Roblox documentation, it’s a lot simpler!
local mps = game:GetService("MarketplaceService")
local players = game:GetService("Players")
local productFunctions = {} --store all the things products do
--replace '000000' with your product ID
productFunctions[000000] = function(player:Player)
--what you want the product to do
end
--you can add this as many times as needed for each product. It may need to be moved to a module if it becomes too big.
productFunctions[exampleId] = function(player:Player)
end
--process the receipt
local function processReceipt(info)
--get the player and the handler
local player = players:GetPlayerByUserId(info.PlayerId)
local handler = productFunctions[info.ProductId]
--run the handler in protected mode
local success, result = pcall(handler, player)
if success then --It worked. Let Roblox know the purchase is handled.
return Enum.ProductPurchaseDecision.PurchaseGranted
else --it didn't work. Let Roblox know to retry on next join.
return Enum.ProductPurchaseDecision.NotProcessedYet
end
end
--set the callback
--this can only be done once
mps.ProcessReceipt = processReceipt
This is just an easier system to help simplify your code, it’s a lot easier to read as well. There’s also a few other things I would recommend changing:
You are doing to if statements; consider doing an if ... elseif instead.
You are using _G, which is generally considered bad practice.
I’d agree with this, however _G is necessary in some places, so I wouldn’t really critique that, though I’d probably go with making your own Globals by having a empty module return just {}, since it provides the same functionality as the built in _G at better performance.
Essentially how returning {} works, is it caches values and when you require that module, and do module.something = setTheValue, it’ll update the cached value.
Yeah, I was going along the lines of creating a custom globals module as well. Thanks for explaining the details of it, I didn’t quite know how to phrase that part