Cant save data on the leaderstats

so im making guess the anime game and i have problem with the leaderstats.
I have two leaderstats: Stage and Points.
Stage is show u what stage u are and you can purchase for skip stage.
Points is how much door/stage u did opened so far.
I want to do save data only to points but i cant.
The problem is that the save data not working.
i think its not working because the points and the save data not in the same script
and if i put them together the points dont show on the leader stats.
How do i save the data of the points without broke the stages or the checkpoints script.
anyway this is the scripts:

Checkpoints(Script in ServerScriptService):

local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SkipStage = ReplicatedStorage:WaitForChild("SkipStage")

local Checkpoints = workspace:WaitForChild("Checkpoints")
local inGameStartupPlayers = {}
local CurrentStage = {}
local CurrentPoints = {}
local TouchDb = {}

local ProductId = 1145455293
local Products = {
	{
		ProductPrice = 5, --The price from the Developer Product.
		ProductId = 1141211330 -- The ID from the Developer Product.	
	},
	{
		ProductPrice = 25, --The price from the Developer Product.
		ProductId = 1141214738 -- The ID from the Developer Product.	
	},
	{
		ProductPrice = 50, --The price from the Developer Product.
		ProductId = 1141214866 -- The ID from the Developer Product.	
	},
	{
		ProductPrice = 100, --The price from the Developer Product.
		ProductId = 1141214989 -- The ID from the Developer Product.	
	},
	{
		ProductPrice = 1000, --The price from the Developer Product.
		ProductId = 1141215192 -- The ID from the Developer Product.	
	},
	
}


local function NewCharacter(player, char)
	local TempCurrentStage = CurrentStage[player.UserId]
	if TempCurrentStage ~= nil then
		local TempCheckpoint = Checkpoints:FindFirstChild(TempCurrentStage)
		if TempCheckpoint ~= nil then
			repeat wait(0.1) until char.PrimaryPart ~= nil
			char:SetPrimaryPartCFrame(CFrame.new(TempCheckpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(TempCheckpoint.Orientation.Y) + math.rad(90), 0))
		end
	end
end

local function NewPlayer(player)
	CurrentStage[player.UserId] = 1

	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local Stage = Instance.new("IntValue", leaderstats)
	Stage.Name = "Stage"
	Stage.Value = 1
	
	local Points = Instance.new("IntValue", leaderstats)
	Points.Name = "Points"
	Points.Value = 0
	
	local TempChar = player.Character
	if TempChar ~= nil then
		NewCharacter(player, TempChar)
	end
	player.CharacterAdded:Connect(function(char)
		NewCharacter(player, char)
	end)
end

Players.PlayerAdded:Connect(function(player)
	if inGameStartupPlayers[player] == nil then
		NewPlayer(player)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	CurrentStage[player.UserId] = nil
end)

SkipStage.OnServerInvoke = function(player)
	local connection
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats ~= nil then
		local Stage = leaderstats:FindFirstChild("Stage")
		if Stage ~= nil then
			if #Checkpoints:GetChildren() ~= Stage.Value then
				local PurchaseResult = "Purchase Failed"
				connection = MarketplaceService.PromptProductPurchaseFinished:Connect(function(userId, productId, purchased)
					if player.UserId == userId and productId == ProductId then
						if purchased == true then
							PurchaseResult = "Success"
						end
					end
					connection:Disconnect()
				end)
				MarketplaceService:PromptProductPurchase(player, ProductId)
				repeat wait(0.1) until connection.Connected == false or Players:GetPlayerByUserId(player.UserId) == nil
				return PurchaseResult
			else
				return "You have reached the highest stage!"
			end
		end
	end
end

MarketplaceService.ProcessReceipt = function(recieptInfo)
	local player = Players:GetPlayerByUserId(recieptInfo.PlayerId)

	-- Don't grant purchase if the player left or is not here for whatever reason
	if not player then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	if recieptInfo.ProductId == ProductId then
		CurrentStage[player.UserId] = CurrentStage[player.UserId] + 1
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats ~= nil then
			local Stage = leaderstats:FindFirstChild("Stage")
			if Stage ~= nil then
				Stage.Value = CurrentStage[player.UserId]
			end
		end
		local TempChar = player.Character
		if TempChar ~= nil then
			NewCharacter(player, TempChar)
		end
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end

	-- Loop through the product data
	for _, productData in ipairs(Products) do
		-- if the productData's productId matches the prouct being purchased's id then continue
		if productData.ProductId == recieptInfo.ProductId then
			-- Since IncrementAsync can error we wrap it in a pcall (protected call)
			local success, err = pcall(function()
				game:GetService("DataStoreService"):GetOrderedDataStore("TopDonators"):IncrementAsync(player.UserId, productData.ProductPrice)
			end)
			-- If it errored we wanna know what went wrong
			if success then
				return Enum.ProductPurchaseDecision.PurchaseGranted
			else
				warn("Failed to increment amount donated. Error thrown: " .. err)
				return Enum.ProductPurchaseDecision.NotProcessedYet
			end
		end
	end

	return Enum.ProductPurchaseDecision.NotProcessedYet
end

for i,v in pairs(Checkpoints:GetChildren()) do
	local StageNum = tonumber(v.Name)
	v.Touched:Connect(function(hit)
		local char = hit.Parent
		if char ~= nil then
			local Humanoid = char:FindFirstChildOfClass("Humanoid")
			if Humanoid ~= nil and Humanoid.Health > 0 then
				local player = Players:GetPlayerFromCharacter(char)
				if player ~= nil and (TouchDb[player.UserId] or 0) + 1 <= os.time() then
					TouchDb[player.UserId] = os.time()
					local TempCurrentStage = CurrentStage[player.UserId]
					if TempCurrentStage == StageNum - 1 then
						CurrentStage[player.UserId] = StageNum
						local TempLeaderstats = player:FindFirstChild("leaderstats")
						if TempLeaderstats ~= nil then
							local TempStage = TempLeaderstats:FindFirstChild("Stage")
							if TempStage ~= nil then
								TempStage.Value = StageNum
							end
						end
					end
				end
			end
		end
	end)
end

inGameStartupPlayers = Players:GetPlayers()
for i,v in pairs(inGameStartupPlayers) do
	spawn(function()
		NewPlayer(v)
	end)
end

inGameStartupPlayers = {}

SaveData(Script in ServerScriptService)

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore") -- This can be changed to whatever you want

local function saveData(player) -- The functions that saves data

	local tableToSave = {
		player.leaderstats.Points.Value; -- First value from the table
		 
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
	end)

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)		
	end
end

game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game

	-- // Assigning player stats //
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Points = Instance.new("IntValue")
	Points.Name = "Points"
	Points.Parent = leaderstats

	

	local data -- We will define the data here so we can use it later, this data is the table we saved
	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore

	end)

	if success then -- If there were no errors and player loaded the data

		Points.Value = data[1] -- Set the money to the first value of the table (data)
		 -- Set the coins to the second value of the table (data)

	else -- The player didn't load in the data, and probably is a new player
		print("The player has no data!") -- The default will be set to 0
	end

end)

game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
	local success, err  = pcall(function()
		saveData(player) -- Save the data
	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)

		if success then
			print("Data has been saved")
		else
			print("Data has not been saved!")
		end
	end
end)

It seems like you’re only attempting to save data once, regardless if it fails or not.
You should add a repeat loop to attempt to save until it’s successful (or x amount of tries).

You should also save data on an interval, including game:BindToClose().

More information on how to save data here: Saving Player Data