I have a shop gui which has products that gives the player more 'Dev Credits'. What happens is that when the player spam clicks on buy, or they keep buying the same product for a while the purchase starts to duplicate, what I mean by that is the player is charged extra but they also get extra credits. I've tried to use PurchaseId and debounces to try and prevent this but it doesnt do much. This has also apparently been happening to other people so I dont know if its something wrong with my scripts or if its just a bug from roblox.

Local Script:

-- Scripted by LifeInDevelopment 
local marketPlaceService = game:GetService('MarketplaceService')

local player = game.Players.LocalPlayer

local productFrame = script.Parent
local contentFrame = productFrame.Parent
local currencyShopGui = contentFrame.Parent

local infoFrame = contentFrame:WaitForChild('InfoFrame')
local buyButton = infoFrame:WaitForChild('BuyButton')
local descriptionLabel = infoFrame:WaitForChild('DescriptionLabel')
local nameLabel = infoFrame:WaitForChild('NameLabel')

local product1Frame = productFrame:WaitForChild('Product1Frame')
local product2Frame = productFrame:WaitForChild('Product2Frame')
local product3Frame = productFrame:WaitForChild('Product3Frame')
local product4Frame = productFrame:WaitForChild('Product4Frame')
local product5Frame = productFrame:WaitForChild('Product5Frame')
local product6Frame = productFrame:WaitForChild('Product6Frame')

local product1BuyButton = product1Frame:WaitForChild('BuyButton')
local product2BuyButton = product2Frame:WaitForChild('BuyButton')
local product3BuyButton = product3Frame:WaitForChild('BuyButton')
local product4BuyButton = product4Frame:WaitForChild('BuyButton')
local product5BuyButton = product5Frame:WaitForChild('BuyButton')
local product6BuyButton = product6Frame:WaitForChild('BuyButton')

local selectedProduct
local db = false
buyButton.MouseButton1Down:connect(function()
	if selectedProduct and not db then
		db = true
		marketPlaceService:PromptProductPurchase(player, selectedProduct)
		wait(5)
		db = false
	end
end)

product1BuyButton.MouseButton1Down:connect(function()
	selectedProduct = 45963513 
	infoFrame.Visible = true
	nameLabel.Text = '50 Dev Credits'
	descriptionLabel.Text = 'Buy this to get 50 Dev Credits for 10 Robux!'
end)

product2BuyButton.MouseButton1Down:connect(function()
	selectedProduct = 45964179 
	infoFrame.Visible = true
	nameLabel.Text = '100 Dev Credits'
	descriptionLabel.Text = 'Buy this to get 100 Dev Credits for 20 Robux!'
end)

product3BuyButton.MouseButton1Down:connect(function()
	selectedProduct = 45964222 
	infoFrame.Visible = true
	nameLabel.Text = '250 Dev Credits'
	descriptionLabel.Text = 'Buy this to get 250 Dev Credits for 50 Robux!'
end)

product4BuyButton.MouseButton1Down:connect(function()
	selectedProduct = 45964324 	
	infoFrame.Visible = true
	nameLabel.Text = '525 Dev Credits'
	descriptionLabel.Text = 'Buy this to get 525 Dev Credits for 100 Robux. You get 5% extra Dev Credits!'
end)

product5BuyButton.MouseButton1Down:connect(function()
	selectedProduct = 45964354 
	infoFrame.Visible = true
	nameLabel.Text = '1375 Dev Credits'
	descriptionLabel.Text = 'Buy this to get 1375 Dev Credits for 250 Robux. You get 10% extra Dev Credits!'
end)

product6BuyButton.MouseButton1Down:connect(function()
	selectedProduct = 45964368 
	infoFrame.Visible = true
	nameLabel.Text = '2800 Dev Credits'
	descriptionLabel.Text = 'Buy this to get 2800 Dev Credits for 500 Robux. You get 12% extra Dev Credits!'
end)

Server Script:

-- Scripted by LifeInDevelopment
local dataStoreService = game:GetService('DataStoreService')
local marketPlaceService = game:GetService('MarketplaceService')

local devCreditsDataStore = dataStoreService:GetDataStore('DevCredits')

local shopProductId = 45785623

local purchaseHistory = dataStoreService:GetDataStore('PurchaseHistory')

marketPlaceService.ProcessReceipt = function(receiptInfo)
	local productKey = receiptInfo.PlayerId .. ':' .. receiptInfo.PurchaseId
	local playerId = receiptInfo.PlayerId
	local id = receiptInfo.ProductId
	local player = game.Players:GetPlayerByUserId(playerId)
	if not player then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	if purchaseHistory:GetAsync(productKey) then
		return Enum.ProductPurchaseDecision.PurchaseGranted 
	end
	if receiptInfo.ProductId == shopProductId then
		-- do stuff later
		return Enum.ProductPurchaseDecision.PurchaseGranted
	else
		if id == 45963513 then
			player.DevCredits.Value = player.DevCredits.Value + 50
		elseif id == 45964179 then
			player.DevCredits.Value = player.DevCredits.Value + 100
		elseif id == 45964222 then
			player.DevCredits.Value = player.DevCredits.Value + 250
		elseif id == 45964324 then
			player.DevCredits.Value = player.DevCredits.Value + 525
		elseif id == 45964354 then
			player.DevCredits.Value = player.DevCredits.Value + 1375
		elseif id == 45964368 then
			player.DevCredits.Value = player.DevCredits.Value + 2800
		end

		devCreditsDataStore:SetAsync(receiptInfo.PlayerId, player.DevCredits.Value)
		purchaseHistory:SetAsync(productKey, true)
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
end