MarketplaceService:UserOwnsGamePassAsync() doesn't update after player buys gamepass

After an in-game purchase, MarketplaceService:UserOwnsGamePassAsync() seems to not recognize that the player has bought the gamepass in-game and the player has to reset before the function returns true.

I read that PlayerHasPass() is depreciated so I am using MarketplaceService:UserOwnsGamePassAsync() as I read from several sources that it updates the player’s gamepass ownership after it’s been bought, but it’s nor working for me. Is there anything I’m doing wrong?

local Player =  game.Players.LocalPlayer
local MarketplaceService = game:GetService("MarketplaceService")
local GamepassId = 4780308

-- Directly after an in-game purchase with MarketplaceService:PromptGamePassPurchase(Player, GamepassId)

script.Parent.MouseButton1Click:Connect(function()
	if MarketplaceService:UserOwnsGamePassAsync(Player.UserId, GamepassId) then
		print("player owns pass!")
	else
		print("player does not own pass")
	end
end)

player does not own pass

It only works after resetting the player or rejoining the game.

6 Likes

This functionality isn’t documented and I requested the documentation be fixed a while ago, it hasn’t yet unfortunately.

12 Likes

Thank you!

I just tested this out, and it’s taking a lot longer than 10 seconds to yield true. Does this have anything to do with internet speeds or server connection?

4 Likes

I am unsure. I do hope the delay gets documented, however.

4 Likes

I appreciate the advice. I suppose manually creating a local bool to help out until the player resets or leaves is an option, since players might be confused about not receiving the benefits of the gamepass right away.

2 Likes

If you want to inform the player right away, PromptGamePassPurchaseFinished might come in handy.

I used this function to change the gui the player is looking at after they purchase the gamepass, but when the player closes and re-opens the GUI, it prompts them with another gamepass prompt purchase because of the yield.

1 Like

In that case I’d store a bool and change it to true upon PromptGamePassPurchaseFinished firing, although the delay is only 10ish seconds it shouldn’t be that huge of a deal.

2 Likes

I believe a server restart is required for gamepasses. The server doesn’t seem to reload it, at least with my experiences.

1 Like

That’s no longer the case. Game passes used to cache for whole play sessions with GamePassService and its PlayerHasPass method. Both of those have been deprecated and superseded by UserOwnsGamePassAsync. This callback is different; it only caches false for 10 seconds (or rather should) if a player does not own a pass, or true for the rest of the session if they do.

That being said, @ShinyGriffin, you should also be sure to pcall anything that’s internally a web call to avoid any future troubles. This allows you to handle errors without your threads terminating due to calls throwing errors.

local success, hasPass = pcall(MarketplaceService.UserOwnsGamePass, MarketplaceService, Player.UserId, GamePassId)

-- 1:
if not success then
    -- Handle error
else
    if hasPass then
        -- Handle players with pass
    else
        -- Handle players without pass
    end
end

-- 2:
print("player", hasPass and "owns pass!" or "does not own pass")
5 Likes

If you want to have a good UX for this time, fill it with some kind of loading screen for fifteen seconds (just to make sure the cache is cleared), and then check their ownership again.

This makes the UX slightly better than them having to wait ten seconds with no feedback to get their gamepass.

2 Likes