How can I keep this from happening?

I have a server-script which detect when a player buys cash with robux. But for some reason the ProductPurchase fires more than once per purchase the more developer products I buy. Which means… the player will get more cash than they bought with robux. Here is a video of what I mean:

Here is the server script that gives the player the cash when the player buys it with robux:

local marketPlaceService = game:GetService("MarketplaceService")
local currencyName = "Cash"

--// ID's for each developer product \\--
local oneCashID = 939720557
local tenCashID = 939721000
local oneHundredCashID = 939722221
local oneThousandCashID = 939723943
local tenThousandCashID = 939732514
local oneHundredThousandCashID = 939735055
local twoHundredThousandCashID = 939737976
local oneMilCashID = 939736450
local tenMilCashID = 939739393
-----------------------------------------

marketPlaceService.ProcessReceipt = function(receipt)
	print("Transaction!")
	local player = game.Players:GetPlayerByUserId(receipt.PlayerId)
	
	
	if not player then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	else
		if receipt.ProductId == oneCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 1
		end
		
		if receipt.ProductId == tenCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 10
		end
		
		if receipt.ProductId == oneHundredCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 100
		end
		
		if receipt.ProductId == oneThousandCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 1000
		end
		
		if receipt.ProductId == tenThousandCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 10000
		end
		
		if receipt.ProductId == oneHundredThousandCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 100000
		end
		
		if receipt.ProductId == twoHundredThousandCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 250000
		end
		
		if receipt.ProductId == oneMilCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 1000000
		end
		
		if receipt.ProductId == tenMilCashID then
			player.leaderstats[currencyName].Value = player.leaderstats[currencyName].Value + 10000000
		end
	end
end

Can someone tell me how to stop this from happening?

I would say put a debounce, but I am not sure because devproducts are meant to be purchased multiple times. If a more experienced developer could tell the best practice that would be great :slight_smile:

You need to return Enum.ProductPurchaseDecision.PurchaseGranted

1 Like

Here This thread will help you out

1 Like

This happened to me before, and I think to solve it you have to use :Disconnect() at the end or something.

function:Disconnect()

Doesn’t work with ProcessReceipt. ProcessReceipt is a callback that the developer defines (it’s akin to assigning the property of ProcessReceipt to a function) which is called by MarketplaceService internally. As ProcessReceipt is not a listener, it cannot be disconnected. Disconnect is only available to RBXScriptConnection objects.

2 Likes

Why does using this prevent the function from running more than it should?

Alright I’ll be sure to do that when I try out devproducts for the first time! :slight_smile: But i’m still not quite understanding why it stops the duplicate execution of the function.

If you don’t return a ProductPurchaseDecision enum in the callback ROBLOX assumes that something went wrong and tries again.

I see! So what’s actually going on in the OP is that the purchase never goes through and the customer gets free currency.

If we tried this same code in a live game then would some error be shown to the client?