1 time purchase per item

i want to add 1 time purchase on items but it allows many times and my script don’t work

local Name = script.Parent.Name
local Robux = script.Parent.Robux
local Imageid = script.Parent.Image
local BoolIfOwns = script.Parent.SlingShot

local DataStoreService = game:GetService("DatastoreService")
local ds = DataStoreService:GetDataStore("datatest")

print("Running Robux Purchases")

while wait() do
	if script.Parent.Parent.InsidePurchase then
	script.Parent.Title.Text = tostring(script.Parent.NamePass.Value)  --does the name first
		script.Parent.Price.Text = tostring(script.Parent.Robux.Value) 
		script.Parent.ImageLabel.Image = "http://www.roblox.com/asset/?id="..tostring(Imageid.Value)
		Robux.Value = string.gsub(Robux.Value, "^(-?%d+)(%d%d%d)", '%1,%2')
		if Robux.Value == "0" then
			Robux.Value = "Free"
		end
	end
end

game.Players.PlayerAdded:Connect(function(plr)
	local Folder = Instance.new("Folder",plr)
	Folder.Name = "Purchase"
	local BoolValue = Instance.new("BoolValue",Folder)
	BoolValue.Name = "SlingShot"

	local dataofuser = ds:GetAsync(plr.UserId)
	if dataofuser ~= nil then -- anything but nil
		print("Found data for " .. plr.Name)
		BoolValue.Value = ds[1]
	else
		print("Replacing no data with new data.")
		BoolValue = false
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	local datasave = {}
	table.insert(datasave, plr:WaitForChild("Purchase"):WaitForChild("SlingShot").Value)
	local success,response = pcall(function()
		ds:SetAsync(plr.UserId, datasave)
	end)

	if success then
		print("succesfully saved data of " .. plr.Name)
	else
		warn(response)
	end
end)


and I wanna put custom name on the item

2 Likes

anyone>??? this takes long man/:sweat_smile:

You can use gamepasses as one time purchases, you know. What are you trying to do here?

2 Likes

bro not the question like buying tools and then it disables but
image
isn’t working here picture I remade it coz I am making like roblox but ok I added boolvalue still NOT WORKING /: I wanna save it too so

Do you mean the player can own multiple copies of the tool at once, or do they have to repurchase the item each time they join the game? If it’s the former, ensure the player doesn’t already have the item before giving it to them.

1 Like

i wanne add bool value of every names of the (shop ) items and if enables they cant own

From my understanding, the code snippet only updates the pop-up that appears and manages data. Can you share the code that gives the player the item, please?


Anyway, with your method, you could check if the item is owned with something like

if item.IsOwned.Value == false then
    -- give the player the item

where IsOwned is a BoolValue inside the item.


If you haven’t already, I suggest looking at solutions related to your goal on the DevHub.

1 Like

??? what u mean about the code

To fix this issue, you will need to update your code to properly track whether a player has already purchased an item. One way to do this is to store a list of items that the player has purchased in the Datastore, and check if the item they are trying to purchase is already in that list. If it is, you can prevent the player from purchasing the item again.

local toolfolder = game:GetService("ServerStorage"):FindFirstChild("Tools")
local DataStoreService = game:GetService("DataStoreService")
local SaveData = DataStoreService:GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(Player)
	local ToolData = SaveData:GetAsync(Player.UserId)
	
	local Backpack = Player:WaitForChild("Backpack")
	local StarterGear = Player:WaitForChild("StarterGear")
	
	if ToolData ~= nil then
		for i, v in pairs(ToolData) do
			if toolfolder:FindFirstChild(v) and Backpack:FindFirstChild(v) == nil and StarterGear:FindFirstChild(v) ==nil then
				toolfolder[v]:Clone().Parent = Backpack
				toolfolder[v]:Clone().Parent = StarterGear
			end
		end
	end
	
	Player.CharacterRemoving:Connect(function(Character)
		Character:WaitForChild("Humanoid"):UnequipTools()
	end)
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local ToolTable = {}
	for i, v in pairs(Player.Backpack:GetDescendants()) do
		table.insert(ToolTable, v.Name)
	end
	if ToolTable ~= nil then
		SaveData:SetAsync(Player.UserId, ToolTable)
	end
