Remote Event Messed Up

apologies for bumping but why would you use remote events for something like this? exploiters can easily take advantage of this to cheat onto the leaderboard

edit: @p49p0 gave a good example below me of how you could handle this safely

1 Like

also @Developer4Lifee i suggest listening from the serverside. since clientside is never trustable. put this on your serverscript:

local MarketPlaceService = game:GetService("MarketPlaceService")
MarketPlaceService.PromptProductPurchaseFinished:Connect(function(plr, assetId, purchased)
	if (purchased) then
		-- identify the assetid
		local info = MarketPlaceService:GetProductInfo(assetId)
		local price = info.PriceInRobux
		player.leaderstats.Donated.Value += price
	end
end)

and change all your localscripts to

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketPlaceService = game:GetService("MarketplaceService")

local id = 1265665801

script.Parent.MouseButton1Click:Connect(function()
	MarketPlaceService:PromptProductPurchase(game:GetService("Players").LocalPlayer, id)
end)

@Inkthirsty tru tru i agree

2 Likes

Simple. One Localscript, which handles buttons. One Serverscript, which handles purchases and the rest.

Also, one Localscript. Don’t create one per button. Please.

1 Like

yeah lol I made this script from a tutorial a year ago

1 Like

If it’s AlvinBlox then I’m not surprised.

Well, you got your tips, have fun scripting.

1 Like

what do you mean by identify it? Make sure that it’s the right asset id?

1 Like

identify the (price of) asset the player bought.

what would I use to do that i’m kinda confused my bad, not to experienced with this kind of stuff

1 Like

i already wrote it below the comment. if you dont know what’s a comment, a comment in lua is a line that starts with -- or starts with --[[ and ends with ]]

oh shoot my bad I thought you were trying to get me to write something there because usually I see the comment on the same line as the piece of code that your explaining.

1 Like
local MarketPlaceService = game:GetService("MarketplaceService")
MarketPlaceService.PromptProductPurchaseFinished:Connect(function(player, assetId, purchased)
	if (purchased) then
		local info = MarketPlaceService:GetProductInfo(assetId)
		local price = info.PriceInRobux
		player.leaderstats.Donated.Value += price
	end
end)


I’ve ran into a issue here

nvm change it to

local MarketPlaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
MarketPlaceService.PromptProductPurchaseFinished:Connect(function(userId, assetId, purchased)
	if (purchased) then
		local info = MarketPlaceService:GetProductInfo(assetId)
		local price = info.PriceInRobux
		local player = Players:GetPlayerByUserId(userId)
		if (not player) then return end;
		player.leaderstats.Donated.Value += price
	end
end)

i forgor PromptProductPurchaseFinished gives userid on the first argument, my bad

1 Like

The reason why this is happening is because you aren’t checking the asset id of the product purchased which results in every purchase stacking up ur value. Also I would like to mention many of the methods here replied as solutions are inefficient and bad practice. PromptProductPurchaseFinished on the docs says you shouldn’t use it to handle dev product purchases.

another thing, this is mostly insecure do to the fact you’re firing a remote event with the amount donating. Leaving place for an exploiter to constantly fire the event and rack up more of his “donated” robux. A better way is to handle the prompt purchase on the client and do the donation handling entirely on the server(no client!)

To do this, we can simply just use ProcessReceipt, which will let us handle the donation handling entirely on the server. Also resulting in a more efficient, working, secure, and also a faster script as processreceipt happens as soon as the product is done being bought. While PromptPurchaseFinished takes around 2-3 seconds to activiate.

Updated client script(also you should stop the copy paste scripting and instead handle it thru a single script with a forloop going thru the buttons and automatically prompting the id thru an intvalue in the buttons):

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketPlaceService = game:GetService("MarketplaceService")

local id = 1265665801

script.Parent.MouseButton1Click:Connect(function()
	MarketPlaceService:PromptProductPurchase(game:GetService("Players").LocalPlayer, id)
end)

updated server:

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

local donationIds = {
	-- place the product ids of ur donation dev products here
	1265665801, -- 10 robux product id
}

MPS.ProcessReceipt = function(receiptInfo)
	local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then -- check if player left whilst purchase was going on.
		return Enum.ProductPurchaseDecision.NotProcessedYet -- now when the player returns to the game, process reciept will be called
	end
	-- proceed as player is still in game
	if table.find(donationIds, receiptInfo.PurchaseId) then
		-- the product purchased is a donation dev product, now give value
		local amountDonated = receiptInfo.CurrencySpent
		player.leaderstats.Donated.Value += amountDonated
		
		return Enum.ProductPurchaseDecision.PurchaseGranted -- now tell roblox that the purchase was successfully given.
	end
end

if you have any questions then feel free to ask :slight_smile:

@Developer4Lifee, if this solves your problem then please mark my post as the solution.

1 Like

Alright appreciate you ill test it out in the morning and I hope to give you the solution!

1 Like

Hey man it didn’t seem to work, heres my exact code incase I missed something
Server:

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

local donationIds = {
	1265665801,
	1265665829, 
	1265665853, 
	1265665881, 
	1265665924,
}
MPS.ProcessReceipt = function(receiptInfo)
	local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then 
		return Enum.ProductPurchaseDecision.NotProcessedYet 
	end
	
	if table.find(donationIds, receiptInfo.PurchaseId) then
		local amountDonated = receiptInfo.CurrencySpent
		player.leaderstats.Donated.Value += amountDonated

		return Enum.ProductPurchaseDecision.PurchaseGranted 
	end
end

Local:

local MarketPlaceService = game:GetService("MarketplaceService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local id = 1265665881

script.Parent.MouseButton1Click:Connect(function()
	MarketPlaceService:PromptProductPurchase(game:GetService("Players").LocalPlayer, id)
end)

any errors in the output that you can show me?

Are these dev products? If so you can just use the MarketplaceService.ProcessReceipt callback and omit the remote event. This method is also more secure than a remote event.

1 Like

nope none whatsoever, i tested in studio tho should i test in game?

try changing the donation id stuff in the table to strings instead of numbers.

so like

local donationIds = {
	"1265665801",
	"1265665829", 
	"1265665853", 
	"1265665881", 
	"1265665924",
}
1 Like

hmm still doesnt work and no errors in output which I find very strange, should I test in game? Also should I keep as Strings?