ProcessReceipt Purchase History saving

Someone told me that the ProcessReceipt function can be called twice, which I don’t want to multiply any values to giving the player.

So I decided to make a DataStore2, which if the player has no data, the Purchased will be false. If all goes through, I set the DataStore2 to true. I tried my best to copy how it was done in the Process Receipt code sample from Roblox.

These products are developer products, which I want it to be bought multiple times which if I add a PurchaseHistory, it’s not gonna allow the Player to get the product again, but at the same time, someone told me that I should add a datastore because the ProcessReceipt function can be called more than one time.

How can I save the Purchase History, but making the player be able to purchase the product again without the ProcessReceipt being called more than once?

--[[ NoobsterStudio ]]--

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

local DataStore2 = require(ServerScriptService.DataStore2)

local StageEvent = ReplicatedStorage.StageEvent
local MessageEvent = ReplicatedStorage.MessageEvent

local SkipStageProductId = 1083175537

DataStore2.Combine("Data", "PurchaseHistory")

local ProductFunctions = {
	[SkipStageProductId] = function(Receipt, Player)
		StageEvent:Fire(Player)
		Player:LoadCharacter()
		return true
	end
}

local function ProcessReceipt(ReceiptInfo)
	local Player = Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
	
	if not Player then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	
	local PurchaseHistoryDataStore = DataStore2("PurchaseHistory", Player)
	local Purchased = PurchaseHistoryDataStore:Get(false)
	
	if Purchased then
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
	
	local Handler = ProductFunctions[ReceiptInfo.ProductId]
	
	local Success, Result = pcall(Handler, ReceiptInfo, Player)
	
	if not Success or not Result then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	
	PurchaseHistoryDataStore:Set(true)
	
	local Success, Error = pcall(function()
		PurchaseHistoryDataStore:Save()
	end)
	
	if not Success then
		MessageEvent:FireClient(Player, "Your Purchase History did not save.")
	end
	
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

MarketplaceService.ProcessReceipt = ProcessReceipt

Problem solved. Did it the wrong way.