Roblox ProcessReceipt wiki question

I’m not a bum, I promise.

Shouldnt the if success and purchased thing, not be an else statement, but an elseif not success then?

Otherwise it’s requiring information that doesnt exist yet. You havent set the purchasehistorystore, therefore how can you expect a true value to come out of it?

I made this change in my own code because it wasn’t getting passed this point and everything now works smoothly, just wanna make sure I won’t have issues.

Here’s a direct link to what i’m referencing: https://developer.roblox.com/en-us/api-reference/callback/MarketplaceService/ProcessReceipt

local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
local purchased = false
local success, errorMessage = pcall(function()
	purchased = purchaseHistoryStore:GetAsync(playerProductKey)
end)
-- If purchase was recorded, the product was already granted
if success and purchased then
	return Enum.ProductPurchaseDecision.PurchaseGranted
else
		error("Data store error:" .. errorMessage)
end
1 Like

It is fine with being an else statement, because what the script is doing is checking if success and purchased are true, if they are BOTH true, then we are going to return, if one of them is false, or both are false, then we are going to print an error statement.

In regards to the purchaseHistoryStore, that is a database that you are missing the definition for, so yes there will likely be an error, but it is not an error with the way the if statement is written.

In the wiki, these variables are defined here:

local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
 
-- Data store for tracking purchases that were successfully processed
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")

If it errors there because purchased is false, there is no possible way for it to ever hit the code that sets it to true

You are correct in saying this should be an elseif not success case, because in the end, both an error and a return will stop the function from processing, causing there to be no attempt of processing the purchase, as you can see later in the sample function:

local function processReceipt(receiptInfo)

	-- Determine if the product was already granted by checking the data store

	-- If purchase was recorded, the product was already granted
	if success and purchased then
		return Enum.ProductPurchaseDecision.PurchaseGranted
	else
		error("Data store error:" .. errorMessage)
	end
	--[[ BOTH OPTIONS MAKE THE FUNCTION STOP HERE ]]


	-- Find the player who made the purchase in the server

	-- Look up handler function from 'productFunctions' table above

	-- Call the handler function and catch any errors

	-- Record transaction in data store so it isn't granted again
	local success, errorMessage = pcall(function()
		purchaseHistoryStore:SetAsync(playerProductKey, true)
	end)
	if not success then
		error("Cannot save purchase data: " .. errorMessage)
	end

	-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

Good job finding this. Since you are a New Member, I recommend you submit a topic to #platform-feedback:developer-hub while following the Post Approval procedure, outlined in Rule 15.1.

Rule quote here

So you’re saying that this would not set it to true?

local success, errorMessage = pcall(function()
	purchased = purchaseHistoryStore:GetAsync(playerProductKey)
end)

No that is simply a GetAsync, fetching whether or not it was previously set to true or if it even exists. It is set to true at the very bottom of that codeblock, after the error event, causing it to stop running, so it will always fail.

1 Like

I get what you are saying now that I have read the entire script, I was assuming that the DataStore for the specified product was set before the script actually requested it. I thought you were saying that the DataStore didn’t exist at all, my apologies.

In my game, in testing that was actually giving me some problems so I changed it to elseif like you said. It’s worked just fine with no reports from players of not receiving their purchase.

1 Like

I’m not sure I understand what you mean, could you explain with an example?

Not sure I can explain more than i already have