Dev Product Script Doesn't Work

I’ve been looking at multiple tutorials and other posts to try and get an idea of why my script isn’t working, but all attempts have failed.

what the script is supposed to do, is when the product is purchased it randomises the players clan/family. However when test purchased nothing happens.

Local Script

local MPS = game:GetService("MarketplaceService")
local button = script.Parent
local player = game.Players.LocalPlayer

local Product = 1709787296 --interchangable

button.MouseButton1Click:Connect(function()
	MPS:PromptProductPurchase(player, Product)
end)

ServerScript

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

local clans = {

	["Tsuyobuta"] = nil,
	["McDermott"] = 0.1,
	["Kure"] = 0.1,
	["Gensai"] = 0.15,
	["Yoroizuka"] = 0.3,
	["Niko"] = 0.15,
	["Mikazuchi"] = 0.15,
	["Narushima"] = 0.4,
	["Gaoh"] = 0.2,
	["Robinson"] = 0.6,
	["Reinhold"] = 0.3,
	["Kanoh"] = 0.05,
	["Hongou"] = 0.2,
	["Tenma"] = 0.25

}

local Weight = 0

local function purchase(receiptInfo)
	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	local ProductId = 1709787296
	if player and ProductId then
		
		local Clan = player.ClanFolder.Clan

		task.wait(.5)

		for i, Chance in pairs(clans) do
			Weight += (Chance * 10)
		end

		local ranNumber = math.random(1, Weight)

		Weight = 0
		for clan, Chance in pairs(clans) do
			Weight += (Chance * 10)
			if Weight >= ranNumber then
				Clan.Value = clan
				break
			end
		end

		player:LoadCharacter()
	else
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
end

MPS.ProcessReceipt = purchase

did the purchase go thru or not

It won’t even let me check. this is the code to check right?

MPS.PromptPurchaseFinished:Connect(function(player, ProductId, Purchased)
		ProductId = 1709787296
		player = Players:GetPlayerByUserId(receiptInfo.PlayerId)

		if Purchased then
			print("the Purchase of ".. ProductId.. " Went through")
		else
			print("the Purchase of ".. ProductId.. " did not go through")
		end
	end)

Check if purchased == true and that the product id is 1709787296 instead of replacing ProductId with yours

like this?

MPS.PromptPurchaseFinished:Connect(function(player, ProductId, Purchased)
		player = Players:GetPlayerByUserId(receiptInfo.PlayerId)

		if Purchased == true and ProductId == 1709787296 then
			print("the Purchase of ".. ProductId.. " Went through")
		else
			print("the Purchase of ".. ProductId.. " did not go through")
		end
	end)

You’ll want to use the ProcessReceipt callback for MarketplaceService as it is the intended means of handling your developer products. They include an example script that is basically ready to use outside of needing to write your own functions for what each product should do.

Having looked at the initial code, you may run into trouble with having one of your clan table values set to nil, as im not sure youll be able to perform the math operation on a nil value without getting an error. Based on how your script works, you should be able to assign the value to 0 and have the desired results

I’ve changed the script according to what you sent but I’m still coming to a problem where not even an error message is being sent to output

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

local DataStoreService = game:GetService("DataStoreService")
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")

local clans = {

	["Tsuyobuta"] = 0,
	["McDermott"] = 0.1,
	["Kure"] = 0.1,
	["Gensai"] = 0.15,
	["Yoroizuka"] = 0.3,
	["Niko"] = 0.15,
	["Mikazuchi"] = 0.15,
	["Narushima"] = 0.4,
	["Gaoh"] = 0.2,
	["Robinson"] = 0.6,
	["Reinhold"] = 0.3,
	["Kanoh"] = 0.05,
	["Hongou"] = 0.2,
	["Tenma"] = 0.25

}

local Weight = 0

local productFunctions = {}

productFunctions[1709787296] = function(_receipt, player)
	
	local Clan = player.ClanFolder.Clan

	task.wait(.5)

	for i, Chance in pairs(clans) do
		Weight += (Chance * 10)
	end

	local ranNumber = math.random(1, Weight)

	Weight = 0
	for clan, Chance in pairs(clans) do
		Weight += (Chance * 10)
		if Weight >= ranNumber then
			Clan.Value = clan
			break
		end
	end

	player:LoadCharacter()
end


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, result, errorMessage

	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

	-- Determine if the product was already granted by checking the data store  
	local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId

	local success, isPurchaseRecorded = pcall(function()
		return purchaseHistoryStore:UpdateAsync(playerProductKey, function(alreadyPurchased)
			if alreadyPurchased then
				return true
			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 nil
			end

			local handler = productFunctions[receiptInfo.ProductId]

			local success, result = pcall(handler, receiptInfo, player)
			-- If granting the product failed, do NOT record the purchase in datastores.
			if not success or not result then
				error("Failed to process a product purchase for ProductId: " .. tostring(receiptInfo.ProductId) .. " Player: " .. tostring(player) .. " Error: " .. tostring(result))
				return nil
			end

			-- Record the transcation in purchaseHistoryStore.
			return true
		end)
	end)

	if not success then
		error("Failed to process receipt due to data store error.")
		return Enum.ProductPurchaseDecision.NotProcessedYet
	elseif isPurchaseRecorded == nil then
		-- Didn't update the value in data store.
		return Enum.ProductPurchaseDecision.NotProcessedYet
	else	
		-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
