Donation Buttons Help

Note: Go to Post #7 for update on script!

I was trying to make a donation list game where you can donate to others like Pls Donate. But, it didn’t work as expected. I tried to search over the web but nothing helped me figure it out. I’d appreciate if you would help me out on this.

If you want to know what’s happening when I claim a board, nothing happens(no errors)

Here are my scripts:
Claiming the Board script:

script.Parent.ProximityPrompt.Triggered:Connect(function(plr)
	if plr then
		if script.Parent and script.Parent.Parent and script.Parent.Parent:WaitForChild("Values") and script.Parent.Parent:WaitForChild("Values"):WaitForChild("Owner") then
			plr:WaitForChild("Board").Value = script.Parent.Parent.Name -- Board value is like Board1, Board2, etc in workspace.Boards
			script.Parent.ProximityPrompt.Enabled = false
			script.Parent.Parent:WaitForChild("Values"):WaitForChild("Owner").Value = plr.Name
			script.Parent.Parent.Player.SurfaceGui.Text.Text = plr.DisplayName.."'s Board"
			script.Parent.Parent.Time.SurfaceGui.Text.Text = "Best Time: "..plr.leaderstats.BestTime.Value
			script.Parent.Parent.Played.SurfaceGui.Text.Text = "Played: "..tostring(plr.leaderstats.Plays.Value)
			script.Parent.Parent.Raised.SurfaceGui.Text.Text = "Raised: "..tostring(plr.Values.Raised.Value)
			script.Parent.Parent.Donated.SurfaceGui.Text.Text = "Donated: "..tostring(plr.Values.Donated.Value)
			script.Parent.Parent.Screen.BrickColor = BrickColor.new("Cyan")
			script.Parent.Parent.Timer.SurfaceGui.Text.Text = "Click the Start button to play!"
		end
	end
end)

DonationButton Script

local Market = game:GetService("MarketplaceService")
local HTTPService = game:GetService("HttpService")

local function CloneAssets(BoothName, Contents) -- BoothName is Board1, Board2, etc. from "plr.Board.Value"
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		for _, Asset in pairs(Contents) do
			local data = Market:GetProductInfo(Asset, Enum.InfoType.Asset)
			if data and data.IsForSale then
				local Gui = script.Template:Clone()
				Gui.Parent = game.Workspace.Boards[BoothName].DonationBoard.SurfaceGui.DonationFrame
				Gui.Name = table.find(Contents, Asset)
				Gui.PurchaseButton.Text = ""..data.PriceInRobux
				Gui.Visible = true
				Gui.ImportantValues:FindFirstChild("AssetId").Value = Asset
			end
		end
	end
	for _, Asset in ipairs(Contents) do
		local data = Market:GetProductInfo(Asset, Enum.InfoType.Asset)
		if data and data.IsForSale then
			local MainGui = script.Template:Clone()
			MainGui.Parent = game.Workspace.Boards[BoothName].DonationBoard.SurfaceGui.DonationFrame
			MainGui.Name = table.find(Contents, Asset)
			MainGui.PurchaseButton.Text = ""..data.PriceInRobux
			MainGui.Visible = true
			MainGui.ImportantValues:FindFirstChild("AssetId").Value = Asset
		end
	end
end

SuccessfulDonation(If donation is successful) script

local Market = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

Market.PromptProductPurchaseFinished:Connect(function(player, assetId, purchaseSuccess)
    if purchaseSuccess then
        -- Get the board this player owns
        local boardName = player:WaitForChild("Board").Value
        local board = game.Workspace.Boards:FindFirstChild(boardName)
        
        if board then
            -- Update raised/donated values
            local productInfo = Market:GetProductInfo(assetId, Enum.InfoType.Asset)
            local amount = productInfo.PriceInRobux
            
            player.Values.Raised.Value += amount
            board.Raised.SurfaceGui.Text.Text = "Raised: "..tostring(player.Values.Raised.Value)
        end
    end
end)

And again, I appreciate to any help!

2 Likes

The clone assest function is never called. Unless it is later down the script.

How do I call the function when the player claims the board?

I never actally made a donation script so i can really help with the contents table sorry.

Oh. Maybe another person can help

