This callback I’m using from the Developer Wiki is not working. I’m prompting the purchase through a LocalScript in StarterGui. The purchase is prompted on the player but when purchased, nothing is printed on the server. Am I doing something wrong? And what do I need to revise?
Local Script: [Descendant of StarterGui]
local Player = game.Players.LocalPlayer
local ProductId = 1020631268
MarketplaceService:PromptProductPurchase(Player, ProductID)
Server Script: [Located in ServerScriptService]
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PurchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local ProductFunctionList = {}
ProductFunctionList[1020631268] = function(Receipt, Player)
print("ProductPurchased")
return true
end
local function ProcessReceipt(ReceiptInfo)
local PlayerProductKey = ReceiptInfo.PlayerId .. "_" .. ReceiptInfo.PurchaseId
local Purchased = false
local Success, ErrorMessage = pcall(function()
Purchased = PurchaseHistoryStore:GetAsync(PlayerProductKey)
end)
if Success and Purchased then
return Enum.ProductPurchaseDecision.PurchaseGranted
elseif not Success then
error("Data store error:" .. ErrorMessage)
end
local Player = Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local Handler = ProductFunctionList[ReceiptInfo.ProductId]
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
local Success, ErrorMessage = pcall(function()
PurchaseHistoryStore:SetAsync(PlayerProductKey, true)
end)
if not Success then
error("Cannot save purchase data: " .. ErrorMessage)
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
MarketplaceService.ProcessReceipt = ProcessReceipt
print(1)
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local PurchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local ProductFunctionList = {}
ProductFunctionList[1020631268] = function(Receipt, Player)
print("ProductPurchased")
return true
end
print(2)
local function ProcessReceipt(ReceiptInfo)
print("Receipt called")
local PlayerProductKey = ReceiptInfo.PlayerId .. "_" .. ReceiptInfo.PurchaseId
local Purchased = false
local Success, ErrorMessage = pcall(function()
Purchased = PurchaseHistoryStore:GetAsync(PlayerProductKey)
end)
if Success and Purchased then
return Enum.ProductPurchaseDecision.PurchaseGranted
elseif not Success then
error("Data store error:" .. ErrorMessage)
end
local Player = Players:GetPlayerByUserId(ReceiptInfo.PlayerId)
if not Player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local Handler = ProductFunctionList[ReceiptInfo.ProductId]
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
local Success, ErrorMessage = pcall(function()
PurchaseHistoryStore:SetAsync(PlayerProductKey, true)
end)
if not Success then
error("Cannot save purchase data: " .. ErrorMessage)
end
print("receipt finished")
return Enum.ProductPurchaseDecision.PurchaseGranted
end
MarketplaceService.ProcessReceipt = ProcessReceipt
print(3)
It might be that your game settings don’t allow the DataService API, which would cause an error at this part
if Success and Purchased then
return Enum.ProductPurchaseDecision.PurchaseGranted
elseif not Success then
error("Data store error:" .. ErrorMessage)
end
You can enable the API usage in Game Settings -> Security -> Enable Studio Access
Edit: It likely won’t output an error actually, because it looks like if that api isn’t enabled the requests yields indefinetly? Weird, anyone else may test this out, but thats my result. Definitely go into game settings and try that out.
Make sure you only have one ProcessReceipt callback function in your entire game. If there are multiple the newest one will execute but the other ones will not which could be why it is not running the ProcessReceipt at all. You can use the shortcut CTRL + SHIFT + F to search all scripts in your game and just search ProcessReceipt.
Wouldn’t be that. GetPlayerByUserId returns a Player object associated with the given UserId or nil: assigning nil to a variable is valid, as is the if statement which is meant to return NotProcessedYet if the Player variable is nil (player with the given UserId is not in the current server).
Code looks fine to me otherwise so not particularly sure where this code is dropping off at. It’s something in the ProcessReceipt function itself that’s not allowing the code to pass through and I’m sure it’s one of the pcalls that’s doing this. Would help if OP debugged more to see what pieces of the ProcessReceipt function are getting reached.
haha yeah u right. What I meant was that the variables ‘Players’ is never set in code. So it’d be nil, and attempting to access the method of a nil value would result in that error.
You would have to use game.Players or game:GetService("Players") to define ‘Players’, which is the only fault I can find.
And this might just be something clipped off from copying to devforums, but I definitely agree code looks fine otherwise. If this isn’t the issue, then error reports or more debugging would be real helpfull in finding the trickery!
Hmm, interesting. Well here’s a quick method of debugging, and should help locate the problem.
First set up a break point at the start of your process receipt function, because its where the problem area is most likely to be. This will pause the code at that point and allow you to go line by line to see whats happening.
Next click play, and either prompt the product through store or with the line: game:GetService("MarketplaceService"):PromptProductPurchase(game.Players:GetChildren()[1], 1020631268)
Buy product, and then the code should appear with an arrow at which line you’re at. Next follow through line by line with ‘Step Into’ at the top.
You can visualize which lines of code run. Pay special attention to what code blocks you enter and where the code terminates or errors. So if you enter the line: error("Data store error:" .. ErrorMessage)
that means the datastore request a few lines before it failed. You can then take out the breakpoint, and run it again without to see if there is an error which tells you why.
And print statement debugging is more or less a shorthand of this. But let me know if you have questions on anything.