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.
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
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")
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-hubwhile following the Post Approval procedure, outlined in Rule 15.1.
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.
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.