Server not adding values after successful marketplace purchase

  1. What do you want to achieve?
    I want to give gold bars to player after successful purchase

  2. What is the issue?
    The function “givePlayerGoldBars” does not show any warnings while the “Error occurred while processing a product purchase” is shown at line 189 (which is under “handler” variable in “processReceipt” function). Since there are no warnings from “givePlayerGoldBars” function, I expect the value to be added. Unfortunately, it doesn’t add anything.

  3. What solutions have you tried so far?
    I only slightly edited the code from this Roblox official documentation: Developer Products – In‑Game Purchases
    I was skeptical making my own code because it might cause problems later on.


local MarketplaceService = game:GetService("MarketplaceService")

local Players = game:GetService("Players")

local DataStoreService = game:GetService("DataStoreService")

local PurchaseHistoryDataStorage = DataStoreService:GetDataStore("PurchaseHistoryDataStorage")

local ReplicatedStorage = game:GetService("ReplicatedStorage") or game:FindService("ReplicatedStorage")

local PlayersLocalData = ReplicatedStorage:WaitForChild("PlayersLocalData")

local productID_1GoldBars = 1286970561
local productID_5GoldBars = 1286971494
local productID_10GoldBars = 1286971495
local productID_25GoldBars = 1286972141

local function givePlayerGoldBars(Player, goldBarsAmount)

	local PlayerLocalData
	local PlayerUserStatsData
	local PlayerGoldBarsInstance

	local previousGoldBarValue

	if not goldBarsAmount then

		warn("No value for gold bars to be added")

		return false

	end

	if not Player then

		warn("Did not find "..Player.Name.." object")

		return false

	end

	PlayerLocalData = PlayersLocalData:FindFirstChild(Player.Name)

	if not PlayersLocalData then

		warn("Did not find "..Player.Name.." local data")

		return false

	end

	PlayerUserStatsData = PlayerUserStatsData:FindFirstChild("UserStatsData")

	if not PlayerUserStatsData then

		warn("Did not find "..Player.Name.." user stats data")

		return false

	end

	PlayerGoldBarsInstance = PlayerUserStatsData:FindFirstChild("GoldBars")

	if not PlayerGoldBarsInstance then

		warn("Did not find "..Player.Name.." gold bars instance")

		return false

	end

	previousGoldBarValue = PlayerGoldBarsInstance.Value

	if not previousGoldBarValue then

		warn("Did not find "..Player.Name.." previous gold bars value")

		return false

	end

	PlayerGoldBarsInstance.Value += goldBarsAmount

	if not ((PlayerGoldBarsInstance.Value - previousGoldBarValue) == goldBarsAmount) then

		warn("Incorrect gold bars amount added")

		PlayerGoldBarsInstance.Value = previousGoldBarValue

		return false

	else

		print("Gold bars added!")

		return true

	end


end

local productFunctions = {}
-- ProductId 123123 for a full heal
productFunctions[productID_1GoldBars] = function(receipt, Player)

	local isPurchased

	isPurchased = givePlayerGoldBars(Player, 1)

	return isPurchased

end

productFunctions[productID_5GoldBars] = function(receipt, Player)

	local isPurchased

	isPurchased = givePlayerGoldBars(Player, 5)

	return isPurchased

end

productFunctions[productID_10GoldBars] = function(receipt, Player)

	local isPurchased

	isPurchased = givePlayerGoldBars(Player, 10)

	return isPurchased

end

productFunctions[productID_25GoldBars] = function(receipt, Player)

	local isPurchased

	isPurchased = givePlayerGoldBars(Player, 25)

	return isPurchased

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, errorMessage = pcall(function()

		purchased = PurchaseHistoryDataStorage: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()

		PurchaseHistoryDataStorage: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

MarketplaceService.ProcessReceipt = processReceipt

1 Like