I am trying to achieve a working ProcessReceipt function, the issue with this is that it keeps throwing the error Attempt to call a boolean value
and I can’t find out why or where it does that, the script it throws that error is this function right here:
productFunctions[0] = function(Player)
local PlayerData = ServerStorage.PlayerData:FindFirstChild(Player.Name)
local ProductId = 0
local GamepassFolder = PlayerData:WaitForChild("Gamepasses",60)
if GamepassFolder then
if not GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
local Success,ErrorMessage = pcall(function()
local HasData = GamepassDatastore:GetAsync(Player.UserId)
if HasData then
GamepassDatastore:UpdateAsync(Player.UserId,function(OldValue)
local NewValue = {}
NewValue[#OldValue+1] = ProductId
return NewValue
end)
elseif not HasData then
local NewData = {ProductId}
GamepassDatastore:SetAsync(Player.UserId,NewData)
end
end)
if Success then
local NewValue = Instance.new("NumberValue",GamepassFolder)
NewValue.Name = MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name
return true
elseif not Success then
warn("Error: "..ErrorMessage)
return false
end
elseif GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
return false
end
elseif not GamepassFolder then
return false
end
end
Any help is appreciated.
1 Like
Are you sure you’re not getting any line numbers?
1 Like
This is all what prints out
If needed, this is the entire module:
local module = {}
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local GamepassDatastore = DataStoreService:GetDataStore("GamepassDatastore")
local productFunctions = {}
productFunctions[0] = function(Player)
local PlayerData = ServerStorage.PlayerData:FindFirstChild(Player.Name)
local ProductId = 0
local GamepassFolder = PlayerData:WaitForChild("Gamepasses",60)
if GamepassFolder then
if not GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
local Success,ErrorMessage = pcall(function()
local HasData = GamepassDatastore:GetAsync(Player.UserId)
if HasData then
GamepassDatastore:UpdateAsync(Player.UserId,function(OldValue)
local NewValue = {}
NewValue[#OldValue+1] = ProductId
return NewValue
end)
elseif not HasData then
local NewData = {ProductId}
GamepassDatastore:SetAsync(Player.UserId,NewData)
end
end)
if Success then
local NewValue = Instance.new("NumberValue",GamepassFolder)
NewValue.Name = MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name
return true
elseif not Success then
warn("Error: "..ErrorMessage)
return false
end
elseif GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
return false
end
elseif not GamepassFolder then
return false
end
end
function module.ProcessReceipt(ReceiptInfo)
local Player = Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
local ProductId = ReceiptInfo.ProductId
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local ProductHandler = productFunctions[ProductId](Player)
local Success,Result = pcall(ProductHandler)
if not Success or not Result then
warn("There was an error processing the product '".. MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name.."' for the player ".. Player.Name..".")
print("Result: "..Result)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
return module
And this is the way i am calling this module:
local MarketplaceService = game:GetService("MarketplaceService")
local ProductModule = require(script.ProductModule)
MarketplaceService.ProcessReceipt = ProductModule.ProcessReceipt
1 Like
This might cause a problem down the road since you are deleting OldValue’s data. Make sure you keep the data from OldValue.
As for the main problem, comment out the pcall because pcall will suppress the line number. It will be a lot more convenient if I can see the line number the problem occurs on.
2 Likes
Yeah, please comment the pcall - we can’t see the line number.
1 Like
The problem seems to be on lines 54 and 55. If I’m right, changing lines 54 and 55 to this will fix the issue.
local ProductHandler = productFunctions[ProductId]
local Success,Result = pcall(ProductHandler, Player)
Original:
local ProductHandler = productFunctions[ProductId](Player)
local Success,Result = pcall(ProductHandler)
1 Like
Comment in like putting:
-- Comment
To a pcall or something else?
1 Like
The issue is still there after changing it to that
Edit:
Turns out that after removing parts from the function that this might be one causing the problem:
productFunctions[0] = function(Player)
local PlayerData = ServerStorage.PlayerData:FindFirstChild(Player.Name)
local ProductId = 0
local GamepassFolder = PlayerData:WaitForChild("Gamepasses",60)
if GamepassFolder then
if not GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
local Success,ErrorMessage = pcall(function()
local HasData = GamepassDatastore:GetAsync(Player.UserId)
GamepassDatastore:UpdateAsync(Player.UserId,function(OldValue)
local NewValue = {}
for Index,Value in ipairs(OldValue) do
NewValue[#NewValue+1] = Value
end
NewValue[#NewValue+1] = ProductId
return NewValue
end)
end)
return true -- < This might be the one causing the problem.
end
end
end
Is the return true
removed will it print “Attempt to call a nil value” is it kept will it print already said error.
1 Like
Can you show me the full script after you add in the change I made? That was exactly the problem I tried to fix.
1 Like
I did add the player argument into the pcall but i had to keep the (Player) as the function needs the player argument
local module = {}
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local GamepassDatastore = DataStoreService:GetDataStore("GamepassDatastore")
local productFunctions = {}
-- // Own Avatar [Gamepass]
productFunctions[0] = function(Player)
local PlayerData = ServerStorage.PlayerData:FindFirstChild(Player.Name)
local ProductId = 0
local GamepassFolder = PlayerData:WaitForChild("Gamepasses",60)
if GamepassFolder then
if not GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
local Success,ErrorMessage = pcall(function()
local HasData = GamepassDatastore:GetAsync(Player.UserId)
GamepassDatastore:UpdateAsync(Player.UserId,function(OldValue)
local NewValue = {}
for Index,Value in ipairs(OldValue) do
NewValue[#NewValue+1] = Value
end
NewValue[#NewValue+1] = ProductId
return NewValue
end)
end)
return true -- < This is the trouble maker
end
end
end
function module.ProcessReceipt(ReceiptInfo)
local Player = Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
local ProductId = ReceiptInfo.ProductId
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local ProductHandler = productFunctions[ProductId](Player)
local Success,Result = pcall(ProductHandler, Player)
if not Success or not Result then
warn("There was an error processing the product '".. MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name.."' for the player ".. Player.Name..".")
print("Result: "..Result)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
return module
1 Like
That’s the problem. Adding it to the pcall will take care of that automatically. Here is the flow as I am seeing it.
productFunctions
is the table of functions
productFunctions[ProductId]
is the function specific to that product
productFunctions[ProductId](Player)
calls the function with the player argument, turning the whole thing into a bool value.
Remove the player and the parentheses from line 54.
Update with a little more info. pcall calls a function in a protected environment.
pcall(functionToCall [, arg1 [, arg2 [, ...]]])
In this case, we are calling ProductHandler where arg1 is Player.
1 Like
Now it is printing “Attempt to call a nil value”
local module = {}
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local GamepassDatastore = DataStoreService:GetDataStore("GamepassDatastore")
local productFunctions = {}
-- // Own Avatar [Gamepass]
productFunctions[0] = function(Player)
local PlayerData = ServerStorage.PlayerData:FindFirstChild(Player.Name)
local ProductId = 0
local GamepassFolder = PlayerData:WaitForChild("Gamepasses",60)
if GamepassFolder then
if not GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
local Success,ErrorMessage = pcall(function()
local HasData = GamepassDatastore:GetAsync(Player.UserId)
GamepassDatastore:UpdateAsync(Player.UserId,function(OldValue)
local NewValue = {}
for Index,Value in ipairs(OldValue) do
NewValue[#NewValue+1] = Value
end
NewValue[#NewValue+1] = ProductId
return NewValue
end)
end)
if Success then
local NewValue = Instance.new("NumberValue",GamepassFolder)
NewValue.Name = MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name
return true
elseif not Success then
warn("Error: "..ErrorMessage)
return false
end
elseif GamepassFolder:FindFirstChild(MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name) then
return false
end
elseif not GamepassFolder then
return false
end
end
function module.ProcessReceipt(ReceiptInfo)
local Player = Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
local ProductId = ReceiptInfo.ProductId
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local ProductHandler = productFunctions[ProductId]
local Success,Result = pcall(ProductHandler,Player)
if not Success or not Result then
warn("There was an error processing the product '".. MarketplaceService:GetProductInfo(ProductId,Enum.InfoType.Product).Name.."' for the player ".. Player.Name..".")
print("Result: "..Result)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
return module
Edit:
Nevermind, i’ve forgotten to put the id back into there
2 Likes