Whys my leaderstat value not updating?

I have a “Donated” leaderstat that would go up by the amount that the asset cost but as of right now, it goes up by nothing. Any ideas why? Heres my script:

MarketPlaceService.PromptPurchaseFinished:Connect(function(loserPlayer, itemId, was_purchased)

						if was_purchased then
							
							local productInfo = MarketPlaceService:GetProductInfo(itemId, Enum.InfoType.Product)
							local itemPrice = productInfo.PriceInRobux

							loserPlayer.leaderstats.Donated.Value += itemPrice
							local playerId = loserPlayer.UserId

						else
							return
						end
						return
					end)
					
					local function donateButtonClicked(donateButton)

						local itemId = donateButton.Value.Value
						local itemPrice = donateButton.Price.Value

						MarketPlaceService:PromptPurchase(loserPlayer, itemId, itemPrice)

						return
					end

					for i,v in pairs(loserPlayer.PlayerGui.Donation.Frame.itemsScroller:GetChildren()) do
						if not (v:IsA("TextButton") or v:IsA("ImageButton")) then continue end
						v.MouseButton1Click:Connect(function()
							donateButtonClicked(v)
						end)
					end
					
					local exitButton = loserPlayer.PlayerGui.Donation.Frame.Exit
					
					exitButton.MouseButton1Click:Connect(function() 
						loserPlayer.PlayerGui.Donation.Enabled = false
					end)
2 Likes

Do you get any errors in the output console?
If so, please send a screenshot of it.

1 Like

I don’t know how to test in studio because it requires two players, and when I do the 2 player tests, they aren’t actual players so they have no gamepasses for sale.

Just simulate it, trigger a random gamepass prompt from studio to see if it works/ where the error comes from.

1 Like

How would I do this?

hjhgjhgjgh

1 Like

When you trigger a product purchase in studio, it simulates purchasing the product. So you can test your leaderstat, etc. Like kolbxyz responded, you can use MPS to achieve this.

In this case PromptGamePassPurchase could work
If you receive errors when the product is purchased, then feel free to respond again, but display the error you get.

2 Likes

Should this code work? I just get an error popping up saying there was an error with prompting the gamepass. Theres no errors in the output.

local MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService.PromptPurchaseFinished:Connect(function(loser, itemId, was_purchased)

	if was_purchased then

		local productInfo = MarketplaceService:GetProductInfo(itemId, Enum.InfoType.Product)
		local itemPrice = productInfo.PriceInRobux

		loser.leaderstats.Donated.Value += itemPrice
		local playerId = loser.UserId

	else
		return
	end
	return
end)

game.Players.PlayerAdded:Connect(function(plr) 
	plr.CharacterAdded:Connect(function(chr)
		local ff = Instance.new("ForceField")
		ff.Parent = chr
		ff.Visible = false

		local productId = 98681915 -- Change this to your developer product ID
		
		local player = game.Players:GetPlayerFromCharacter(chr)

		-- Function to prompt purchase of the developer product
		local function promptPurchase()
			print("PROMPTED")
			MarketplaceService:PromptProductPurchase(player, productId)
		end
		
		task.wait(2)
		
		promptPurchase()
	end)
end)

Wrote this script
It isn’t necessary to get the player two times, in the same script like that when you get the player on PlayerAdded. Also it seems like the error could be that you didn’t add a developer product, but got something else instead.

local MarketplaceService = game:GetService("MarketplaceService")

game.Players.PlayerAdded:Connect(function(player) 
	player.CharacterAdded:Connect(function(chr)
		local ff = Instance.new("ForceField")
		ff.Parent = chr
		ff.Visible = false

		local productId = 1766628202 -- Developer product, not gamepass

		-- Function to prompt purchase of the developer product
		local function promptPurchase()
			print("PROMPTED")
			MarketplaceService:PromptProductPurchase(player, productId)
		end

		task.wait(2)

		promptPurchase()
	end)
end)

Result
Using my own developer product
image

2 Likes

Thank you, ok I have tested it and I get no error messages, but I have realised the issue is the “PromptPurchaseFinished” function never gets called. (I tested using print statements)

Current code:

local MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService.PromptPurchaseFinished:Connect(function(loser, itemId, was_purchased)
	
	print("Noticed")

	if was_purchased then
		
		print("Boooooom")

		local productInfo = MarketplaceService:GetProductInfo(itemId, Enum.InfoType.Product)
		local itemPrice = productInfo.PriceInRobux

		loser.leaderstats.Donated.Value += itemPrice
		local playerId = loser.UserId

	else
		print("AH")
		return
	end
	return
end)

game.Players.PlayerAdded:Connect(function(player) 
	player.CharacterAdded:Connect(function(chr)
		local ff = Instance.new("ForceField")
		ff.Parent = chr
		ff.Visible = false

		local productId = 1340784080 -- Developer product, not gamepass

		-- Function to prompt purchase of the developer product
		local function promptPurchase()
			print("PROMPTED")
			MarketplaceService:PromptProductPurchase(player, productId)
		end

		task.wait(2)

		promptPurchase()
	end)
end)

Problem is that you actually need to handle the product being purchased. I put together some code for you here to solve your problem, as I know how frustrating it is.

A few tips.
Instead of naming “player” for loser, name it player. Readability is important.
Always check documentation for your solution.

-- // SERVICES
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")

local products = {
	[1340784080] = function(receipt, player)
		-- Do something if you want to 
	end
}


local function processReceipt(receiptInfo)
	local userId = receiptInfo.PlayerId
	local productId = receiptInfo.ProductId
	
	local player = Players:GetPlayerByUserId(userId)
	if player then 
		local handler = products[productId]
		local success, problem = pcall(handler, receiptInfo, player)
		
		if success then 
			local info = MarketplaceService:GetProductInfo(productId, Enum.InfoType.Product)
			local leaderstats = player.leaderstats
			local donated = leaderstats.Donated
			donated.Value += info.PriceInRobux
		else 
			warn("Failed to process receipt ", receiptInfo, problem)
		end
	end
	
	
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

MarketplaceService.ProcessReceipt = processReceipt

game.Players.PlayerAdded:Connect(function(player) 
	player.CharacterAdded:Connect(function(character)
		local ff = Instance.new("ForceField")
		ff.Parent = character
		ff.Visible = false

		local productId = 1340784080 -- Developer product, not gamepass

		-- Function to prompt purchase of the developer product
		local function promptPurchase()
			print("PROMPTED")
			MarketplaceService:PromptProductPurchase(player, productId)
		end

		promptPurchase()
	end)
end)

Result

Handling product purchase

3 Likes

Thats amazing its working now, thank you very much. Since the players will be buying T shirts, not products in my actual script, would I need to change the script to detect that rather than a developer product? Thank you so much for your help I really appreciate it :slight_smile:

Yes, u’ll need to detect items and check their owner.

1 Like

Ive got a script that detects the items and gets the user id and all that my issue was the leaderstats updating when they purchased them.

This is the whole script:

