Hi, I was using a developer product script that I’ve used before in a different game of mine, just with new IDs. It was working just fine until a day or two ago, and we didn’t change any code whatsoever. My client even tested the product in normal Roblox Player by setting the price to zero and it still didn’t award the product. Here’s the script:
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[1130552603] = function(receipt, player)
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 50
return true
end
productFunctions[1130553264] = function(receipt, player)
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 125
return true
end
productFunctions[1130553322] = function(receipt, player)
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 275
return true
end
-- 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
print(success)
print(result)
warn("Error occurred while processing a product purchase")
print("ProductId: ", receiptInfo.ProductId)
print("Player: ", 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
And yeah, I’m pretty sure this code is from the Developer Hub, which makes it even more puzzling why it’s breaking.
When I print success and result, success returns false and result returns “attempt to call a nil value”, and this definitely did not happen before January 1.
Any clue how it broke on its own? Any errors or deprecated code somewhere? Any help would be appreciated, we’re looking to release very soon.