end

MPS.ProcessReceipt = processReceipt

Odd, when I run your function and make it print out its values it seems to work fine:

local clans = {

	["Tsuyobuta"] = 0,
	["McDermott"] = 0.1,
	["Kure"] = 0.1,
	["Gensai"] = 0.15,
	["Yoroizuka"] = 0.3,
	["Niko"] = 0.15,
	["Mikazuchi"] = 0.15,
	["Narushima"] = 0.4,
	["Gaoh"] = 0.2,
	["Robinson"] = 0.6,
	["Reinhold"] = 0.3,
	["Kanoh"] = 0.05,
	["Hongou"] = 0.2,
	["Tenma"] = 0.25

}

local Weight = 0

local productFunctions = {}

local function set_Clan(_receipt, player)

	local Clan = "Unset"

	for i, Chance in pairs(clans) do
		Weight += (Chance * 10)
	end
	print (Weight)
	
	local ranNumber = math.random(1, Weight)
	print (ranNumber)

	Weight = 0
	for clan, Chance in pairs(clans) do
		Weight += (Chance * 10)
		if Weight >= ranNumber then
			Clan = clan
			break
		end
	end
	
	print (Clan)

end
set_Clan()

So then I’m inclined to believe there’s an error with the function getting called in the first place. If you add a print statement to the very start of the function that sets someones clan as random, does it print when you run a test purchase? If not then you may have the wrong Asset ID for your dev product.

I made a new test dev product but the results are still the same, although, I will say that it had worked once initially when I watched this tutorial https://youtu.be/ChWaB2n0pMI?si=Y_PXwgwtQn38jJwP but after I had changed it so it was not a 1 time purchase by changing the purchase value back to false when the script had finished. But after that the script suddenly stopped working.

This is the server script in the video:

local DataStoreService = game:GetService("DataStoreService")
local LeaderstatDataStore = DataStoreService:GetDataStore("LeaderstatDataStore")

local DeveloperProductID = 1234567890 -- Change this ID with your Developer Product ID

game.Players.PlayerAdded:Connect(function(player)
    local Leaderstat = player.leaderstats.Coins

    local LeaderstatKey = player.UserId .. "_Coins"
    local success, savedValue = pcall(function()
        return LeaderstatDataStore:GetAsync(LeaderstatKey)
    end)
    if success and savedValue then
        Leaderstat.Value = savedValue
    end

    local Purchased = false

    game:GetService("MarketplaceService").ProcessReceipt = function(receiptInfo)
        if receiptInfo.PlayerId == player.UserId and receiptInfo.ProductId == DeveloperProductID and not Purchased then
            Purchased = true

            Leaderstat.Value = Leaderstat.Value + 1

            local Success, error = pcall(function()
                LeaderstatDataStore:SetAsync(LeaderstatKey, Leaderstat.Value)
            end)
            if not Success then
                warn("Failed to save leaderstat data:", error)
            end
        end
        return Enum.ProductPurchaseDecision.PurchaseGranted
    end
end)

Running the same scenario works for me
I’m thinking it’s an issue with the game being saved/published
Try adding print functions to check when the code stops
If nothing works just export your models, maps, scripts, etc and add them into a new game
(sometimes when making a new game studio makes it wrong and things bugout)

Also you don’t need to define a function if it’s used in only one spot

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

local clans = {

	["Tsuyobuta"] = nil,
	["McDermott"] = 0.1,
	["Kure"] = 0.1,
	["Gensai"] = 0.15,
	["Yoroizuka"] = 0.3,
	["Niko"] = 0.15,
	["Mikazuchi"] = 0.15,
	["Narushima"] = 0.4,
	["Gaoh"] = 0.2,
	["Robinson"] = 0.6,
	["Reinhold"] = 0.3,
	["Kanoh"] = 0.05,
	["Hongou"] = 0.2,
	["Tenma"] = 0.25

}

local Weight = 0

MPS.ProcessReceipt = function(receiptInfo)
	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	local ProductId = 1709787296
	if player and ProductId then
		
		local Clan = player.ClanFolder.Clan

		task.wait(.5)

		for i, Chance in pairs(clans) do
			Weight += (Chance * 10)
		end

		local ranNumber = math.random(1, Weight)

		Weight = 0
		for clan, Chance in pairs(clans) do
			Weight += (Chance * 10)
			if Weight >= ranNumber then
				Clan.Value = clan
				break
			end
		end

		player:LoadCharacter()
	else
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
end

I think you are right because the script works right up until the receiptInfo function, but I’ll try upload everything to a new game

Edit: I made a new game with all the scripts and models from the old one but the issue is still persisting I’m just going to leave developer products for a while and eventually come back to it again later, however, ill leave the post open for replies in case anyone has a solution