Need help with my donation leaderboard!

The code doesnt give any errors and the issue is that it processes purchases but doesnt call the receipt function to announce in chat nor adds the robux the the leaderboard. It only works sometimes.

local leaderboardbuttons = script:WaitForChild("LeaderBoardButtons")
local firstplace = script.Parent:WaitForChild("FirstPlace")
local secondplace = script.Parent:WaitForChild("SecondPlace")
local thirdplace = script.Parent:WaitForChild("ThirdPlace") 
local buttons = script.Parent:WaitForChild("Buttons")
local screen = script.Parent:WaitForChild("Screen")
local infomation = script.Parent:WaitForChild("Infomation")

local datastore = game:GetService("DataStoreService")
local DSLB = datastore:GetOrderedDataStore("DonoPurchaseLB_")  
local productsmodule = require(script.Parent:WaitForChild("Products"))
local market = game:GetService("MarketplaceService")
local products = productsmodule.Products
local PeopleDonatedinlast1minute = {}

leaderboardbuttons.Disabled = false
leaderboardbuttons.Parent = game.StarterPlayer.StarterPlayerScripts

function Default() 
	coroutine.wrap(updatecharacter)(78217237, 1)
	coroutine.wrap(updatecharacter)(78217237, 2)
	coroutine.wrap(updatecharacter)(78217237, 3)
	
	buttons.SurfaceGui.MainFrame.Scroll.TempDono.Parent = script
	screen.SurfaceGui.MainFrame.Scroll.TempScreen.Parent = script
	for _, v in pairs(screen.SurfaceGui.MainFrame.Scroll:GetChildren()) do
		if v:IsA("Frame") then
			v:Destroy()
		end
	end
	if infomation.DoPages.Value then
		local numberofplayers = math.ceil(infomation.AmountofPlayers.Value / 15)
		local numberofproducts = math.ceil(#products / 4)
		for i = 1, numberofplayers do
			local temp = screen.SurfaceGui.MainFrame.Pages.ScreenPageTemp:Clone()
			temp.Parent = screen.SurfaceGui.MainFrame.Pages
			temp.Name = "P" .. i
		end
		screen.SurfaceGui.MainFrame.Pages.P1.Visible = true
		screen.SurfaceGui.MainFrame.Pages.ScreenPageTemp:Destroy()
		screen.SurfaceGui.MainFrame.Scroll:Destroy()
		for i = 1, numberofproducts do
			local temp = buttons.SurfaceGui.MainFrame.Pages.ButtonPageTemp:Clone()
			temp.Parent = buttons.SurfaceGui.MainFrame.Pages
			temp.Name = "P" .. i
		end
		buttons.SurfaceGui.MainFrame.Pages.ButtonPageTemp:Destroy()
		buttons.SurfaceGui.MainFrame.Scroll:Destroy()
		if #screen.SurfaceGui.MainFrame.Pages:GetChildren() == 1 then
			screen.SurfaceGui.MainFrame.Footer.PageNumbers:Destroy()
		end
		if #buttons.SurfaceGui.MainFrame.Pages:GetChildren() == 1 then
			buttons.SurfaceGui.MainFrame.Footer.PageNumbers:Destroy()
		end
	else
		buttons.SurfaceGui.MainFrame.Pages:Destroy()
		buttons.SurfaceGui.MainFrame.Footer.PageNumbers:Destroy()
		screen.SurfaceGui.MainFrame.Footer.PageNumbers:Destroy()
		screen.SurfaceGui.MainFrame.Pages:Destroy()
	end
	for place, v in pairs(products) do
		local button = script.TempDono:Clone()
		button.Text = NumberConvert(v.ProductPrice) .. " Robuxs"
		button.LayoutOrder = place
		button.Name = v.ProductId
		if infomation.DoPages.Value then
			button.Parent = buttons.SurfaceGui.MainFrame.Pages["P" .. math.ceil(place / 4)]
		else
			button.Parent = buttons.SurfaceGui.MainFrame.Scroll
		end
	end
end

function find(tab, object, Type)
	for i, v in pairs(tab) do
		if Type == "i" then
			if i == object then
				return true
			end
		elseif Type == "v" then
			if v == object then
				return true
			end
		end
	end
	return false
end

function updatecharacter(userid, number)
	local description = game.Players:GetHumanoidDescriptionFromUserId(tonumber(userid))
	local character
	local animName = "First"

	if number == 1 then
		character = firstplace
		animName = "First"
	elseif number == 2 then
		character = secondplace
		animName = "Second"
	elseif number == 3 then
		character = thirdplace
		animName = "Third"
	end

	local humanoid = character:WaitForChild("Humanoid")

	character.Humanoid:ApplyDescription(description)
	if character:FindFirstChild("Tags") then
		character.Tags.Container.pName.Text = safeGetNameFromUserIdAsync(tonumber(userid))  
	end

end

function NumberConvert(num)
	local x = tostring(num)
	if #x:split("") < 7 then
		if #x >= 10 then
			local important = (#x - 9)
			return x:sub(0, (important)) .. "," .. x:sub(important + 1, important + 3) .. "," .. x:sub(important + 4, important + 6) .. "," .. x:sub(important + 7)
		elseif #x >= 7 then
			local important = (#x - 6)
			return x:sub(0, (important)) .. "," .. x:sub(important + 1, important + 3) .. "," .. x:sub(important + 4)
		elseif #x >= 4 then
			return x:sub(0, (#x - 3)) .. "," .. x:sub((#x - 3) + 1)
		else
			return num
		end
	else
		local suffixes = {"k", "M", "B", "T", "qd", "Qn", "sx", "Sp", "O", "N", "de", "Ud", "DD", "tdD", "qdD", "QnD", "sxD", "SpD", "OcD", "NvD", "Vgn", "UVg", "DVg", "TVg", "qtV", "QnV", "SeV", "SPG", "OVG", "NVG"}
		local amnt = math.floor(((#x) - 1) / 3)
		local remove = 3 * amnt
		local important = (#x - 6)
		if suffixes[amnt] then
			local retuen
			if important + 1 > 0 then
				retuen = x:sub(0, (important)) .. "." .. x:sub(important + 1, important + 1) .. suffixes[amnt]
			else
				retuen = x:sub(0, (important)) .. suffixes[amnt]
			end
			return retuen
		end
	end
end

function safeGetNameFromUserIdAsync(userId)
	local maxRetries = 3
	local retries = 0
	local success, result

	repeat
		success, result = pcall(function()
			return game.Players:GetNameFromUserIdAsync(userId)
		end)

		if not success then
			wait(5)  
			retries = retries + 1
		end
	until success or retries >= maxRetries

	return result or "Unknown" 
end
function receipt(receiptInfo)
	DSLB:IncrementAsync(receiptInfo.PlayerId, receiptInfo.CurrencySpent)
	local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
	local robux = receiptInfo.CurrencySpent
	local prefix = "<font color='rgb(255, 255, 255)'>" .. player.Name .. "</font>"
	local rb = "<font color='rgb(85, 255, 127)'>" .. tostring(robux) .. " Robux" .. "</font>"
	local str = prefix .. " just donated " .. rb .. "!"

	local prefix1 = "<font color='rgb(255, 255, 255)'>" .. player.Name:upper() .. "</font>"
	local rb1 = "<font color='rgb(85, 255, 127)'>" .. tostring(robux) .. " ROBUX" .. "</font>"
	local str1 = prefix1 .. " JUST DONATED " .. rb1 .. "!"
	
	print(robux)
	if robux >= 1000 then
		game:GetService("MessagingService"):PublishAsync("GlobalDonate", str1)
	else
		game:GetService("ReplicatedStorage").Remotes.SystemChat:FireAllClients(str, false)
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

market.ProcessReceipt = receipt

Default()  


function updateboard()
	if infomation.DoPages.Value then
		for _, page in pairs(screen.SurfaceGui.MainFrame.Pages:GetChildren()) do
			for _, v in pairs(page:GetChildren()) do
				if v:IsA("Frame") then
					v:Destroy()
				end
			end
		end
	else
		for _, v in pairs(screen.SurfaceGui.MainFrame.Scroll:GetChildren()) do
			if v:IsA("Frame") then
				v:Destroy()
			end
		end
	end

	local success, errorMessage = pcall(function()
		local Data
		if infomation.AmountofPlayers.Value < 0 then
			Data = DSLB:GetSortedAsync(false, 15)
		elseif infomation.AmountofPlayers.Value > 60 then
			Data = DSLB:GetSortedAsync(false, 60)
		else
			Data = DSLB:GetSortedAsync(false, infomation.AmountofPlayers.Value)
		end
		local WinPage = Data:GetCurrentPage()
		for Rank, data in ipairs(WinPage) do
			local userName = safeGetNameFromUserIdAsync(data.key)
			local Name = userName
			local amount = data.value
			local isOnLeaderboard = false
			if infomation.DoPages.Value then
				for _, page in pairs(screen.SurfaceGui.MainFrame.Pages:GetChildren()) do
					for _, v in pairs(page:GetChildren()) do
						if v.Name == Name then
							isOnLeaderboard = true
							break
						end
					end
				end
			else
				for _, v in pairs(screen.SurfaceGui.MainFrame.Scroll:GetChildren()) do
					if v.Name == Name then
						isOnLeaderboard = true
						break
					end
				end
			end
			if amount > 0 and isOnLeaderboard == false then
				if Rank <= 3 then
					coroutine.wrap(updatecharacter)(data.key, Rank)
				end
				local newLBFrame = script.TempScreen:Clone()
				newLBFrame.Title.Text = Name
				newLBFrame.Explaination.Text = coroutine.wrap(NumberConvert)(amount)  
				newLBFrame.LayoutOrder = Rank
				newLBFrame.Name = Name
				newLBFrame.Visible = true
				if infomation.ShowUserThumbnail.Value then
					newLBFrame.Icon.Image = game.Players:GetUserThumbnailAsync(data.key, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
				else
					newLBFrame.Icon:Destroy()
				end
				if infomation.DoPages.Value then
					newLBFrame.Parent = screen.SurfaceGui.MainFrame.Pages["P" .. math.ceil(Rank / 15)]
				else
					newLBFrame.Parent = screen.SurfaceGui.MainFrame.Scroll
				end
				local color = nil
				if Rank == 1 then
					color = infomation.PlaceColors.First.Value
				elseif Rank == 2 then
					color = infomation.PlaceColors.Second.Value
				elseif Rank == 3 then
					color = infomation.PlaceColors.Third.Value
				else
					color = infomation.PlaceColors.Rest.Value
				end

				newLBFrame.Title.BackgroundColor3 = color
				newLBFrame.Explaination.BackgroundColor3 = color
			end

			local player = game:GetService("Players"):GetPlayerByUserId(data.key)
			for i, v in pairs(game:GetService("Players"):GetPlayers()) do
				if player == v then
					player.DonateTop.Value = Rank
				end
			end
		end
	end)

	if not success then
		print("TimeLB error: " .. errorMessage)
	end
end

script.UpdateplayerDonoStats.OnServerEvent:Connect(function(player, product)
	market:PromptProductPurchase(player, tonumber(product))
	print(product)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local num = 0
	if find(PeopleDonatedinlast1minute, player.UserId, "i") then
		if DSLB:GetAsync(player.UserId) then
			num = DSLB:GetAsync(player.UserId)
		end
		DSLB:SetAsync(player.UserId, PeopleDonatedinlast1minute[player.UserId] + num)
		PeopleDonatedinlast1minute[player.UserId] = 0
	end
end)

updateboard()
while wait(0) do
	for i, v in pairs(PeopleDonatedinlast1minute) do
		if v > 0 then
			if DSLB:GetAsync(i) then
				num = DSLB:GetAsync(i)
			end
			DSLB:SetAsync(i, v)
		end
	end
	table.clear(PeopleDonatedinlast1minute)
	print(PeopleDonatedinlast1minute)
	wait(1)
	updateboard()
	wait(60)
end