-
What do you want to achieve?
I want to give gold bars to player after successful purchase -
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. -
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