I am trying to make a currency and have another issue, my script seems to not detect when a purchase is done, and my processReceipt function runs when the game starts. Here is my script:
local function processReceipt(info)
print("smelly oompa loompa body")
local plrProductKey = info.PlayerId .. "_" .. info.PurchaseId -- Here is where my error occurs, attempt to index a nil value.
local purchased = false
local suc, errormsg = pcall(function()
purchased = purchaseHistory:GetAsync(plrProductKey)
end)
Can someone help me out with this? In-game currency is extremely difficult. I am also using datastore2 (Roblox/DataStore2.module.lua at master · Kampfkarren/Roblox · GitHub) if that helps. I tried using it originally, and tried again with the regular ROBLOX datastore with the same error.
This is because nothing is calling it,also datastore2 uses player objects to save, not keys.To call the function do, marketplaceservice.OnProductPurchase:Connect(processReceipt) or however you wanna call it.
Okay, I fixed it using PromptPurchaseFinished. Now, I get no output.
local function processReceipt(Player,asset,tPur)
if tPur then
print("smelly oompa loompa body")
local plrProductKey = Player.UserId .. "_" .. asset -- Here is where my error occurs, attempt to index a nil value.
local purchased = false
local suc, errormsg = pcall(function()
purchased = purchaseHistory:GetAsync(plrProductKey)
end)
This should be making it run. Do purchases count on studio?
Okay, the function finally runs when it should. I now have an issue with:
local function processReceipt(receiptInfo)
print("smelly oompa loompa body")
local plrProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId -- Here is where my error occurs, attempt to index a nil value.
local purchased = false
local success, errorMessage = pcall(function()
purchased = purchaseHistory:GetAsync(plrProductKey)
end)
if success and purchased then
return Enum.ProductPurchaseDecision.PurchaseGranted
else
error("[SERVER] Data Store Error! Details: " .. errorMessage) -- Server:215: attempt to concatenate a nil value
What is purchaseHistory defined as? Is the error you gave on line 3 still there? Does the error on line 215 start with "[SERVER] Data Store Error! Details: "? Keep in mind that success can be true (which means errorMessage is nil) but purchased can still be a falsey value.
The problem in short from what I see is that purchaseHistory:GetAsync(plrProductKey) is blank. There’s nothing there as we can see, therefore, it’s a falsey value. If it’s a falsey value, it does not meet the first condition in your if-statement (that success is true andpurchased is a truthy value). You’re going to need a value there in the first place if you need PurchaseGranted. From my perspective, I don’t think you’re looking to not GetAsync the purchaseHistory but rather SetAsync so something like this would work:
...
local success, errorMessage = pcall(function()
purchaseHistory:SetAsync(plrProductKey, true)
end)
if success then
return Enum.ProductPurchaseDecision.PurchaseGranted
else
...
I’m dumb, I meant to set the record of the player purchasing the item. It works completely now, except now my function (to give the player what they purchased) does not run.
local handler = productFunc[receiptInfo.ProductId]
local success, result = pcall(handler, receiptInfo, Player)
if not success or not result then
warn("[SERVER] Error occurred while processing a product purchase.")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", Player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
Below is my function to give the player their money
productFunc[617923600] = function(receipt, plr)
print("fat") -- does not output
local val = 500
local PlayerStoredData = Server.DataStoreService("Money", plr)
local CURPLRDTA = Server.PlayerData:FindFirstChild(plr.Name)
local MNEYDATA = CURPLRDTA:FindFirstChild("Money")
if MNEYDATA then
MNEYDATA.Value = MNEYDATA.Value + val
sendNumberPlayerData(plr, MNEYDATA.Value) -- a function to refresh the players gui balance
PlayerStoredData:Increment(val) -- datastore2 increment
return true
end
end
I think my pcall() is the reason that it does not work, but I am not sure.
Where is that chunk of code placed in relation to your other code? What’s Player defined as? Could you try giving a bigger piece of code so we can see how all this fits together?
sorry for the vagueness, just trying to make sure that in the future my game won’t be exploited/manipulated, but the chunk that gives the player their money that they purchased is located right above the function. Let me try to make it easier to read:
productFunc[617923600] = function(receipt, plr)
print("fat") -- does not output
local val = 500
local PlayerStoredData = Server.DataStoreService("Money", plr)
local CURPLRDTA = Server.PlayerData:FindFirstChild(plr.Name)
local MNEYDATA = CURPLRDTA:FindFirstChild("Money")
if MNEYDATA then
MNEYDATA.Value = MNEYDATA.Value + val
sendNumberPlayerData(plr, MNEYDATA.Value) -- a function to refresh the players gui balance
PlayerStoredData:Increment(val) -- datastore2 increment
return true
end
end
local purchaseHistory = game:GetService("DataStoreService"):GetDataStore("Purchased")
local function processReceipt(receiptInfo)
print("smelly oompa loompa body")
local plrProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId -- Here is where my error occurs, attempt to index a nil value.
local purchased = false
local success, errorMessage = pcall(function()
purchaseHistory:SetAsync(plrProductKey, true)
end)
if success then
return Enum.ProductPurchaseDecision.PurchaseGranted
else
error("[SERVER] Data Store Error! Details: " .. errorMessage)
end
local Player = Server.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local handler = productFunc[receiptInfo.ProductId]
local success, result = pcall(handler, receiptInfo, Player)
if not success or not result then
warn("[SERVER] Error occurred while processing a product purchase.")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", Player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local success, errorMessage = pcall(function()
purchaseHistory:GetAsync(plrProductKey, true)
end)
Here’s the issue, you’re returning something inside your function. When you return something inside a function, the code that follows is never executed. You should change the chunk that returns PurchasedGranted to this and make the SetAsync value to false before you give the item.
if not success then
error("[SERVER] Data Store Error! Details: " .. errorMessage)
end
At the very end (after giving the item), you should SetAsync the purchase to true. You should only return PurchaseGranted at the very very end of your ProcessReceipt callback function.
local function processReceipt(receiptInfo)
print("smelly oompa loompa body")
local plrProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId -- Here is where my error occurs, attempt to index a nil value.
local purchased = false
local success, errorMessage = pcall(function()
purchaseHistory:GetAsync(plrProductKey, true)
end)
if success then
return Enum.ProductPurchaseDecision.PurchaseGranted
else
error("[SERVER] Data Store Error! Details: " .. errorMessage)
end
local Player = Server.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local handler = productFunc[receiptInfo.ProductId]
purchaseHistory:SetAsync(plrProductKey, false)
local success, result = pcall(handler, receiptInfo, Player)
if not success or not result then
warn("[SERVER] Error occurred while processing a product purchase.")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", Player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local success, errorMessage = pcall(function()
purchaseHistory:SetAsync(plrProductKey, true)
end)
if not success then
error("[SERVER] Cannot save purchase data! Details: " .. errorMessage)
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
I still don’t have the handler function run, however
You haven’t fixed it, that’s still the same code as you’re returning purchase granted 9 lines in. Please re-read my answer above and follow all the steps outlined in there.
Oops, I thought you meant at the end. completely forgot about the beginning:
local purchaseHistory = game:GetService("DataStoreService"):GetDataStore("Purchased")
local function processReceipt(receiptInfo)
print("smelly oompa loompa body")
local plrProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId -- Here is where my error occurs, attempt to index a nil value.
local purchased = false
local success, errorMessage = pcall(function()
purchaseHistory:GetAsync(plrProductKey, true)
end)
if success then
purchaseHistory:SetAsync(plrProductKey, false)
else
error("[SERVER] Data Store Error! Details: " .. errorMessage)
end
local Player = Server.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local handler = productFunc[receiptInfo.ProductId]
local success, result = pcall(handler, receiptInfo, Player)
if not success or not result then
warn("[SERVER] Error occurred while processing a product purchase.")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", Player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local success, errorMessage = pcall(function()
purchaseHistory:SetAsync(plrProductKey, true)
end)
if not success then
error("[SERVER] Cannot save purchase data! Details: " .. errorMessage)
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end