local function FormatUserGeneratedTShirtsEndpoint(UserId, Cursor)
						Cursor = Cursor or ""
						return "https://catalog.roproxy.com/v1/search/items/details?Category=Clothing&Subcategory=ClassicTShirts&Limit=30&CreatorTargetId="..UserId.."&Cursor="..Cursor
					end
					local function TableConcat(TableA, TableB)
						local TableC = {}
						for i, v in ipairs(TableA) do
							table.insert(TableC, v)
						end
						for i, v in ipairs(TableB) do
							table.insert(TableC, v)
						end
						return TableC
					end
					local function GetUserGeneratedTShirts(UserId, Limit, Cursor)
						local TShirts = {}
						local Endpoint = FormatUserGeneratedTShirtsEndpoint(UserId, Cursor)
						local Success, Result = pcall(function()
							return Http:GetAsync(Endpoint)
						end)
						if not Success then
							warn("Unable to get t-shirts from API: "..Result)
							return TShirts
						end
						local Success2, Result2 = pcall(function()
							return Http:JSONDecode(Result)
						end)
						if not Success2 then
							warn("Unable to decode response from t-shirts API: "..Result2)
							return TShirts
						end
						for _, TShirt in ipairs(Result2.data) do
							table.insert(TShirts, TShirt.id)
						end
						if #TShirts >= Limit then
							return TShirts
						else
							Cursor = Result2.nextPageCursor
							if Cursor then
								local MoreTShirts = GetUserGeneratedTShirts(UserId, Limit, Cursor)
								return TableConcat(TShirts, MoreTShirts)
							else
								return TShirts
							end
						end
					end
					
					local userTShirts = GetUserGeneratedTShirts(winnerId, 10)
					local num = (#userTShirts)
					
					loser.PlayerGui.Donation.Frame.TextLabel.Text = "Donate to ".. winnerName
					
					local table1 = {}
					
					for i = num, 1, -1 do
						local Asset = MarketPlaceService:GetProductInfo(userTShirts[i])
						local assetPrice = Asset.PriceInRobux
						local assetId = Asset.AssetId
						
						if assetPrice == nil or assetId == nil then
							print("Failure")
						else 
							-- Create a new table for each item with the price and id
							local item = {price = assetPrice, id = assetId}

							-- Insert the item into the table
							table.insert(table1, item)
						end

						-- Create a new table for each item with the price and id
						
					end
					
					table.sort(table1, function(a, b)
						return a.price < b.price
					end)

					for i, item in ipairs(table1) do
						if item then
							local price = item.price or "default price"
							local id = item.id or "unknown"
							
							local newButton = workspace.DonateButton:Clone()
							newButton.Name = "DonateButton"..i
							local priceValue = Instance.new("IntValue", newButton)
							priceValue.Name = "Price"
							priceValue.Value = price
							newButton.Text = price .. " R$" 

							local id = Instance.new("IntValue", newButton)
							id.Value = item.id

							newButton.Parent = loser.PlayerGui.Donation.Frame.itemsScroller
							
						else
							
						end
					end
					
					MarketPlaceService.PromptPurchaseFinished:Connect(function(loser, itemId, was_purchased)

						if was_purchased then
							
							local productInfo = MarketPlaceService:GetProductInfo(itemId, Enum.InfoType.Product)
							local itemPrice = productInfo.PriceInRobux

							loser.leaderstats.Donated.Value += itemPrice
							local playerId = loser.UserId

						else
							return
						end
						return
					end)
					
					local function donateButtonClicked(donateButton)

						local itemId = donateButton.Value.Value
						local itemPrice = donateButton.Price.Value

						MarketPlaceService:PromptPurchase(loser, itemId, itemPrice)

						return
					end

					for i,v in pairs(loser.PlayerGui.Donation.Frame.itemsScroller:GetChildren()) do
						if not (v:IsA("TextButton") or v:IsA("ImageButton")) then continue end
						v.MouseButton1Click:Connect(function()
							donateButtonClicked(v)
						end)
					end

In your local function donateButtonClicked(), you’re not specifying what loser is :thinking:
Tell me if I’m wrong, but I don’t see it, to do so, you can do:

v.MouseButton1Click:Connect(function(player)
    donateButtonClicked(v, player)
end)

and for your func:

local function donateButtonClicked(donateButton, loser)

						local itemId = donateButton.Value.Value
						local itemPrice = donateButton.Price.Value

						MarketPlaceService:PromptPurchase(loser, itemId, itemPrice)

						return
					end
1 Like

Ill give that a go now thank you

1 Like

Yeah I just tested and it makes no difference, the “loser” variable is created outside of the function so it should be able to be accessed whether I add it in as a parameter or not

Edit: The purchases is prompted to the loser player, this isn’t the issue, the issue is with the detection that they have purchased the item.

Try printing to see if that says anything / is it a local script or server script?

MarketPlaceService.PromptPurchaseFinished:Connect(function(loser, itemId, was_purchased)
print(loser, itemId, was_purchased)
						if was_purchased then
							
							local productInfo = MarketPlaceService:GetProductInfo(itemId, Enum.InfoType.Product)
							local itemPrice = productInfo.PriceInRobux

							loser.leaderstats.Donated.Value += itemPrice
							local playerId = loser.UserId

						else
							return
						end
						return
					end)
1 Like

That was the issue to begin with, I can’t test because it requires two players to get to this point, and when you do a test it uses bots that don’t have t shirts for sale. Ill try get my friend to test though

You can try a 2 player test server and use that in the dev console to prompt the purchase.

1 Like