I need help with MarketplaceService.ProcessReceipt

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?

There is a help article on using PromptPurchaseFinished. I would recommend you check it out and see if it helps you.

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.

But, well… That’s what im stuck on :confused::

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.

I have read that. Im ashamed to admit that it seems too advanced for me though.
Or rather, for my brain to understand. Thats why I created this post.

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
12 Likes

Honestly, I think I might’ve done it.

1 Like