Event keeps firing?

Why does the event fire every time the player leaves and comes online again (after they bought it onces)

local MarketPlaceService = game:GetService("MarketplaceService")
local players = game:GetService("Players")
local Repli = game:GetService("ReplicatedStorage")

local fiftyrobloxdonationid = 1239962194

local function processReceipt(receiptInfo)
	local Spent = receiptInfo.CurrencySpent
	local MessageSpent = tostring(Spent)
	local player = players:GetPlayerByUserId(receiptInfo.PlayerId)
	if player then 
		Repli.DonationMessage:FireAllClients(MessageSpent, player)
		player.leaderstats.Donated.Value += Spent
	end
	
end

MarketPlaceService.ProcessReceipt = processReceipt

Is this a dev product? If so, you should have a randomly generated DataStore key, to make sure this doesn’t happen. More info on it here! (You can also use PromptProductPurchaseFinished, located here.)

If it is indeed a gamepass, utilize PromptGamePassPurchaseFinished, as it will give you the result you’d like. I hope you found use of one of these!

I do understand what they mean in the posts you send me and it is a dev product. But in this script, there are multiple id’s for this one script and I’m struggling to wrap my head around how to implement the saving of the purchase into my own script

You can use MarketplaceService:PlayerOwnsAsset to check if they already own the asset.

The first method up there can track granted purchases, and give the item.

Here is a code snippet from it that may help you further:

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[123123] = function(receipt, player)
	-- Logic/code for player buying a full heal (may vary)
	if player.Character and player.Character:FindFirstChild("Humanoid") then
		-- Heal the player to full health
		player.Character.Humanoid.Health = player.Character.Humanoid.MaxHealth
		-- Indicate a successful purchase
		return true
	end
end
-- ProductId 456456 for 100 gold
productFunctions[456456] = function(receipt, player)
	-- Logic/code for player buying 100 gold (may vary)
	local stats = player:FindFirstChild("leaderstats")
	local gold = stats and stats:FindFirstChild("Gold")
	if gold then
		gold.Value = gold.Value + 100
		-- Indicate a successful purchase
		return true
	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 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 they come back, the callback will be called again
				return nil
			end
 
			local handler = productFunctions[receiptInfo.ProductId]
 
			local success, result = pcall(handler, receiptInfo, player)
			-- If granting the product failed, do NOT record the purchase in datastores.
			if not success or not result then
				error("Failed to process a product purchase for ProductId:", receiptInfo.ProductId, " Player:", player)
				return nil
			end
 
			-- Record the transcation 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
		-- Didn't update the value in 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

do you know if there is a way to save the data of the purchase without needing the purchase id? or is that just the datastore part of the script u send me bc i dont think u need a purchase id for that only from the receipt info

ProcessReceipt is a callback not an event, so it doesn’t fire it executes, but the reason this occurs is because you’re not specifying whether or not the purchase was handled successfully.

if player then 
	Repli.DonationMessage:FireAllClients(MessageSpent, player)
	player.leaderstats.Donated.Value += Spent
	return Enum.ProductPurchaseDecision.PurchaseGranted
else
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

https://developer.roblox.com/en-us/api-reference/enum/ProductPurchaseDecision

Thanks man this was the solution

Man this was the little more complicated solution but still learned alot from reading the articles thanks