Is this finish stage developer product script ok or there is a better way?

Hello im making my first obby and i have this code for finish stage dev product

local MarketplaceService = game:GetService("MarketplaceService")
local Checkpoints = workspace:FindFirstChild("Checkpoints")

MarketplaceService.ProcessReceipt = function(ReceiptInfo)
	if ReceiptInfo.ProductId == 1187025174 then
		local Player = game.Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
		local PlayerStage = game.Players[Player.Name].leaderstats.Stage
		workspace[Player.Name].HumanoidRootPart.CFrame = Checkpoints["Checkpoint".. PlayerStage.Value + 1].TPFrame.CFrame
		return Enum.ProductPurchaseDecision.PurchaseGranted

if i need to explain this there is a folder named Checkpoints in workspace and checkpoints are named like this


Are there a better way or i need to keep this script

1 Like

why not shorten this

local PlayerStage = Player.leaderstats.Stage

You need to take extra special care to ensure that your product handling code actually grants players what they paid for. Simple handling won’t cut it and in the instance that you return PurchaseGranted without actually getting the player their items, you won’t have honoured a purchase and this could lead to issues with your community or moderation.

All articles on the Developer Hub for handling developer products, such as the dedicated Developer Products article, make sure to be meticulous about the way they check that everything ran successfully and gave the player what they paid for. I would recommend using the same boilerplate or implementing similar such meticulous checks to ensure everything actually exists.

  • Keep a record of purchase history to avoid granting duplicate purchases. Preferably also create a way to allow checking of purchases. This is optional but recommended.

  • Don’t grant purchases by default.

  • Don’t grant purchases if the player doesn’t exist in the server.

  • Stay consistent with the way you access services. Use GetService for Players.

  • Use your variables. You already define the player in the purchase so you don’t need to reindex them to check their stage and it’s especially dangerous to do what you’re currently doing to access their character model. Players have a character property that references their character which should be used instead to avoid potential name conflictions.


Hello there, I will explain another way of what I believe what you are trying to say.
Try to use MarketplaceService.PromptProductPurchaseFinished() , then fire a remote event to a server script and create your skip stage through there. If you do not understand me, continue reading.

First off create a remote event and re-create your local script (buy script):

local DeveloperProduct = 0
local MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService.PromptProductPurchaseFinished:Connect(function(PlayerUserId, PurchasedProductId, Purchased)
	if Purchased == true and PurchasedProductId == DeveloperProduct then

Secondly, re-create your server script:


    local currency = "Stage"

            players.leaderstats[currency].Value = players.leaderstats[currency].Value + 1
            local LowerTorso = players.Character.LowerTorso
            LowerTorso.CFrame = --// HERE GOES THE TELEPORT SCRIPT //--


I hope this helped in some sort of way.

1 Like

Thank you for all but i dont understand lot of things colbert said

Feel free to to ask for clarification or do some research and build your knowledge on these topics. What confuses you exactly?