DevProducts don't work on Servers

My devproducts wont work on regular servers, but they do work on studio

local MarketplaceService = game:GetService("MarketplaceService")
local winBrick = workspace.Storage.End.WinBrick
local DataStoreService = game:GetService("DataStoreService")
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local Players = game:GetService("Players")
local KillMessage = game.ReplicatedStorage.KillMessage

-- Table setup containing product IDs and functions for handling purchases
local productFunctions = {1339707522, 1339710535, 1153921276, 1153921344, 1153921386}
productFunctions[1339707522] = function(receipt, player)
	for i, player in ipairs(game.Players:GetPlayers()) do
		if player.Character then
			local hum = player.Character:FindFirstChild('Humanoid')
			if hum then
				hum.Health = 0
			end 
		end
	end
	KillMessage:FireAllClients(player)
		return true
end

productFunctions[1339710535] = function(receipt, player)
	player.Character:SetPrimaryPartCFrame((winBrick.CFrame)* CFrame.new(0, -2, -20))
		return true
end

productFunctions[1153921276] = function(receipt, player)
	player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 500
	return true
end
productFunctions[1153921344] = function(receipt, player)
	player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 2000
	return true
end
productFunctions[1153921386] = function(receipt, player)
	player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 10000
	return true
end

local function processReceipt(receiptInfo)

	local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId

	local success, isPurchaseRecorded = pcall(function()
		return purchaseHistoryStore:UpdateAsync(playerProductKey, function(alreadyPurchased)
			if alreadyPurchased then
				return true
			end

			local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
			if not player then
				
				return nil
			end

			local handler = productFunctions[receiptInfo.ProductId]

			local success, result = pcall(handler, receiptInfo, player)
			
			if not success or not result then
				error("Failed to process a product purchase for ProductId:", receiptInfo.ProductId, " Player:", player)
				return nil
			end

		
			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
		
		return Enum.ProductPurchaseDecision.NotProcessedYet
	else	

		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
end

MarketplaceService.ProcessReceipt = processReceipt
1 Like

Sorry, my first post was fixing minor errors I saw. “not working” is not enough to know what the issue is. Are there errors? If so, share.

1 Like

A couple of things,

Instead of writing giant numbers like 10000, you can instead shorten it to 1e4 which is the exact same as 10^4 (Ten to the Power of Four) which both are equal to 10000
Along with 2000, we can shorten it to 2e3 or 10^3*2

Instead of having just functions, you can have the coins value be tables with a string Attached to it to indicate the leaderstat value, from there, you are able to do a recursive search with FindFirstChild()

local Instance = Plr:FindFirstChild(index.ls, true)
-- this will look through descendants

You are also able to organize them like this:

function KillAll(receipt, plr)
    for _,p in game.Players:GetPlayers() do
        if p.Character and p.Character:FindFirstChild("Humanoid") then
            p.Character.Humanoid.Health = 0
        end
    end
end
function PivotTo(receipt, plr)
    plr.Character:PivotTo((winBrick.CFrame) * CFrame.new(0, -2, -20))
end

Products = {
    [1339707522] = KillAll; -- remove parenthesis so they don't fire
    [1339710535] = PivotTo;
    
    [1153921276] = {ls = "Coins", val = 500}
    [1153921344] = {ls = "Coins", val = 2e3}
    [1153921386] = {ls = "Coins", val = 1e4}

}

But to Avoid errors, we can check the type() of these values:

local Var = type(val) -- returns Variant
if Var == "function" then -- if a function
    -- fire function
elseif Var == "table" then -- If a table
    -- Apply value
else -- something else (use typeof() if its something else)

end