As a Roblox developer, it is currently too hard to sell developer products, gamepasses, catalog assets, and so forth in game.
If this issue is addressed, it would improve my development experience because…
- I could much easier allow players immediate access to the product they just purchased.
- I could create better and fluid UI feedback such as denying the clicking of other buttons until the prompt is closed.
- I would no longer need to create a complex system where I’m waiting for multiple events and remotes to tell me if a purchase was successful or not. This overall would simplify the process making it easier to implement a marketplace in my game.
Non developer products
My request is for a new set of API that allows us to do the following:
- A method or property to check if a purchase prompt is visible on screen or not
- Events for when a purchase prompt becomes visible and is hidden
- An asyncronous method for prompting a purchase.
- Enums for different types of purchase prompt results.
In use I think it would look something like this:
local function tryPurchase(player, productType, productId)
local result
local success, err = pcall(function()
-- this method yields until the player has made a choice or the prompt is denied
result = MarketplaceService:PromptPurchaseOf(player, productType, productId)
end)
if success then
-- the prompt did not error
if result == Enum.PromptResult.Purchased then
-- the player successfully bought the item
elseif result == Enum.PromptResult.Cancelled then
-- the player did not buy the item
elseif result == Enum.PromptResult.Denied then
-- Another prompt was already visible and thus this prompt could not be shown
-- Alternatively, we could've checked if MarketplaceService:IsPurchasePromptVisible()
-- was false before requesting the current prompt
end
else
-- something happened w/ the prompt. for example, network issues.
warn(err)
end
end
-- might use these events to disallow the player to interact w/ the rest of the UI
-- until they're done with the purchase prompt
MarketplaceService.PurchasePromptVisible:Connect(function()
ScreenGui.InputSinkFrame.Visible = true
end)
MarketplaceService.PurchasePromptVisible:Connect(function()
ScreenGui.InputSinkFrame.Visible = false
end)
-- Simple buy a game pass example
ScreenGui.Button.Activated:Connect(function()
tryPurchase(player, "GamePass", 123456)
end)
Developer products
Now unfortunately due to the nature of developer products they wouldn’t be able to work like the above API. This is because the developer should ensure the “benefits” of the product are awarded to the player before the transaction is considered a success.
My suggestion here would be to scrap the current system in favour of a much simpler design.
This would involve a new method that behaves very similarily to the prompt purchase method suggested above. The only difference is that this method requires a callback function that will be run when the player attempts to purchase a developer product.
If this callback returns true then they are charged and the purchase was a success. Otherwise, the purchase failed and it does NOT try again automatically when the player joins a future game session.
It would look something like this:
local function tryDevProductPurchase(player, productId, )
local result
local success, err = pcall(function()
-- this method yields until the player has made a choice or the prompt is denied
result = MarketplaceService:PromptDevProductPurchase(player, productId, function(purchaseReceipt)
-- verify the player's still in the game
-- save that they purchased the product to a datastore
-- if all the above succeeded then...
return true
end)
end)
if success then
-- the prompt did not error
if result == Enum.PromptResult.Purchased then
-- the player successfully bought the item
elseif result == Enum.PromptResult.Cancelled then
-- the player did not buy the item
elseif result == Enum.PromptResult.Denied then
-- Another prompt was already visible and thus this prompt could not be shown
-- Alternatively, we could've checked if MarketplaceService:IsPurchasePromptVisible()
-- was false before requesting the current prompt
elseif result == Enum.PromptResult.Failed then
-- the callback did not succeed
end
else
-- something happened w/ the prompt. for example, network issues.
warn(err)
end
end
Conclusion
I understand the above API would not be implemented as is (nor would i expect it to be). I hope though that it makes clear how a system overhaul could make the process of marketplace transactions much much easier.
Thanks!