Since there is not a lot of documentation for PolicyService, I am having a bit of trouble right now.
If I have a “loot box” type dev product, of course I can add code to the button so the player can only buy the product if ArePaidRandomItemsRestricted is false.
The issue is, if the player uses exploits to still prompt the purchase from the client, is there a way to cancel the purchase in the ProcessReceipt function?
I tried removing return Enum.ProductPurchaseDecision.PurchaseGranted but the purchase still somehow went through. And return Enum.ProductPurchaseDecision.NotYetProcessed would make the ProcessReceipt function fire again when there is a chance. I dont want to charge the player if they arent even allowed to get the rewards due to policy service.
Server code:
local mps = game:GetService("MarketplaceService")
local ps = game:GetService("PolicyService")
local lootBoxId = 0 -- the id
--// PRODUCT BOUGHT
mps.ProcessReceipt = function(info)
local plr = game.Players:GetPlayerByUserId(info.PlayerId)
--// RANDOM UNLOCK
if info.ProductId == lootBoxId then
local policy = ps:GetPolicyInfoForPlayerAsync(plr)
if policy.ArePaidRandomItemsRestricted == false then
-- add random item here
else
-- what do i do here?
end
end
--// GRANT PURCHASE
return Enum.ProductPurchaseDecision.PurchaseGranted
end
Button code:
local plr = game.Players.LocalPlayer
local ms = game:GetService("MarketplaceService")
local ps = game:GetService("PolicyService")
script.Parent.Visible = false
task.wait(2)
local info = ps:GetPolicyInfoForPlayerAsync(plr)
if info.ArePaidRandomItemsRestricted == false then
script.Parent.Visible = true
end
script.Parent.MouseButton1Click:Connect(function()
if info.ArePaidRandomItemsRestricted == false then
ms:PromptProductPurchase(plr, currentId)
else
end
end)
If an exploiter does this, there is no way for me to cancel the purchase.
Though I dont know the rules for the policy service considering exploits. Would you still get in trouble if policy service got bypassed by using an exploit? Should you just not give anything to the player in that situation, but still mark the purchase as PurchaseGranted?
Thats why this is frustrating to me. This is rather important, but Roblox has not explained it well at all. We were given almost no policy service code samples (neither in the PolicyService dev hub page, or the ProcessReceipt dev hub page, though we were given a short code sample of how to get the policies in the first place, which is not helpful in this case)
Returning ProductPurchaseDecision.NotProcessedYet would eventually stop it from retrying, but when it wants to try again at a later time (such as them rejoining the game), it’ll try again. The only real safe solution would likely be to return ProductPurchaseDecision.PurchasedGranted.
While nothing was actually rewarded to the player, Roblox currently doesn’t give you any way to actually permanently cancel the product purchase, aside from PurchasedGranted.
I don’t believe you’d ever be held responsible for something like this. As long as your game won’t offer these mechanics for users where it’s banned in their territory per policy, you should be fine. If a player willingly exploits your game to try and bypass this, I don’t believe you’re realistically expected to make sure they don’t. Of course, since Roblox hasn’t actually stated this, I couldn’t absolutely confirm/deny this as it’s just my best guess at this point.
I’d likely assume the statement above, but try to make your code block off any malicious actors regardless, just to be safe.
If an exploiter were to force this prompt themselves, thats on them. You would not be held responsible for the breach of policy because its not an intended function of the game for that user.