ProcessReceipt Callback Not Working

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)

Mind running this and tell me how much prints?

1 Like

I’m running this in studio. It only printed:

-- 1
-- 2
-- 3

So it looks like your ProcessReceipt is not being fired, is this a local or server script?

The ProcessReceipt part is in a server script as defined above the code block.

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.

I’m pretty sure it was already enabled but I’ll go in tomorrow after school and make sure.

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.

1 Like

I did as instructed. There is only one ProcessReceipt callback, that being the server script at the top.

I checked and “Enable Studio Access” was already enabled.

Then its probably that Players isn’t defined on line 23. Should output something like “attempt to index nil with ‘GetPlayerByUserId’”

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.

1 Like

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!

Fixed it and added the variable Players to the script and to the original post. There’s still nothing happening.

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.
Screen Shot 2020-10-03 at 2.33.36 PM

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.

Sorry for the LATE LATE LATE response. You were correct with that and I have marked it as a solution.

Turns out, an open source donation board script had set the ProcessReceipt callback so I was basically setting it again. It’s not fixed. Thank you.