How to Make Sure a DevProduct Purchase Has Been Done

Hello, I am trying to make a DevProduct that gives an in game value (+1), but the script makes it give that value even without the purchase being confirmed. what happens is that the purchase screen shows up, but the value is added at the same time, so the player can just cancel the purchase and get the value… (I tried adding a video but it didn’t work…)

Here is the code I used:

MPS = game:GetService("MarketplaceService")
id = 967538409
local player = game.Players.LocalPlayer


function ButtonClicked()
	local NewTicket = script.Parent.Parent.Parent.Parent.Menu.Frame.NewTicket
	
	MPS:PromptProductPurchase(player, id)
-- RegularTicketAmount is a value stored in the player
-- The Line bellow is the one that gives that value... Does it need to be in an if/else or something?
	game.Players.LocalPlayer.Tickets.RegularTicketAmount.Value = game.Players.LocalPlayer.Tickets.RegularTicketAmount.Value + 1
	script.Parent.Parent.Parent.Enabled = false
	NewTicket.Visible = true
end

script.Parent.MouseButton1Click:Connect(ButtonClicked)

Thanks a lot.

2 Likes

You need to check if the player had actually purchased the product. You can find more information on Developers Products here.

1 Like

From what I know you are suppose to use ProcessReceipt for this kind of stuff.

2 Likes

The thing is that I don’t understand how to use ProcessReceipt and when to use PurchaseGranted…

I did some digging and I am fairly certain that you should use ProcessReceipt. People have mentioned that if a purchase never returns that it was granted in a ProcessReceipt callback, it will be refunded to the user after 3 days. Although this doesn’t seem to be wiki documented so I am only speaking on what others have said.

The general consensus seems to be you can use both if you’d like but you MUST use ProcessReceipt in some form to tell Roblox that you honored the purchase.

You make ProcessReceipt exclusively about processing the purchase, and use PromptPurchaseFinished for everything UI/Gameplay/awarding etc related.

1 Like

All the details are here: MarketplaceService | Documentation - Roblox Creator Hub

You must return PurchaseGranted, but only when the purchase has been processed by you. This system is to ensure that players get what they purchased and if your game couldn’t process it due to an error or because the purchase wasn’t supported, then the player will get their Robux back.

In the ProcessReceipt callback, you should do things like checking that the purchase hasn’t already been saved (check your Datastore for the unique PurchaseId). You should then grant whatever the player has purchased (e.g. coins). And then you should save that the purchase has been granted by storing the unique PurchaseId in your Datastore. And finally return Enum.ProductPurchaseDecision.PurchaseGranted.

If, for example, the purchase already exists in your Datastore, you can go ahead and return Enum.ProductPurchaseDecision.PurchaseGranted immediately. If, for some reason, there’s an issue with the Datastore, you should return Enum.ProductPurchaseDecision.NotProcessedYet which will cause ProcessReceipt to fire again next time the player joins the game or makes another purchase, in the hope that whatever issue prevented it from being processed before is now working.

Granting coins or other items without ProcessReceipt means you might be giving it away for free. Incorrect handling of ProcessReceipt (by returning PurchaseGranted when it hasn’t been saved yet) will essentially be scamming your users as they won’t get what they paid for. Read the documentation carefully and ask further questions if you’re unsure.

2 Likes