Issues with Developer Products

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

  1. What do you want to achieve? Keep it simple and clear!
    I followed the tutorial in https://developer.roblox.com/en-us/articles/Developer-Products-In-Game-Purchases but it doesn’t work

  2. What is the issue? Include screenshots / videos if possible!
    I made a developer product where if you buy it, it would kill everybody else. And if there are not enough players, it would return false, however, in both cases it would say “Purchase suceeded”. Also it would not kill anyone, but I’m pretty sure it’s just a coding error

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried putting return true and return false in the code but it still tells me purchase succeeded. When I try to print the player nothing appears (server and client)

workspace
image

localscript in purchasesgui
image

script in serverscriptservice

local MarketplaceService = game:GetService("MarketplaceService")
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 = {}
-- ProductId 123123 for a full heal
productFunctions[1305503315] = function(receipt, player)
	local players = Players:GetChildren()
	
	print(player)
	
	if #Players >= 2 then
		for i, v in ipairs(players) do
			if v ~= player then
				local character = v.Character

				if character then
					local human = character:FindFirstChild("Humanoid")

					if human then
						human.Health = 0
					end
				end
			end
		end
		
		return true
	else
		return false
	end
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

I’m pretty sure that references the Players Service instead of your table players

Don’t use ipairs, since the table players doesn’t have an order. Instead, use pairs

Also, if your kill button doesn’t work if there is only 1 player, don’t let the player purchase it. Have a sanity check in the client where if #players < 2 then don’t prompt the purchase.

Thank you for mentioning the players thing, but for some reason it still doesn’t work. I don’t see this print in the console either

image

You could add breakpoints and prints to see what event fires. Is there any specific errors or anything

You said print player, did you mean print(player.Name)?

I added some prints to try and debug the code (in the productfunctions and in the processreciept script)

^^^ The product function does not get called at all
image

I think it may be a problem with these lines

	-- 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

There are no errors in the console either (client and server)

image

I tried printing the handler but it didn’t appear in console, not even an error about not being able to print a function

That wouldn’t error anyhow, you’d just output the function’s memory address.

local function f() end print(f) --function: 0xda2b124479cbd20b