Dev Products not working

Hi, I am having an issue in my game where Dev Products just seem to be not working. I have found that if I put the script into a new button on the gui it will work and then the original button will also work and I have tested the exact same script on another game which works completely fine.

This is the code which I know works fine as stated before. It seems to be an issue with the specific place but im not sure what could cause something like this to happen



local devProductId = 3258933939	
local player= script.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent


script.Parent.MouseButton1Click:connect(function()
	print(player)
	game:GetService("MarketplaceService"):PromptProductPurchase(player, devProductId)
	
end)

local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService.ProcessReceipt = function(receiptInfo)
	for i, player in ipairs(game.Players:GetChildren()) do
		if player.userId == receiptInfo.PlayerId then
			if receiptInfo.ProductId == devProductId then		
				local P = game.Players:FindFirstChild(player.Name)
				P.Luck.Luck.Value += 5000
				print("WIN!")
			end
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

MarketplaceService.ProcessReceipt is a callback, not an event. You can only assign one function to handle all developer product transactions. Having multiple scripts that assign to this member of MarketplaceService will override previous callback(s), rendering the developer products they handled null.

On another note, you already have the player in your loop variable:

for i, player in ipairs(game.Players:GetChildren()) do
local P = game.Players:FindFirstChild(player.Name)

Doing this is redundant…

1 Like

So how can I have multiple then?

I linked you to ProcessReceipt’s API reference. There, Roblox demonstrates how you’re meant to use it

Ive tried to make it in one script using just one process receipt function and it still doesnt work

local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService.ProcessReceipt = function(receiptInfo)
	for i, player in ipairs(game.Players:GetChildren()) do
		if player.userId == receiptInfo.PlayerId then
			if receiptInfo.ProductId == 3258928056 then		
				player.Luck.Luck.Value += 10
				print("WIN!")
			end
			
		elseif receiptInfo.ProductId == 3258931532 then		
			player.Luck.Luck.Value += 100
			print("WIN!")
		elseif receiptInfo.ProductId == 3258933096 then		
				player.Luck.Luck.Value += 1000
				print("WIN!")
		elseif receiptInfo.ProductId == 3258935278 then		
				player.Luck.Luck.Value += 100000
				print("WIN!")
		elseif receiptInfo.ProductId == 3258934601 then		
				player.Luck.Luck.Value += 25000
				print("WIN!")
		elseif receiptInfo.ProductId == 3258933939 then		
				player.Luck.Luck.Value += 5000
				print("WIN!")
		elseif receiptInfo.ProductId == 3260806988 then		
				player.Boxes.LegendaryBox.Value += 1
				print("WIN!")
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

1 Like

Helloooo, there’s a few things I’d change here. One, use Players:GetPlayerByUserId(), there isn’t a need to loop through all the players. Also make sure that the process receipt function is on a server script and the MouseButton1Click is on a local script and if that’s the case for the player variable use game.Players.LocalPlayer no need for all those .parent’s lol.

Thirdly, if I was you I’d store some of the products in a table, so like for example with all the luck ones. So like for example:

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

local LuckIds = {
    [3258928056] = 10, -- number in the square brackets is the product id, the second number is amount you wanna give
    [3258931532] = 100,
    [3258933096] = 1000,
    -- etc

}

MarketplaceService.ProcessReceipt = function(receiptInfo)
    local Player = Players:GetPlayerByUserId(receiptInfo.PlayerId)

    if LuckIds[receiptInfo.ProductId] then
        Player.Luck.Luck.Value += LuckIds[receiptInfo.ProductId]
    else
        -- do rest here of product ids here
    end
end
1 Like

Yeah i believe i have fixed it using this which is basically the same thing

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

MarketPlaceService.ProcessReceipt = function(receiptInfo)
	local plr = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not plr then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	if receiptInfo.ProductId == 3258928056 then
		plr.Luck.Luck.Value += 10
	elseif receiptInfo.ProductId == 3258931532 then
		plr.Luck.Luck.Value += 100
	elseif receiptInfo.ProductId == 3258933096 then
		plr.Luck.Luck.Value += 1000
	elseif receiptInfo.ProductId == 3258935278 then
		plr.Luck.Luck.Value += 100000
	elseif receiptInfo.ProductId == 3258934601 then
		plr.Luck.Luck.Value += 25000
	elseif receiptInfo.ProductId == 3258933939 then
		plr.Luck.Luck.Value += 5000
	elseif receiptInfo.ProductId == 3260806988 then
		plr.Boxes.LegendaryBox.Value += 1
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

I highly recommend you use a table. This is an extremely poor approach

1 Like

for clarification he means a dictionary in code not in your grammer

3 Likes

This is not a viable way to handle the ProcessReceipt callback.

You need to check and record purchases using a GlobalDataStore and you need to properly return PurchaseGranted if the purchase has been successfully completed OR if the function detects that the purchase in question was already granted using the GlobalDataStore.

Below is a modified code sample originally taken directly from the Creator Documentation that shows how to properly utilize ProcessReceipt. I modified it so it fits your use case.

Click here to see the ProcessReceipt documentation

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

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

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

-- Developer Product Id 3258928056 for 10 Luck
productFunctions[3258928056] = function(_receipt, player)

	if player and player.Luck.Luck then

		-- Add the Luck
		player.Luck.Luck.Value += 10

		-- Indicate a successful purchase
		return true
	end
end

-- Repeat the code above for the rest of your developer products,
-- making sure you modify the developer ID in the product functions dictionary
-- and the corresponding reward that is given upon purchase

-- The core 'ProcessReceipt' callback function
local function processReceipt(receiptInfo)

	-- Check the data store to determine if the product was already granted
	local playerProductKey = receiptInfo.PurchaseId
	local purchased = false
	local success, result, errorMessage

	success, errorMessage = pcall(function()
		purchased = purchaseHistoryStore:GetAsync(playerProductKey)
	end)

	-- If the purchase is 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

	-- Update the purchase record
	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 the player returns, the callback is called again
				return nil
			end

			local handler = productFunctions[receiptInfo.ProductId]

			local success, result = pcall(handler, receiptInfo, player)
      
			-- Do not record the purchase if granting the product failed
			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 transaction 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

		-- Did not update the value in the data store
		return Enum.ProductPurchaseDecision.NotProcessedYet
	else

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

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

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.