Today, I tried making a simple one-time developer product that you buy and use, repeatable.
So, I have tried to use MarketplaceService.PromptPurchaseFinished, but it didn’t work.
Then, I realized that I had to use MarketplaceService.ProcessReceipt.
I tried using that, but no matter what I tried, it didn’t work and I couldn’t understand it, so I have been banging my head against the closest wall ever since.
So, could any of you fine people please explain this to me? I would be very thankful if you could.
It would be helpful if you posted your code so that we can look at why it’s not working. Make sure you include additional information about your code. Is it a Script or a LocalScript?
PromptPurchaseFinished does not work on developer products.
Not only that, but my code is completely rubbish. I could not even figure how to use ProcessReceipt.
game.ReplicatedStorage.Events.Prompt.OnServerEvent:Connect(function(plr, id)
mPS:PromptProductPurchase(plr, id)
--check if the player has bought the product and give the product to the player if he did.
end)
This article goes in detail about how to handle developer product purchases made and give them the product. It even provides a code example. I suggest you check it out and see if it helps you with your issue.
Note that this article is different from the other one I posted above.
You need a ProcessReceipt callback. This will handle any purchases made in your game. DataStore is used to record that a player completed a transaction and that the game does not accidentally duplicate what they bought. I added some comments to the code from the help article so that you could understand it.
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Data store for tracking purchases that were successfully processed
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
-- Table setup containing product IDs and functions for handling purchases
local productFunctions = {}
productFunctions[123123] = function(receipt, player) -- Replace 123123 to your ProductId.
-- Write the code to give them what they bought.
return true -- Keep this to show that you gave the product to the player.
end
-- You can copy and paste the code above for each product you make.
-- The core 'ProcessReceipt' callback function
local function processReceipt(receiptInfo)
-- Determine if the product was already granted by checking the data store
local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
local purchased = false
local success, errorMessage = pcall(function()
purchased = purchaseHistoryStore:GetAsync(playerProductKey)
end)
-- If purchase was recorded, the product was already granted
if success and purchased then
return Enum.ProductPurchaseDecision.PurchaseGranted
elseif not success then
error("Data store error:" .. errorMessage)
end
-- Find the player who made the purchase in the server
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- The player probably left the game
-- If they come back, the callback will be called again
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Look up handler function from 'productFunctions' table above
local handler = productFunctions[receiptInfo.ProductId]
-- Call the handler function and catch any errors
local success, result = pcall(handler, receiptInfo, player)
if not success or not result then
warn("Error occurred while processing a product purchase")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Record transaction in data store so it isn't granted again
local success, errorMessage = pcall(function()
purchaseHistoryStore:SetAsync(playerProductKey, true)
end)
if not success then
error("Cannot save purchase data: " .. errorMessage)
end
-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt