Marketplace
Overview
Creators can use the Marketplace to sell world products like in-game currency (Gold, Crystals, etc.) or items (guns, ammo, healing potions, etc.) to players.
Seller Responsibilities
Creators are responsible for ensuring proper delivery of purchased items to buyers. In cases where missing deliveries, misleading product descriptions, damage to the value of purchased items, or other issues arise, creators must take appropriate action to resolve them. Creators who fail to fulfill delivery obligations or repeatedly receive related reports may be subject to penalties, such as payout holds, world sanctions, or even account deactivation.
Learn More
World Product GuidelinesItem Type
World Product
One-time delivery of currency, items, etc.
Currency (Gold, Crystals, etc.) Items (swords, axes, healing potions, etc.) Consumables (Revives, Instant Building Passes, etc.)
Manage Products
Products are set up per world and can be configured individually.
To register and manage products, you must first publish your world. If you assign a group as the Owner group when publishing the world, you can manage products and share revenue with group members.
Features by Permission Level
World Creator (Personal World)
O
O
O
Group Owner (Group World)
O
O
O
Group Member (Group World)
O
X
X
View Product List
From the World tab on the Dashboard, click on your world. On the world's page, click the World Product tab to view your registered products.

Register Product
Click the + Create World Product button to add a new product.


Copy Product ID
Click the ... button next to each product's name, then click Copy Product ID to copy the product's ID.

Edit Product
Click the product image or name to change its image, name, or price.

