Player keeps getting developer product reward when rejoining

Hello there, I have messed up my developer product system really badly. When a player makes a purchase, it will duplicate that current purchase and give the new purchase, along with that, the player gets everything they purchased DUPLICATED again when they rejoin, please help!

Code:

local mps = game:GetService("MarketplaceService")
local webHookService = require(game.ServerScriptService.WebhookService)
local http = game:GetService("HttpService")

mps.ProcessReceipt = function(purchaseInfo)
	print('proccessed')
	local Index = require(game.ReplicatedStorage.Framework.Index)
	local plrPurchased = game.Players:GetPlayerByUserId(purchaseInfo.PlayerId)
	
	if not plrPurchased then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	
	if purchaseInfo.ProductId == 1245882067 then

		local petsUnlockTable = {"Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Gargoyle Dragon", "Huge Gargoyle Dragon", "Rainbow Huge Signature"}

		local petString = petsUnlockTable[math.random(1,#petsUnlockTable)]

		local fakeVal = Instance.new("StringValue")
		fakeVal.Parent = game.ReplicatedStorage
		fakeVal.Name = petString

		local realVal = Instance.new("NumberValue") 
		realVal.Value = Index.GetPetDamage(petString)
		realVal.Name = petString 
		realVal.Parent = plrPurchased.Pets

		game.ReplicatedStorage.Framework.Network.Hatch1EggEvent:FireClient(plrPurchased, fakeVal, "Gift Egg")
		game.ReplicatedStorage.purchaseComplete:FireClient(plrPurchased)

		local data = 
			{
				["content"] = "",
				["embeds"] = {{
					["title"] = "Product Receipt",
					["description"] = plrPurchased.Name .. " has purchased a new product! ✅",
					["type"] = "rich",
					["color"] = tonumber(0xed971f),
					["fields"] = {
						{
							["name"] = "Buyer:",
							["value"] = plrPurchased.Name,
							["inline"] = true
						},
						{
							["name"] = "Product Bought:",
							["value"] = petString,
							["inline"] = true
						}
					}
				}}
			}

		local newdata = http:JSONEncode(data)
		http:PostAsync(url, newdata)

		return Enum.ProductPurchaseDecision.PurchaseGranted
	end

	if purchaseInfo.ProductId == 1245882021 then

		local petsUnlockTable1 = {"Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Gargoyle Dragon", "Huge Gargoyle Dragon", "Rainbow Huge Signature"}
		local petsUnlockTable2 = {"Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Gargoyle Dragon", "Huge Gargoyle Dragon", "Rainbow Huge Signature"}
		local petsUnlockTable3 = {"Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Pog Cat", "Huge Pog Dog", "Huge Gargoyle Dragon", "Huge Gargoyle Dragon", "Rainbow Huge Signature"}

		local petString1 = petsUnlockTable1[math.random(1,#petsUnlockTable1)]
		local petString2 = petsUnlockTable2[math.random(1,#petsUnlockTable2)]
		local petString3 = petsUnlockTable3[math.random(1,#petsUnlockTable3)]

		local fakeVal1 = Instance.new("StringValue")
		fakeVal1.Parent = game.ReplicatedStorage
		fakeVal1.Name = petString1

		local realVal1 = Instance.new("NumberValue") 
		realVal1.Value = Index.GetPetDamage(petString1)
		realVal1.Name = petString1
		realVal1.Parent = plrPurchased.Pets

		local fakeVal2 = Instance.new("StringValue")
		fakeVal2.Parent = game.ReplicatedStorage
		fakeVal2.Name = petString2

		local realVal2 = Instance.new("NumberValue") 
		realVal2.Value = Index.GetPetDamage(petString2)
		realVal2.Name = petString2
		realVal2.Parent = plrPurchased.Pets

		local fakeVal3 = Instance.new("StringValue")
		fakeVal3.Parent = game.ReplicatedStorage
		fakeVal3.Name = petString3

		local realVal3 = Instance.new("NumberValue") 
		realVal3.Value = Index.GetPetDamage(petString3)
		realVal3.Name = petString3
		realVal3.Parent = plrPurchased.Pets
		
		game.ReplicatedStorage.Framework.Network.Hatch3EggsEvent:FireClient(plrPurchased, fakeVal1, fakeVal2, fakeVal3, "Gift Egg")
		game.ReplicatedStorage.purchaseComplete:FireClient(plrPurchased)
		
		local data = 
			{
				["content"] = "",
				["embeds"] = {{
					["title"] = "Product Receipt",
					["description"] = plrPurchased.Name .. " has purchased a new product! ✅",
					["type"] = "rich",
					["color"] = tonumber(0xed971f),
					["fields"] = {
						{
							["name"] = "Buyer:",
							["value"] = plrPurchased.Name,
							["inline"] = true
						},
						{
							["name"] = "Product Bought:",
							["value"] = petString1 .. ", " .. petString2 .. ", " .. petString3,
							["inline"] = true
						}
					}
				}}
			}

		local newdata = http:JSONEncode(data)
		http:PostAsync(url, newdata)

		return Enum.ProductPurchaseDecision.PurchaseGranted
	end

end```
2 Likes

You are returning a value that isn’t Enum.ProductPurchaseDecision.PurchaseGranted somewhere. Is your script erroring anywhere? Are you sure your product ID is one that’s in the script?

You should add prints to find what is and what isn’t happening.

hi, the error I’m getting is “Receipt is already being processed”

Do you have multiple scripts trying to handle .ProcessReceipt?

When a developer product is purchased, it saves?

1 Like

Hey! Have you tried looking at the developer hub? https://developer.roblox.com/en-us/api-reference/callback/MarketplaceService/ProcessReceipt
This might help you, as you can compare the two.

Also, I would recommend you make this block of code a function as it looks more clean this way.

2 Likes