I made a developer product and for some reason it runs the code after buying it every time you join!

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? I would like to make a nuke developer product in order to nuke a server.

  2. What is the issue? If you have purchased the item, every time you join then it nukes.

  3. What solutions have you tried so far? I have tried redoing the entire script, and I’ll show the redone script.

Here is my localscript inside of the button

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local productID = 1247322560

-- Function to prompt purchase of the developer product
local function promptPurchase()
	local player = Players.LocalPlayer
	MarketplaceService:PromptProductPurchase(player, productID)
end
script.Parent.MouseButton1Click:Connect(function()
	promptPurchase()
end)

Here is my script inside of the ServerScriptService

local MarketplaceService = game:GetService("MarketplaceService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local PurchaseEvent = ReplicatedStorage.PurchaseNuke
local ProductID = 1247322560

-- Listen for when someone clicks on any of the buttons in the purchase prompt
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")

-- Data store for tracking purchases that were successfully processed
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")

-- Table setup containing product IDs and functions for handling purchases
local productFunctions = {}

productFunctions[ProductID] = function(receipt, player)
	game:GetService("ServerStorage"):WaitForChild("Nuke"):Clone().Parent = game.Workspace
	workspace.Siren.Playing = true
	workspace.Nuke.Nuke1.NukeNoise.Playing = true
end
-- The core 'ProcessReceipt' callback function
local function processReceipt(receiptInfo)

	-- Determine if the product was already granted by checking the data store  
	local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
	local purchased = false
	local success, errorMessage = pcall(function()
		purchased = purchaseHistoryStore:GetAsync(playerProductKey)
	end)
	-- If purchase was recorded, the product was already granted
	if success and purchased then
		return Enum.ProductPurchaseDecision.PurchaseGranted
	elseif not success then
		error("Data store error:" .. errorMessage)
	end

	-- Find the player who made the purchase in the server
	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then
		-- The player probably left the game
		-- If they come back, the callback will be called again
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	-- Look up handler function from 'productFunctions' table above
	local handler = productFunctions[receiptInfo.ProductId]

	-- Call the handler function and catch any errors
	local success, result = pcall(handler, receiptInfo, player)
	if not success or not result then
		warn("Error occurred while processing a product purchase")
		print("\nProductId:", receiptInfo.ProductId)
		print("\nPlayer:", player)
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	-- Record transaction in data store so it isn't granted again
	local success, errorMessage = pcall(function()
		purchaseHistoryStore:SetAsync(playerProductKey, true)
	end)
	if not success then
		error("Cannot save purchase data: " .. errorMessage)
	end

	-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

-- Set the callback; this can only be done once by one script on the server! 
MarketplaceService.ProcessReceipt = processReceipt

Thank you if you can help!

1 Like

I am very confused, and I need this to work.

I believe we are missing code because from these two scripts, they have no ability to fire a nuke on playeradded.

1 Like

Your handler function needs to return true, indicating to the main script that the reward the player is owed has been paid out. Because it isn’t reporting that the processing was successful, the code runs every time the player joins, as it is still trying to process the receipt.

Changing your handler to this should resolve the problem, although it will still go off one more time when the player joins, as ROBLOX still needs to correctly process the result.

productFunctions[ProductID] = function(receipt, player)
	game:GetService("ServerStorage"):WaitForChild("Nuke"):Clone().Parent = game.Workspace
	workspace.Siren.Playing = true
	workspace.Nuke.Nuke1.NukeNoise.Playing = true

	return true
end
3 Likes

I got it fixed, but thank you!

How did you fix it? I’m having the same problem.

You need to make sure you return Enum.ProductPurchaseDecision.PurchaseGranted inside the ProcessReceipt function to indicate the purchase was successful, otherwise Roblox retries the purchase every time the player rejoins.

1 Like

I already have this, it still doesn’t work.
It doesn’t occur when I play test in studio.

It was a problem with some other code in my script I got it fixed.