Problems with dev products!

So i have been having some problems with my dev products. I have quite a few and plan to add more. For now it comes down to two things. I have a kill all button and a bunch of dev products that gives a currency within the game called Items.

The problem right now is that it’s looking like it doesn’t register when you purchase the product. The prompt works fine but it just doesn’t give items. It used to sometimes work and sometimes doesn’t.

I tried a bunch of fixes including trying to publish the game and even pay for the dev product within the game and it just does not work! I tried searching and even asking chatgpt. Hopefully someone has some ideas? At the moment i use both a server script and local script. Maybe not the best way but someone said it could be the issue.

Here’s The server script:

local ClickDetector = script.Parent
local productID = 2657161178 – Replace with your Developer Product ID
local itemAmount = 5 – The amount of items the player receives

– Services
local MarketplaceService = game:GetService(“MarketplaceService”)
local Players = game:GetService(“Players”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)

– Wait for the RemoteEvent with a timeout period (5 seconds max wait)
local requestPurchaseEvent = ReplicatedStorage:WaitForChild(“RequestPurchase”, 5)

– If the RemoteEvent isn’t found, print a warning and stop the script.
if not requestPurchaseEvent then
warn(“RequestPurchase RemoteEvent not found in ReplicatedStorage!”)
return
end

– Function to handle purchase completion
local function onProductPurchased(player, productId, isPurchased)
if productId == productID and isPurchased then
print("Product purchased by " … player.Name)

	-- Get the player's leaderstats
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats then
		local itemsStat = leaderstats:FindFirstChild("Items")
		if itemsStat then
			print("Current Items Value: " .. itemsStat.Value)
			-- Increase the "Items" leaderstat by the specified amount
			itemsStat.Value = itemsStat.Value + itemAmount
			print("Items granted. New Items Value: " .. itemsStat.Value)
		else
			print("Items stat not found!")
		end
	else
		print("Leaderstats folder not found!")
	end
else
	print("Purchase failed or incorrect product ID")
end

end

– Handle the click event
ClickDetector.MouseClick:Connect(function(player)
– Send the request to the client to prompt for the purchase
requestPurchaseEvent:FireClient(player, productID)
end)

– Handle the purchase completion
MarketplaceService.ProcessReceipt = function(receiptInfo)
print(“ProcessReceipt triggered!”) – Debugging line

-- Print receiptInfo details for more context
print("Receipt Info: " .. tostring(receiptInfo.ProductId) .. " - " .. tostring(receiptInfo.PlayerId))

local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if player then
	-- Log player's name and receipt product ID for context
	print("Player found: " .. player.Name)

	-- Call the function to grant the items
	onProductPurchased(player, receiptInfo.ProductId, true)

	-- Return Purchase Granted status
	return Enum.ProductPurchaseDecision.PurchaseGranted
else
	-- If player not found, log this for debugging
	print("Player not found: " .. tostring(receiptInfo.PlayerId))
end

-- If the receipt couldn't be processed, return not processed yet
return Enum.ProductPurchaseDecision.NotProcessedYet

end

And here’s the local script:

local MarketplaceService = game:GetService(“MarketplaceService”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local requestPurchaseEvent = ReplicatedStorage:WaitForChild(“RequestPurchase”)

– Function to handle the purchase prompt
– Client-side script to handle the purchase prompt
requestPurchaseEvent.OnClientEvent:Connect(function(productID)
print("Prompting purchase for product ID: " … tostring(productID)) – Debugging line
MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, productID)
end)

uh can u make it all script its hard to read in normal text

I don’t really know how to do that. For some reason only part of the text is a script. IS there a command to make it fully script?

backticks (```)

oh man i really love devforum.roblox.com

um when typing theres this button jus paste ur script after u press it
Screenshot 2024-11-20 at 3.33.11 PM

Oh okay thanks, here’s the server script:

local ClickDetector = script.Parent
local productID = 2657161178 -- Replace with your Developer Product ID
local itemAmount = 5 -- The amount of items the player receives

-- Services
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Wait for the RemoteEvent with a timeout period (5 seconds max wait)
local requestPurchaseEvent = ReplicatedStorage:WaitForChild("RequestPurchase", 5)

-- If the RemoteEvent isn't found, print a warning and stop the script.
if not requestPurchaseEvent then
	warn("RequestPurchase RemoteEvent not found in ReplicatedStorage!")
	return
end

-- Function to handle purchase completion
local function onProductPurchased(player, productId, isPurchased)
	if productId == productID and isPurchased then
		print("Product purchased by " .. player.Name)

		-- Get the player's leaderstats
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats then
			local itemsStat = leaderstats:FindFirstChild("Items")
			if itemsStat then
				print("Current Items Value: " .. itemsStat.Value)
				-- Increase the "Items" leaderstat by the specified amount
				itemsStat.Value = itemsStat.Value + itemAmount
				print("Items granted. New Items Value: " .. itemsStat.Value)
			else
				print("Items stat not found!")
			end
		else
			print("Leaderstats folder not found!")
		end
	else
		print("Purchase failed or incorrect product ID")
	end
end

-- Handle the click event
ClickDetector.MouseClick:Connect(function(player)
	-- Send the request to the client to prompt for the purchase
	requestPurchaseEvent:FireClient(player, productID)
end)

-- Handle the purchase completion
MarketplaceService.ProcessReceipt = function(receiptInfo)
	print("ProcessReceipt triggered!") -- Debugging line

	-- Print receiptInfo details for more context
	print("Receipt Info: " .. tostring(receiptInfo.ProductId) .. " - " .. tostring(receiptInfo.PlayerId))

	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if player then
		-- Log player's name and receipt product ID for context
		print("Player found: " .. player.Name)

		-- Call the function to grant the items
		onProductPurchased(player, receiptInfo.ProductId, true)

		-- Return Purchase Granted status
		return Enum.ProductPurchaseDecision.PurchaseGranted
	else
		-- If player not found, log this for debugging
		print("Player not found: " .. tostring(receiptInfo.PlayerId))
	end

	-- If the receipt couldn't be processed, return not processed yet
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

And here’s the local script:

local MarketplaceService = game:GetService("MarketplaceService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local requestPurchaseEvent = ReplicatedStorage:WaitForChild("RequestPurchase")

-- Function to handle the purchase prompt
-- Client-side script to handle the purchase prompt
requestPurchaseEvent.OnClientEvent:Connect(function(productID)
	print("Prompting purchase for product ID: " .. tostring(productID)) -- Debugging line
	MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, productID)
end)

before i even get to reading the code

can you give the line the error occurs on?

Well that’s kinda the problem. There isn’t an error. It just doesn’t give the currency or print anything when you buy the product. SO i don’t really know what the problem is or why it doesn’t work

wait can u playtest and show where “Items” is locate

I tested and it might actually be the problem. It adds a leaderstats folder that it doesn’t use. Idk where it does this but it might be the problem
image

ok can u show the script where it creates the leaderstats, and yes that is the problem sometimes it chooses the empty one

Yeah im trynna find it right now. Might take a few minutes!

i am pretty sure the issue lies in the fact you’re using a remote event to do :PromptProductPurchase()

you do not need a remote event for that, you can just simply do it on the server:
image


do not quote me on this

the client will process the receipt, but the information will not get sent back to the server,
and even if you did add a remote event that passes the receipt info, that would be very exploitable


just handle the PromptProductPurchase() on the server and it should fix,
i’m making this assumption because according to you, none of the print statements run, which is… weird

that could be one error but the main error is that there are 2 leaderstat folders so the game gets confused which one to choose

Hmmm it’s quite strange. I tried find all and then found 3 scripts. I found the one that makes the main leaderstats folder but i can’t find the one that makes the useless one. I tried to make all the ones that makes the folder have different names to identify the bad one. However the bad one never changed. I have no idea why tbh

have u checked all of them thouroughly?

Yeah i tried any variation of find all and it never found anything else.

can u show me the leaderstat script

Yeah sure.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("MyDataStore")

-- Function to save player data
local function savePlayerData(player)
	local success, err = pcall(function()
		local data = {
			Items = player.leaderstats.Items.Value  -- Save the Items value
		}
		myDataStore:SetAsync(tostring(player.UserId), data)
		print("Saving data for:", player.Name, "Items value:", player.leaderstats.Items.Value)  -- Debug output
	end)

	if success then
		print("Data saved successfully for:", player.Name)
	else
		warn("Failed to save data for", player.Name, "with error:", err)
	end
end

-- Function to load player data
local function loadPlayerData(player)
	local success, data = pcall(function()
		return myDataStore:GetAsync(tostring(player.UserId))
	end)

	if success then
		if data then
			-- Debugging output
			print("Data found for", player.Name, ": Items =", data.Items)
			player.leaderstats.Items.Value = data.Items or 0  -- Load the Items value or default to 0
			print("Loaded Items value for", player.Name, ":", player.leaderstats.Items.Value)  -- Debugging output
		else
			player.leaderstats.Items.Value = 0  -- Default to 0 if no data is found
			print("No data found for", player.Name, "setting Items value to 0.")
		end
	else
		warn("Failed to load data for", player.Name, "with error:", data)
		player.leaderstats.Items.Value = 0  -- Default to 0 if loading fails
	end
end

-- Function to set up leaderstats for a player
local function setupLeaderstats(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local items = Instance.new("IntValue")
	items.Name = "Items"
	items.Value = 0  -- Initialize to 0
	items.Parent = leaderstats

	loadPlayerData(player)  -- Load data for the player
end

-- Connect player added and removing events
Players.PlayerAdded:Connect(function(player)
	setupLeaderstats(player)  -- Set up leaderstats for the player
end)

Players.PlayerRemoving:Connect(savePlayerData)  -- Save data when the player leaves

theres no issue in this from what i see