For the claiming the board you also want to check if the owner value is nil so that they can’t overwrite another board . After they successfully claim it you can use a remote event and fire to all clients the data so that they see the donation buttons. Then for the donation buttons after the user presses the button u can use a remote event to prompt the purchase.

update!
Script(run legacy is client)

local HTTPService = game:GetService("HttpService")
local Market = game:GetService("MarketplaceService")

local function getPlayerAssets(player)
	local success, response = pcall(function()
		return HTTPService:GetAsync(
			"https://inventory.roblox.com/v1/users/"..player.UserId.."/assets/collectibles?limit=100",
			true -- Enable caching
		)
	end)

	if not success then
		warn("API Failed - Using default items")
		return {12345678, 87654321} -- Your fallback items
	end

	local success, inventory = pcall(function()
		return HTTPService:JSONDecode(response)
	end)

	return inventory and inventory.data or {}
end

script.Parent.ProximityPrompt.Triggered:Connect(function(plr)
	if plr and plr.Board then
		if script.Parent and script.Parent.Parent and script.Parent.Parent:WaitForChild("Values") and script.Parent.Parent:WaitForChild("Values"):WaitForChild("Owner") then
			local assets = getPlayerAssets(plr)
			game.ReplicatedStorage.DonationButtons:FireServer(plr, script.Parent.Parent, assets)
		end
	end
end)

ServerScriptService Script

local Market = game:GetService("MarketplaceService")

local function CloneAssets(boardName, assets)
	local board = game.Workspace.Boards:FindFirstChild(boardName)
	if not board then return end

	local frame = board.DonationBoard.SurfaceGui.DonationFrame

	-- Clear existing buttons
	for _, child in ipairs(frame:GetChildren()) do
		if child:IsA("Frame") and child.Name ~= "Template" then
			child:Destroy()
		end
	end

	-- Create new buttons
	for _, assetId in ipairs(assets) do
		local success, data = pcall(function()
			return Market:GetProductInfo(assetId)
		end)

		if success and data and data.IsForSale then
			local button = script.Template:Clone()
			button.Name = "Donate_"..assetId
			button.PurchaseButton.Text = data.Name.."\n"..data.PriceInRobux
			button.Visible = true

			-- Store asset ID
			local idValue = button:FindFirstChild("AssetId") or Instance.new("IntValue")
			idValue.Name = "AssetId"
			idValue.Value = assetId
			idValue.Parent = button

			button.Parent = frame
		end
	end
end

game.ReplicatedStorage.DonationButtons.OnServerEvent:Connect(function(plr, boardName, content)
	-- Validate input types
	if typeof(boardName) ~= "string" then
		warn("Invalid board name:", boardName)
		return
	end

	-- Convert single instances to tables
	local assets = {}
	if typeof(content) == "table" then
		assets = content
	elseif content:IsA("IntValue") then
		assets = {content.Value}
	else
		warn("Invalid content type:", typeof(content))
		return
	end

	-- Get board reference safely
	local board = game.Workspace.Boards:FindFirstChild(boardName)
	if not board then
		warn("Board not found:", boardName)
		return
	end
	
	plr:WaitForChild("Board").Value = game.Workspace.Boards[plr.Board.Value]
	local board = game.Workspace.Boards[plr.Board.Value]
	board.Start.ProximityPrompt.Enabled = false
	board:WaitForChild("Values"):WaitForChild("Owner").Value = plr.Name
	board.Player.SurfaceGui.Text.Text = plr.DisplayName.."'s Board"
	board.Time.SurfaceGui.Text.Text = "Best Time: "..plr.leaderstats.BestTime.Value
	board.Played.SurfaceGui.Text.Text = "Played: "..tostring(plr.leaderstats.Plays.Value)
	board.Raised.SurfaceGui.Text.Text = "Raised: "..tostring(plr.Values.Raised.Value)
	board.Donated.SurfaceGui.Text.Text = "Donated: "..tostring(plr.Values.Donated.Value)
	board.Screen.BrickColor = BrickColor.new("Cyan")
	board.Timer.SurfaceGui.Text.Text = "Click the Start button to play!"
	
	CloneAssets(boardName, assets)
end)

Screenshot 2025-04-17 at 19.43.10
If you can, please help and is appreciated!