Product purchase doesn't work

Can you send a screenshot of the area around line 37 in “rebirthMake”

Is that what you meant?

Here try this

local player = game:GetService("Players").LocalPlayer
local ld = player:WaitForChild("leaderstats")
local damage = ld.Damage
local rebirth = ld.Rebirth
local main = script.Parent
local button = main.makeRebirth
local donateButton = main.DonateRebirth
local devproductId = 1570940043

local function donateRebirth()
	game:GetService("MarketplaceService"):PromptProductPurchase(player,devproductId)
end



donateButton.MouseButton1Click:Connect(donateRebirth)
donateButton.TouchTap:Connect(donateRebirth)

Oh wait this is a local script

DOn’t use that one second

okey, I wait, what should I do?

Client Script:

local player = game:GetService("Players").LocalPlayer
local ld = player:WaitForChild("leaderstats")
local damage = ld.Damage
local rebirth = ld.Rebirth
local main = script.Parent
local button = main.makeRebirth
local donateButton = main.DonateRebirth
local devproductId = 1570940043

local function donateRebirth()
	game:GetService("MarketplaceService"):PromptProductPurchase(player,devproductId)
end



donateButton.MouseButton1Click:Connect(donateRebirth)
donateButton.TouchTap:Connect(donateRebirth)

Server Script

local players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local debounce = false

local productFunctions = {} 
productFunctions[1570940043] = function(_receipt, player)
 -- Code here
end

MarketplaceService.ProcessReceipt = function(receiptInfo)
	if receiptInfo.ProductId == 1570940043 and debounce == false then

		debounce = true
		local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
		if player then

		return Enum.ProductPurchaseDecision.PurchaseGranted
		else
			return Enum.ProductPurchaseDecision.NotProcessedYet
		end
	end
end

Okay, I clicked the button, the offer to buy came up… but it didn’t display what I wanted, which is what I wanted:

local players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local debounce = false

local productFunctions = {} 
productFunctions[1570940043] = function(_receipt, player)
	print("Donated") -- new code
end

MarketplaceService.ProcessReceipt = function(receiptInfo)
	if receiptInfo.ProductId == 1570940043 and debounce == false then

		debounce = true
		local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
		if player then

			return Enum.ProductPurchaseDecision.PurchaseGranted
		else
			return Enum.ProductPurchaseDecision.NotProcessedYet
		end
	end
end

OH MY GOSH, I’m so sorry I made the process receipt function wrong, let me redo it. I’ll just use roblox’s devforum one. Sorry I haven’t used ProcessReciept in a long time.

Don’t worry about it, I’m the one who should apologize for not understanding how to do what I need to do)

Debounce is not set to false after the receipt is processed. That means the function will only fire once.

If the purchase is granted, give the player the Rebirth on the server.

This one will for sure work, it’s the roblox example in the devforums. (It’ll also log the data in a datastore, you can remove that if you want.)

(Remove the code in the server script and replace it with this)

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")

local productFunctions = {} 
productFunctions[1570940043] = function(_receipt, player)
	print("Donated") -- new code
end

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, result, errorMessage

	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

	-- Determine if the product was already granted by checking the data store  
	local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId

	local success, isPurchaseRecorded = pcall(function()
		return purchaseHistoryStore:UpdateAsync(playerProductKey, function(alreadyPurchased)
			if alreadyPurchased then
				return true
			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 nil
			end

			local handler = productFunctions[receiptInfo.ProductId]

			local success, result = pcall(handler, receiptInfo, player)
			-- If granting the product failed, do NOT record the purchase in datastores.
			if not success or not result then
				error("Failed to process a product purchase for ProductId: " .. tostring(receiptInfo.ProductId) .. " Player: " .. tostring(player) .. " Error: " .. tostring(result))
				return nil
			end

			-- Record the transcation in purchaseHistoryStore.
			return true
		end)
	end)

	if not success then
		error("Failed to process receipt due to data store error.")
		return Enum.ProductPurchaseDecision.NotProcessedYet
	elseif isPurchaseRecorded == nil then
		-- Didn't update the value in data store.
		return Enum.ProductPurchaseDecision.NotProcessedYet
	else	
		-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
end

-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt

Huh… It finally brought out what it needed to. Except, as you can see, there were errors:

and most likely I will remove the dataStore because I already have one, and it will probably interfere with each other

Can you tell me how best to remove it?

So yes this will work!! You just need to add code to the function like such and return true:

productFunctions[1570940043] = function(_receipt, player)
	print("Donated") -- new code
   return true
end

finally, thank you so much for your help, it was harder than i thought… and lastly if you don’t mind could you tell me the best way to remove the dataStore from the script so I don’t accidentally break anything

Btw inside this function you put the code you need to execute on purchase inside of it.
So if it is for rebirths you put the code to add a rebirth to the plr’s leaderstats inside of the product functions.
Ex:

productFunctions[1570940043] = function(_receipt, player)
  if player and player:FindFirstChild("leaderstats") then
     player.leaderstats.Rebirths.Value += 1
	print("Donated") -- new code
   return true
end

Make sense?

It’s actually not usually this hard, it’s just it’s way more complex for DeveloperProducts
it’s really easy to do with gamepasses because they can only be purchased once. So with a gamepass all you gotta do is after you prompt purchase do: game:GetService(“MarketplaceService”):UserOwnsGamepassAysnc(userid,gamepassid)

Is it just me or did something go wrong?


Typo in your code. Line 55, “Rebirths” (you added an s at the end of rebirths)
We all make small mistakes

Oh… I’m sorry for my mistake… it’s just that it’s 12:00 at night and I’m a little slow on the uptake.

1 Like