Can you show how you’re using the function?
After processReceipt is done being defined, the function is run using this code:
Server.MarketplaceService.ProcessReceipt = processReceipt()
(Server.MarketplaceService is just a variable for MarketplaceService)
You should not be using it like that. Your callback connection method should look like this:
MarketplaceService.ProcessReceipt = processReceipt
When you put the parentheses, the function never receives the info
parameter.
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?
Server.MarketplaceService.PromptPurchaseFinished:Connect(processReceipt)
Oh sorry, You would call it with MarketplaceService.ProcessReceipt:Connect(processReceipt)
That’s incorrect. ProcessReceipt requires a callback function, it’s not an Event.
@stalecars: Please look back on the solution I posted above. That's how you should be connecting the event.
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.
Purchasehistory is a data store which I used datastoreservice:getdatastore for. No errors for that.
and no, I do not have the original error. Just the new error.
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 and purchased
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.
Okay, fixed it.
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
edit: It worked! Thank you so much