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.
- Go to create.roblox.com and sign in.
- Click your game.
- On the left, select Monetization → Game Passes.
- Click Create a Game Pass.
- Pick a name, description, and icon. The icon should be a 512×512 PNG image.
- Set the price in Robux.
- 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.
- Go to create.roblox.com and sign in.
- Click your game.
- On the left, select Monetization → Developer Products.
- Click Create a Developer Product.
- Pick a name, description, and icon (512×512 PNG).
- Set the price in Robux.
- 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:
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:
UserOwnsGamePassAsyncreturnstrueif the player owns the pass,falseif 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 thenblock.
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:
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:
PromptPurchaseFinishedfires every time a purchase completes.wasPurchasedistrueonly 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 == ... thenblocks.
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:
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:
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.
Test in Studio
To safely test without real Robux:
- Open your game in Studio.
- In the Studio menu, go to Game Settings → Security.
- Enable Use Studio Access Tokens.
- Add test player accounts to your game.
- 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.