Developer product

Developer products are assets which have the capability of being bought more than once. With this ability, developer products are perfect for in-game currency or ammo purchases. It should also be noted that developer products, unlike game passes (which are place-specific), can be sold in any game within a universe (now known as a 'Game'), provided that the developer product was created on the universe's configuration page.

When a developer product is sold, the funds are put in escrow for three days. After that they are awarded to the developer.

Creating developer products[edit]

In order to create a developer product you must first create a place. Once you have created your place, it is easy to create products for it. Follow these steps in order to create a product for your place:

  1. Go to the configure page for your place.
  2. On the configuration page, there is a tab with the text "Developer Products"
    Developer products tab
  3. Click the button that says "Create new"
  4. On the developer product creation page, you must fill in all of the necessary boxes, and then click create.
    • If you mess up and want to change something later, don't fret! Like all assets, developer products can be edited at any time. After you've edited a developer product remember to press the update button present on the page. You are not required to press the update button for the place, however.
    • After creating your developer product, ROBLOX will assign it a unique productId. If you forget this number, simply check back on the place configuration page, where all of your developer products should be neatly listed.
  5. Once you create your product, you will have to write some code in order to make it purchasable in your place. This, however is not hard at all!

Making your developer products purchasable[edit]

Note: ROBLOX itself does not record the purchase record of developer products by users. It is the game developer's responsibility to track this, typically with Data Stores.

You can prompt a user to purchase one of your developer products with the PromptProductPurchase method of MarketplaceService.

Handling Purchase[edit]

After a purchase is made it is up to the developer to handle and record the transaction. To do this, the developer has to define the ProcessReceipt callback function. After a player has purchased an item, this function will be called repetitively until the callback returns Enum.ProductPurchaseDecision.PurchaseGranted. This function will be passed the following arguments in a table:

  • number PlayerId - The Id of the player making the purchase.
  • number PlaceIdWherePurchased - The specific place where the purchase was made.
  • string PurchaseId - A unique identifier for the purchase, should be used to prevent granting an item multiple times for one purchase.
  • number ProductId - The Id of the purchased product.
  • Enum.CurrencyType CurrencyType - The type of currency used.
  • number CurrencySpent - The amount of currency spent on the product for this purchase.

As long as the player is in the game, the ProcessReceipt function will be called every few seconds. If the player leaves, the function will stop being called, but will resume if the player rejoins the game. As soon as this function returns PurchaseGranted it will stop being called.

Example[edit]

In order to save anything that may be changed by purchasing products, Data Stores should be used. The example code below features a server-sided script and a client-sided script, and allows the client to click a button to purchase the product:

Example

Server-sided code:

Select
local MarketplaceService = Game:GetService("MarketplaceService")
 
MarketplaceService.ProcessReceipt = function(receiptInfo)
	game.Workspace.DisplayScreen.SurfaceGui.TextBox.Text = receiptInfo.PlayerId .. " just bought " .. receiptInfo.ProductId
	-- ...
	-- use DataStore to record purchase
	-- ...	
	return Enum.ProductPurchaseDecision.PurchaseGranted		
end


Client-sided code:

Select
local MarketplaceService = Game:GetService("MarketplaceService")
local buyButton = game.Workspace.BuyButton.SurfaceGui.TextButton
local productId = 13672652
 
buyButton.MouseButton1Click:connect(function()
	MarketplaceService:PromptProductPurchase(player, productId)
end)


Getting Developer Product Info[edit]

To get the product information (price, name, image) for a developer product, use MarketplaceService's GetProductInfo function, with a second argument:

local info = game:GetService("MarketplaceService"):GetProductInfo(developerProductId, Enum.InfoType.Product)

Sample Place[edit]

This sample covers the basics of purchasing a developer product in game. In the place a player can press a button which prompts them to purchase a developer product. When the purchase is made, the ProcessReceipt function will record the purchase in a data store and then display that a purchase was made on a SurfaceGui.

Developer Product Sample Place

This place is not copy locked so you are free to view and copy the code as needed.


Practice[edit]

Exercise

Instructions

Create a developer product that increases players’ ‘’’money’’’ value on the leaderboard.

Solution
Select
--LocalScript in StarterPack
-- setup local variables
local buyButton = game.Workspace.BuyButton.SurfaceGui.TextButton
local productId = 20518668
 
-- when player clicks on buy brick prompt him/her to buy a product
buyButton.MouseButton1Click:connect(function()
	game:GetService("MarketplaceService"):PromptProductPurchase(game.Players.LocalPlayer, productId)
end)
 
 
 
 
--Script in BuyButton part
-- setup local variables
local MarketplaceService = Game:GetService("MarketplaceService")
local ds = game:GetService("DataStoreService"):GetDataStore("PurchaseHistory")
local productId = 20518668
 
-- define function that will be called when purchase finished
MarketplaceService.ProcessReceipt = function(receiptInfo) 
 
	-- find the player based on the PlayerId in receiptInfo
	for i, player in ipairs(game.Players:GetChildren()) do
		if player.userId == receiptInfo.PlayerId then
 
 
			-- check which product was purchased
			if receiptInfo.ProductId == productId then
 
				-- handle purchase
				player.leaderstats.Money.Value = player.leaderstats.Money.Value + 5
			end
		end
	end	
 
	-- record the transaction in a Data Store
	local playerProductKey = "player_" .. receiptInfo.PlayerId .. "_purchase_" .. receiptInfo.ProductId
	ds:IncrementAsync(playerProductKey, 1)	
 
	-- tell ROBLOX that we have successfully handled the transaction
	return Enum.ProductPurchaseDecision.PurchaseGranted		
end


See Also[edit]