If a product is edited while the purchase window is already open for a user, the transaction will be processed with the previous information (price).
Scripting for Product Sales
Since purchasing products through the Marketplace involves spending user currency, it is essential to implement strict error handling and debugging using methods like pcall. This helps maintain system stability during runtime errors or network delays, and prevents critical issues such as missing item deliveries.
Feature List
GetProductInfo(productId, productType)
Request information on a specific product
GetWorldProductsAsync()
Request information on all world products
PromptProductPurchase(player, productId)
Request purchase
PromptProductPurchaseFinished
Handle the event required when the purchase window closes
ProcessReceipt
Event for updating the receipt status to Completed after successful delivery of the purchased product
Request Information on a Specific Product (GetProductInfo)
Returns the product information corresponding to the product ID (productId) and product type (Enum.InfoType).
local MarketplaceService = game:GetService("MarketplaceService")
local function Request_GetProductInfo(productId)
local success, errorOrProductInfo = pcall(function()
return MarketplaceService:GetProductInfo(productId, Enum.InfoType.Product)
end)
if not success then
print("Error: " .. errorOrProductInfo .. " / ProductId : " .. productId)
else
local productInfo = errorOrProductInfo
print("World Product Name: " .. tostring(productInfo.Name))
print("ProductId: " .. tostring(productInfo.ProductId))
print("ProductType: " .. tostring(productInfo.ProductType))
print("PriceInBLUC: " .. tostring(productInfo.PriceInBLUC))
print("Description: " .. tostring(productInfo.Description))
print("Created: " .. productInfo.Created)
print("Updated: " .. productInfo.Updated)
-- Display on UI
end
end
Request Information on All World Products (GetWorldProductsAsync)
Returns a Pages Object containing information on all world products.
local MarketplaceService = game:GetService("MarketplaceService")
local function Request_GetWorldProductsAsync()
local success, errorOrWorldProducts = pcall(function()
return MarketplaceService:GetWorldProductsAsync()
end)
if not success then
print("Error: " .. errorOrWorldProducts)
else
local worldProducts = errorOrWorldProducts
local pageCount = 1
local dataList = {}
while true do
local currentPage = worldProducts:GetCurrentPage()
-- Exit loop if it's the last page
if worldProducts.IsFinished or currentPage == nil then
print(pageCount .. " page IsFinished : " .. tostring(worldProducts.IsFinished))
break
else
worldProducts:AdvanceToNextPageAsync()
pageCount = pageCount + 1
end
-- Each page contains up to 100 product entries
for _, productInfo in pairs(currentPage) do
local i = #dataList + 1
print("------ " .. i .. " ------")
print("World Product Name: " .. tostring(productInfo.Name))
print("ProductId: " .. tostring(productInfo.ProductId))
print("ProductType: " .. tostring(productInfo.ProductType))
print("PriceInBLUC: " .. tostring(productInfo.PriceInBLUC))
print("Description: " .. tostring(productInfo.Description))
print("Created: " .. productInfo.Created)
print("Updated: " .. productInfo.Updated)
table.insert(dataList, productInfo)
-- Display on UI
end
end
end
end
Request Purchase (PromptProductPurchase)
Request the purchase of the product corresponding to the product ID (productID). (Purchase window appears using the system UI.)
local MarketplaceService = game:GetService("MarketplaceService")
local function Request_PromptProductPurchase(player, productId)
local success, error = pcall(function()
MarketplaceService:PromptProductPurchase(player, productId)
end)
if not success then
print("Error: " .. error .. " / ProductId : " .. productId)
end
end
When the Purchase Window Closes (PromptProductPurchaseFinished)
This event is triggered when the purchase window, opened via request Purchase (PromptProductPurchase), is closed. If the purchase is successful, "true" will be sent to isPurchased; if the user cancels or the purchase fails, "false" will be sent to isPurchased.
This event should only be used to detect whether the purchase window is closed. It must never be used to process the deliver of purchased products.
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local function OnPromptPurchaseFinished(userId, productId, isPurchased)
local player = Players:GetPlayerByUserId(userId)
print(player.Name .. " / ProductID : " .. productId .. " / isPurchased : " .. tostring(isPurchased))
end
MarketplaceService.PromptProductPurchaseFinished:Connect(OnPromptPurchaseFinished)
Product Delivery on Successful Purchase (ProcessReceipt)
Trigger the event that returns undelivered receipt information from successfully purchased products.
Receipt Status
NotProcessedYet
Product Undelivered
May be triggered again depending on trigger conditions
PurchaseGranted
Product Delivered
Not triggered again
Trigger Conditions
When a world product is successfully purchased (the successful purchase popup is shown to the user),
if there are any undelivered products, those previous pending items will also be triggered together when the new purchase is made.
When the user connects (or reconnects) to the server
How to Update Delivery Status
After successfully delivering the product, return Enum.ProductPurchaseDecision.PurchaseGranted.
Important Notes
The ProcessReceipt event should be connected only once in a server-side script.
This callback can yield indefinitely and remains valid until it receives a response, as long as the server is running.
If there are multiple undelivered receipts, each one will be triggered individually, and the order of these callbacks is non-deterministic.
The callback will only be triggered when the user is present on the server.
However, the result of the callback may still be recorded on the backend even if the user is no longer on the server.
Returning PurchaseGranted from the callback does not guarantee that the backend will successfully record it. In such cases, the receipt status remains unchanged (remains undelivered).
Products in an undelivered state will have their funds held in an Escrow state.
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ProductDeliverer = {}
-----------------------------------------------------------------------------
-- You can define a function for each product ID in a table as shown below to
-- implement custom delivery logic for each product.
ProductDeliverer[Enter the product number here.] = function(player)
local success, resultOrError = pcall(function()
-- Deliver the product to the player and handle saving using DataStore
-- Tip.
-- When saving product information using DataStore
-- it's recommended to use IncrementAsync or UpdateAsync
-- to prevent network conflicts or race conditions.
-- Return "true" when the product has been successfully delivered and saved
return true
end)
if success and resultOrError then
return true
else
return false, resultOrError
end
end
-----------------------------------------------------------------------------
-- Callback for handling the receipt triggered after a successful product purchase
local function OnProcessReceipt(receiptInfo)
-- Receipt information
local success, error = pcall(function()
print("PurchaseId: " .. receiptInfo.PurchaseId)
print("UserId: " .. receiptInfo.PlayerId)
print("ProductId: " .. receiptInfo.ProductId)
print("CurrencySpent: " .. receiptInfo.CurrencySpent)
print("PurchaseDateTime: " .. receiptInfo.PurchaseDateTime)
end)
if not success then
print("Error: " .. tostring(error))
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- If the player is valid
local productId = receiptInfo.ProductId
local userId = receiptInfo.PlayerId
local player = Players:GetPlayerByUserId(userId)
if player == nil then
print("Error: player is nil")
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Trigger the product delivery function
local delivererFunc = ProductDeliverer[productId]
local success, error = delivererFunc(player)
-- If the product is successfully delivered
if success then
-- Return the status as delivered
print("Item delivery successful / ProductId : " .. productId)
return Enum.ProductPurchaseDecision.PurchaseGranted
-- If product delivery fails
else
print("Error: " .. tostring(error))
return Enum.ProductPurchaseDecision.NotProcessedYet
end
end
MarketplaceService.ProcessReceipt = OnProcessReceipt
Test Purchase
You can test product purchases and delivery in Studio's playtest environment. (Currency will not be deducted.)
Sales Stat
Coming soon.
Revenue
Share Revenue
Coming soon.
Revenue Payout
Coming soon.
Usage Examples
You can drive purchases and increase revenue by separating free and paid in-game currency, adding value to the paid currency, and offering it as a world product.
Offering higher-quality skins as world products can tap into players' desire to customize their look, which may lead to purchases.
Bundling weapons, potions, and currency into value packs can boost conversion rates by offering more value than individual purchases.
Selling consumable items like instant revives during combat as world products helps keep the gameplay smooth while promoting purchases naturally.
Long-term offerings like a season pass can increase both user retention and revenue.
Instead of focusing only on paid items, offering a reasonable selection of free content helps build user satisfaction and trust, leading to more organic purchases.
Last updated