I don’t understand why my remote function keeps on returning nil? I’m trying to see if the player owns a certain dev product so that they can unbox a crate. But instead, whenever the function is called, it returns a nil instead of true or false?? Any ideas why this is happening
I tried using a print statement and it prints “TRUE” for the server script, but it prints nil, false, nil for the local script.
ServerScript
event.OnServerInvoke = function(player ,id)
warn("A")
local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService.ProcessReceipt = function(receiptInfo)
local ID = id
warn("B")
local productId = receiptInfo.ProductId
local playerId = receiptInfo.PlayerId
local player = getPlayerFromId(playerId)
if productId == ID then
warn("TRUE")
return true
else
warn("FALSE")
return nil
end
end
end
Local Script
spin.MouseButton1Down:Connect(function()
local canspin = true
if canspin then
canspin = false
local id = 985025707
warn("A")
game:GetService("MarketplaceService"):PromptProductPurchase(player, id)
local bool = game.ReplicatedStorage.Test:InvokeServer(id)
while wait(1) do
print("B")
warn(bool)
if bool == nil then
warn("False")
warn(bool)
elseif bool == "Yes" then
warn("True")
warn(bool)
break
end
canspin = true
end
end
end)
Why do you use a remotefunction for this? You need to use the MarketPlaceService.ProcessReceipt function for this and fire a RemoteEvent if someone can spin
You shouldn’t have processreceipt inside of a invoke event.
It returns nil because the invoke will not return anything as you just connected an event that isn’t called yet.
Aside from what was already suggested; you should only set ProcessReceiptonce, so don’t place it inside a RemoteEvent or RemoteFunction. This specific example is free of the bug because you then get player again using receiptInfo.PlayerId, but had you done it slightly differently you could have had players overwriting each other’s purchases.
Don’t use RemoteFunctions at all, you don’t need to cross the client-server boundary here. There are some use examples of ProcessReceipt you can get off the Developer Hub about ProcessReceipt and working with developer products.
If you want the player to see when they’ve purchased a product with immediate feedback, use PromptProductPurchaseFinished. Although it does say deprecated and the usual spiel would be that you shouldn’t be using deprecated items, this item only has a deprecation tag to warn developers from misusing it to grant purchases over ProcessReceipt.
Beyond your initial problem which can be resolved by not using RemoteFunctions at all and using the above event, you’re using ProcessReceipt wrong. You must return a ProductPurchaseDecision Enum, either PurchaseGranted for a successful purchase and to tell Roblox that you should be given the money or NotProcessedYet to queue the purchase for later, for example, in case of error.
Developer products, next, are not necessarily “ownable” assets, they are monetary assets that can be purchased several times over. You should rework your system to account for this. For instance, the server should be keeping track of how many spins a player can perform through the purchase.
Finally, please don’t use loops where unnecessary. The specific loop you’re using is bad practice and the LocalScript will yield until InvokeServer returns anyway, removing the need to do any kind of manual waiting. By making a while loop after InvokeServer, you’re causing the script to wait unnecessarily.