Limited counter [error]

when executing I get “Nil/nil” in the code


local MarketplaceService = game:GetService("MarketplaceService")

local itemId = 13679439783

local function getLimitedQuantity(itemId)
	local info = MarketplaceService:GetProductInfo(itemId)
	return info.limitedQuantity
end

local label = script.Parent

label.Text = tostring(getLimitedQuantity(itemId)) .. "/" .. tostring(getLimitedQuantity(itemId))


local function onItemPurchased(itemId, purchaseData)
	if itemId == 13679439783 then
		local quantity = getLimitedQuantity(itemId)
		quantity = quantity - 1
		label.Text = tostring(quantity) .. "/" .. tostring(getLimitedQuantity(itemId))
	end
end



Captura de Pantalla 2023-08-14 a la(s) 5.10.47 p.m.

the idea is simple, a counter that tells you how many copies are left of a limited

any solution?

photo of how it appears to me

2 Likes

I believe you weote limitedQuantity instead of LimitedQuantity.

3 Likes

I don’t understand your solution, does it vary by using the capital “L” or the small “L”?

1 Like

I don’t know how to retrieve it but under Asset Information is ‘Remaining’, which basically is ‘the remaining number of items a limited unique item may be sold.’

local MarketplaceService = game:GetService("MarketplaceService")

local itemId = 14437519689

local function getLimitedQuantity(itemId)
	local info = MarketplaceService:GetProductInfo(itemId)
	return info.limitedQuantity
end

local label = script.Parent

label.Text = tostring(getLimitedQuantity(itemId)) .. "/" .. tostring(getLimitedQuantity(itemId))

local function onLimitedStockItemPurchased(itemId, purchaseData)
	if itemId == 14437519689 then
		local quantity = getLimitedQuantity(itemId)
		if quantity > 0 then
			quantity = quantity - 1
			label.Text = tostring(quantity) .. "/" .. tostring(getLimitedQuantity(itemId))
		else
			label.Text = "Este item está agotado" 
		end
	end
end

MarketplaceService.LimitedStockItemPurchased:Connect(onLimitedStockItemPurchased)

I seem to have made a lot of progress in the script, but this bug has been irritating me.


I already tried 4 other types of memberships, but apparently none of them work (this experience gets the limited copies of games in “in-game”).

I realized that apparently you can’t get the same data if it is an exclusive catalog acquisition and an in-game one. however I still don’t understand how to do it for in-game. AAAAAAAAAA

I hope @NyrionDev can help me with this.

Originally I tried going through MarketplaceService as you did, but I noticed it wasn’t returning the total limiteds in stock(the second argument after your "/"). If you are aware of it, however, you can hardcode it in:

local MarketplaceService = game:GetService("MarketplaceService")

local itemId = 13679439783
local total = 100000
local label = script.Parent 

local function onUpdate()
	--can error, you may want to pcall this
	local info = MarketplaceService:GetProductInfo(itemId)
	label.Text = info.Remaining.."/"..total
end

task.spawn(onUpdate)
MarketplaceService.PromptPurchaseFinished:Connect(function(plr, id, isPurchased)
	--you may not see the counter decrease by 1, due to Roblox server lag or testing in studio
	--but this is the accurate result of remainings the site will show you
	if id == itemId and isPurchased then onUpdate() end 
end)

Now if you aren’t, you will have to use the actual endpoint(which luckily for you, doesn’t require authentication) to fetch the remainings and total:

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

local itemId = 13679439783
local label = script.Parent

--Do not pass non-Roblox urls to this, it can have unpredictable behavior
local function proxyUrl(url: string, proxy: string) return url:gsub("roblox.com", proxy, 1) end

local function getLimitedHash(id: number): string
	--pcall GetProductInfo, it can fail
	return MarketplaceService:GetProductInfo(id).CollectibleItemId
end

local url = "https://apis.roblox.com/marketplace-items/v1/items/details"
local data = HttpService:JSONEncode({itemIds = {getLimitedHash(itemId)}})
url = proxyUrl(url, "roproxy.com")

local function onUpdate()
	--pcall PostAsync, it can also fail
	local response = HttpService:PostAsync(url, data)
	local info = HttpService:JSONDecode(response)[1]
	label.Text = info.unitsAvailableForConsumption.."/"..info.assetStock
end

task.spawn(onUpdate)
MarketplaceService.PromptPurchaseFinished:Connect(function(plr, id, isPurchased)
	--you may not see the counter decrease by 1, due to Roblox server lag or testing in studio
	--but this is the accurate result of remainings the site will show you
	if id == itemId and isPurchased then onUpdate() end 
end)

The second script uses the same endpoint that gives you the “Quantity Sold” information on the site. Most specifically this is the info.sales property. In general, this endpoint returns many values you can check by doing print(info).

I was able to discover the endpoint by simply going to the item page and checking the network tab using inspect element, there I could see how I had to communicate with it and the format of the expected response.

Also since this is mostly server-sided code, I think a good idea is to split it from the label.Text part and move it to the server. Then cache the first value it retrieves in ReplicatedStorage(as a string value) and then every time a player makes a purchase update said value. Then from a local script you can do the following:

local label = script.Parent 

local value = game.ReplicatedStorage.LimitedText

function onChanged(val) label.Text = val end
onChanged(value.Value)
value.Changed:Connect(onChanged)

On your server script(any of the ones shown above) the only change you have to do is replace local label = script.Parent with:

local value = Instance.new("StringValue", game.ReplicatedStorage)
value.Name = "LimitedText"

and label.Text with value.Value. Also, change its location to ServerScriptService and move the local script in your UI instead.

That way when a player makes a purchase the update will replicate to the other clients as well.

1 Like

AMAZING! This works! I cannot find anywhere else anyone has talked about how to do this.

I put your script on a billboard GUI and uploaded it to the creator hub store. If anyone else wants to use this just place the script in your world and change the item ID to the ID of your item.

Remaining Stock Sign - (roblox.com)