Dev Product works in local testing, but not in real games

As you can see in this video, Dev Product is not working.
The purchase will proceed, but no payment will be made.

But with local testing, this works.
Iโ€™m very confused right now. How on earth do I fix this?

local DataManager = require(script.Parent.DataManager)
local devProducts = require(game:GetService("ReplicatedStorage"):WaitForChild("DeveloperProducts"))
local mps = game:GetService("MarketplaceService")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	----------------------- 
	local coins = Instance.new("IntValue", leaderstats)
	coins.Name = "coins"

	-----------------------
	local Data = DataManager:GetData(player)
	while Data == nil do
		task.wait()
		Data = DataManager:GetData(player)
	end

	-----------------------
	coins.Value = Data.coins

	-----------------------
	local function OnValueChanged(IntValue)
		DataManager:UpdateData(player, IntValue.Name, IntValue.Value)
	end

	coins.Changed:Connect(function()
		OnValueChanged(coins)
	end)
end)

-----------------------
coroutine.wrap(function()
	while wait(120) do --๊ธฐ๋ณธ๊ฐ’120 ํ•„์ˆ˜๋ณ€๊ฒฝ ์ถ”ํ›„
		for i, player in ipairs(game.Players:GetPlayers()) do
			if player:FindFirstChild("leaderstats") then
				player.leaderstats["coins"].Value += 10 --๊ธฐ๋ณธ๊ฐ’10 ํ•„์ˆ˜๋ณ€๊ฒฝ ์ถ”ํ›„
			end
		end
	end
end)()

coroutine.wrap(function()
	while wait(300) do
		for i, player in ipairs(game.Players:GetPlayers()) do
			DataManager:SaveData(player)
		end
	end
end)()

function handlePurchase(purchaseInfo)
	local plr = game.Players:GetPlayerByUserId(purchaseInfo.PlayerId)

	if not plr or plr:FindFirstChild("DATA FAILED TO LOAD") then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local productID = purchaseInfo.ProductId

	if devProducts[productID] then
		plr.leaderstats["coins"].Value += devProducts[productID].Cash
		return Enum.ProductPurchaseDecision.PurchaseGranted
	else
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
end

mps.ProcessReceipt = handlePurchase

This is a code that updates data when purchasing coins. (There are other functions as well.)

2 Likes

You should add some logging events to track the ProcessReceipt handler behavior.

So the handler should look something like this:

function handlePurchase(purchaseInfo)
	local plr = game.Players:GetPlayerByUserId(purchaseInfo.PlayerId)

	if not plr or plr:FindFirstChild("DATA FAILED TO LOAD") then
		print("No player was found, or the data failed to load")
		
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local productID = purchaseInfo.ProductId

	if devProducts[productID] then
		plr.leaderstats["coins"].Value += devProducts[productID].Cash
		return Enum.ProductPurchaseDecision.PurchaseGranted
	else
		print("No ProductId behavior was configured")
		
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
end
2 Likes

Iโ€™m sorry, it still doesnโ€™t work. Is it right to apply it to the code like this?

local DataManager = require(script.Parent.DataManager)
local devProducts = require(game:GetService("ReplicatedStorage"):WaitForChild("DeveloperProducts"))
local mps = game:GetService("MarketplaceService")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	----------------------- 
	-- ๋ฆฌ๋”๋ณด๋“œ ๋ถ€๋ถ„
	local coins = Instance.new("IntValue", leaderstats)
	coins.Name = "coins"

	-----------------------
	-- ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ถ€๋ถ„
	local Data = DataManager:GetData(player)
	while Data == nil do
		task.wait()
		Data = DataManager:GetData(player)
	end

	-----------------------
	-- ๋ถˆ๋Ÿฌ์˜จ ๋ฐ์ดํ„ฐ ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„
	coins.Value = Data.coins

	-----------------------
	-- ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ/์ €์žฅํ•˜๋Š” ๋ถ€๋ถ„
	local function OnValueChanged(IntValue)
		DataManager:UpdateData(player, IntValue.Name, IntValue.Value)
	end

	coins.Changed:Connect(function()
		OnValueChanged(coins)
	end)
end)

-----------------------
-- ๋ฐ์ดํ„ฐ ์ž๋™์ €์žฅ
coroutine.wrap(function()
	while wait(120) do --๊ธฐ๋ณธ๊ฐ’120 ํ•„์ˆ˜๋ณ€๊ฒฝ ์ถ”ํ›„
		for i, player in ipairs(game.Players:GetPlayers()) do
			if player:FindFirstChild("leaderstats") then
				player.leaderstats["coins"].Value += 10 --๊ธฐ๋ณธ๊ฐ’10 ํ•„์ˆ˜๋ณ€๊ฒฝ ์ถ”ํ›„
			end
		end
	end
end)()

coroutine.wrap(function()
	while wait(300) do
		for i, player in ipairs(game.Players:GetPlayers()) do
			DataManager:SaveData(player)
		end
	end
end)()

-- ๊ตฌ๋งค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜
function handlePurchase(purchaseInfo)
	local plr = game.Players:GetPlayerByUserId(purchaseInfo.PlayerId)

	if not plr or plr:FindFirstChild("DATA FAILED TO LOAD") then
		print("No player was found, or the data failed to load")

		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local productID = purchaseInfo.ProductId

	if devProducts[productID] then
		plr.leaderstats["coins"].Value += devProducts[productID].Cash
		return Enum.ProductPurchaseDecision.PurchaseGranted
	else
		print("No ProductId behavior was configured")

		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
end

mps.ProcessReceipt = handlePurchase

It still works for local testing.

1 Like

Itโ€™s not intended to fix your problem. This code logs the ProcessReceipt flow behavior, so then you can look at the logs in the live game and see the reason why the currency is not being incremented.

2 Likes