end)

but I’m making roblox studio inside roblox and wanted to make custom gamepass with boolvalue every single place there are 1 per purchase

Sorry, I mean the code that gives the player the item when they click the “Buy” button.


toolfolder[v]:Clone().Parent = StarterGear

For the code you sent, I wouldn’t recommend cloning the tool to StarterGear since any players who join after will get the tool. Cloning it to their Backpack is sufficient.

Nevermind, I misread. :stuck_out_tongue:

1 Like
local Name = script.Parent.Name
local Robux = script.Parent.Robux
local Imageid = script.Parent.Image
local BoolIfOwns = script.Parent.SlingShot

local DataStoreService = game:GetService("DatastoreService")
local ds = DataStoreService:GetDataStore("datatest")

print("Running Robux Purchases")

while wait() do
	if script.Parent.Parent.InsidePurchase then
	script.Parent.Title.Text = tostring(script.Parent.NamePass.Value)  --does the name first
		script.Parent.Price.Text = tostring(script.Parent.Robux.Value) 
		script.Parent.ImageLabel.Image = "http://www.roblox.com/asset/?id="..tostring(Imageid.Value)
		Robux.Value = string.gsub(Robux.Value, "^(-?%d+)(%d%d%d)", '%1,%2')
		if Robux.Value == "0" then
			Robux.Value = "Free"
		end
	end
end

no worrys its just test place but i am making like roblox purchase popup but old version and coz I don’t want to make people get robux only get ingame and I wanna make 1 per purchase per fake gamepasses

site is slow dang means i dont have much times for it

--[[ the first script ]]--

-- code before...
game.Players.PlayerRemoving:Connect(function(plr)
	local datasave = {}

    -- boolean value is saved here...
	table.insert(datasave, plr:WaitForChild("Purchase"):WaitForChild("SlingShot").Value) 
	local success,response = pcall(function()
		ds:SetAsync(plr.UserId, datasave)
	end)
    -- code after...
--[[ the second script ]]--

-- code before...
if ToolData ~= nil then
	for i, v in pairs(ToolData) do -- v is a boolean value (true/false)

        -- ... but we need a string name to find the tool, which won't work with bool values
		if toolfolder:FindFirstChild(v) and Backpack:FindFirstChild(v) == nil and StarterGear:FindFirstChild(v) ==nil then
			toolfolder[v]:Clone().Parent = Backpack
			toolfolder[v]:Clone().Parent = StarterGear
		end
	end
end

-- code after...

It looks like the BoolValue value of SlingShot, which is either true or false, is saved to track purchased items (first script), but the items are looked for by name, which is a string, when loading them (second script).

It may be better to check if the player owns the item with the BoolValue, then store the name of the item to match the loading method.

-- itemValue is the BoolValue associated with the item
local itemValue = plr:WaitForChild("Purchase"):WaitForChild("SlingShot")
if itemValue.Value == true then
    table.insert(datasave, itemValue.Name)
end
-- code continues...
1 Like

i want it to use it from this
image

In that case, store the value of NamePass in datasave. Since NamePass represents a string and not a boolean, it won’t tell you if the player owns the item or not.

table.insert(datasave, NamePass.Value) 
-- or whatever the path for NamePass is

show fully??? coz what about this part

local itemValue = plr:WaitForChild("Purchase"):WaitForChild("SlingShot")

here would change? or just table insert

where

where would I put it??!??!?

Based on how I understand the code, this is what I have in mind for that section.

-- itemValue is the BoolValue associated with the item
local itemValue = plr:WaitForChild("Purchase"):WaitForChild("SlingShot")
if itemValue.Value == true then
    table.insert(datasave, NamePass.Value)
end
-- code continues...

Correct me if I’m wrong, but itemValue is a boolean value that marks whether the item is owned. It’s the same BoolValue created and added to the player’s purchase folder when they join. I’ve only stored the value as itemValue to make the code more readable, although it doesn’t make it any different from

if plr:WaitForChild("Purchase"):WaitForChild("SlingShot").Value == true then
    table.insert(datasave, NamePass.Value)
end
-- code continues...
1 Like