Game Passes and Developer Products are the two ways to earn money from your Roblox game. Both use Robux, but they work differently. Game Passes are permanent one-time purchases—buy once, keep forever. Developer Products can be bought multiple times, so they're perfect for consumables like in-game currency or temporary boosts.

You create both in the Creator Dashboard, then use scripts to detect purchases and trigger rewards. Let's walk through the full setup.

Understanding Game Passes vs Developer Products

Game Passes are best for permanent features: VIP status, exclusive areas, permanent stat boosts, or cosmetics. Players buy them once and never lose them.

Developer Products work for anything consumable: coins, gems, power-ups that wear off, or one-time boosts. Players can buy the same product over and over.

Both appear in your game's catalog. Pricing starts at 10 Robux and goes up from there. You keep a cut of the sale after platform fees.

Create a Game Pass

Game Passes are made through the Creator Dashboard, not in Studio.

  1. Go to create.roblox.com and sign in.
  2. Click your game.
  3. On the left, select MonetizationGame Passes.
  4. Click Create a Game Pass.
  5. Pick a name, description, and icon. The icon should be a 512×512 PNG image.
  6. Set the price in Robux.
  7. Click Create. Roblox will give you the Game Pass ID once it's live.

Write your name and description clearly. New players should understand what they're buying at a glance.

Create a Developer Product

Developer Products are also created in the Creator Dashboard.

  1. Go to create.roblox.com and sign in.
  2. Click your game.
  3. On the left, select MonetizationDeveloper Products.
  4. Click Create a Developer Product.
  5. Pick a name, description, and icon (512×512 PNG).
  6. Set the price in Robux.
  7. Click Create. You'll get the Product ID after it's live.

Developer Products show in the game's store. Be clear about what players get—"50 Coins" is better than "Bundle A".

Detect Game Pass Purchases with Scripts

Once a Game Pass is created, you need a script to check if a player owns it. Use the MarketplaceService API.

Put this script in ServerScriptService:

Lua — ServerScriptService
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

-- Replace with your actual Game Pass ID
local VIP_PASS_ID = 123456789

local function onPlayerAdded(player)
	local userId = player.UserId
	
	-- Check if player owns the VIP Game Pass
	local success, owns = pcall(function()
		return MarketplaceService:UserOwnsGamePassAsync(userId, VIP_PASS_ID)
	end)
	
	if success and owns then
		print(player.Name .. " owns the VIP pass!")
		-- Reward the player here
		player:SetAttribute("HasVIPPass", true)
	else
		print(player.Name .. " does not own the VIP pass")
	end
end

-- Check all players already in the game
for _, player in pairs(Players:GetPlayers()) do
	onPlayerAdded(player)
end

-- Check new players as they join
Players.PlayerAdded:Connect(onPlayerAdded)

Replace 123456789 with your Game Pass ID from the Creator Dashboard. The pcall (protected call) catches errors if the service fails temporarily.

What this does:

  • UserOwnsGamePassAsync returns true if the player owns the pass, false if they don't.
  • The script checks all players when the server starts.
  • It also checks new players as they join.
  • You can set an attribute or trigger any reward inside the if owns then block.

Detect Developer Product Purchases with Scripts

Developer Products are trickier because they're consumable. You need to listen for the purchase event in real time.

Put this in ServerScriptService:

Lua — ServerScriptService
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

-- Replace with your actual Developer Product IDs
local COINS_PRODUCT_ID = 987654321
local COINS_AMOUNT = 50

local function onPromptPurchaseFinished(userId, productId, wasPurchased)
	if not wasPurchased then
		return -- Player cancelled
	end
	
	-- Find the player by their UserId
	local player = Players:GetPlayerByUserId(userId)
	if not player then
		return -- Player left the game
	end
	
	-- Handle the purchase
	if productId == COINS_PRODUCT_ID then
		print(player.Name .. " purchased coins!")
		-- Award coins to the player
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats then
			local coins = leaderstats:FindFirstChild("Coins")
			if coins then
				coins.Value = coins.Value + COINS_AMOUNT
			end
		end
	end
end

-- Listen for all purchase events
MarketplaceService.PromptPurchaseFinished:Connect(onPromptPurchaseFinished)

Replace 987654321 with your Developer Product ID and 50 with how many coins to award.

What this does:

  • PromptPurchaseFinished fires every time a purchase completes.
  • wasPurchased is true only if the player actually bought it (not if they cancelled).
  • The script finds the player and adds coins to their leaderstats.
  • You can have multiple products—just add more if productId == ... then blocks.
💡 Tip — Test purchases in Studio using a test place (not your real game). Enable Studio Access Tokens in your game settings, then use the MarketplaceService:PromptProductPurchase() function to simulate purchases without spending real Robux.

Prompt Players to Buy

You've detected purchases, but how do players buy? You need a GUI with a button that prompts the purchase dialog.

Put this in a LocalScript inside your purchase button:

Lua — LocalScript in Button
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local GAME_PASS_ID = 123456789

local button = script.Parent -- The button this script is in

local function onButtonClicked()
	local player = Players.LocalPlayer
	if not player then return end
	
	-- Prompt the purchase dialog
	local success, errorMsg = pcall(function()
		MarketplaceService:PromptGamePassPurchase(player, GAME_PASS_ID)
	end)
	
	if not success then
		print("Purchase prompt failed: " .. tostring(errorMsg))
	end
end

button.Activated:Connect(onButtonClicked)

For Developer Products, use PromptProductPurchase instead:

Lua — LocalScript for Developer Product
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local PRODUCT_ID = 987654321

local button = script.Parent

local function onButtonClicked()
	local player = Players.LocalPlayer
	if not player then return end
	
	MarketplaceService:PromptProductPurchase(player, PRODUCT_ID)
end

button.Activated:Connect(onButtonClicked)

When a player clicks the button, Roblox pops up a purchase dialog. If they confirm, your PromptPurchaseFinished listener fires and you award the item.

Common Mistakes to Avoid

Wrong IDs: Copy your IDs from the Creator Dashboard carefully. A single digit off breaks everything.

Client-side rewards: Never give rewards from a LocalScript. Always use a Server Script to verify the purchase, then award. Players can hack client scripts.

No error handling: Use pcall around API calls. The Marketplace service can fail temporarily, and your game should handle it gracefully.

Checking off-game players: When you receive a purchase event, always verify the player is still in the game with Players:GetPlayerByUserId(). They might have left.

Testing live: Don't test with real Robux. Use Studio's test mode or create test products first.

💡 Tip — After you create a Game Pass or Developer Product, it takes a few minutes to show up in your game's catalog. Refresh the catalog in-game to see new items.

Test in Studio

To safely test without real Robux:

  1. Open your game in Studio.
  2. In the Studio menu, go to Game SettingsSecurity.
  3. Enable Use Studio Access Tokens.
  4. Add test player accounts to your game.
  5. Use MarketplaceService:PromptProductPurchase() in the command bar to simulate a purchase.

This lets you verify your reward scripts work before going live.

Best Practices

Price fairly: Don't make essential items cost too much. Players will leave if they feel milked.

Be transparent: Clearly show what players get for their Robux. No hidden charges.

Log purchases: Keep a record of who bought what, in case of disputes or refunds.

Test edge cases: What if a player buys twice in 5 seconds? What if they leave mid-purchase? Handle these in your code.

Monitor your store: Check the Creator Dashboard regularly to see what's selling and what isn't. Adjust prices if needed.