UserOwnsGamePassAsync

How to check if a player owns a specific gamepass.

by pobammer

Author Avatar

This short tutorial will go over how to check if a user owns a gamepass using MarketplaceService's function UserOwnsGamePassAsync. It'll also cover using pcall for yielding functions such as this one.

Setup

To setup this, insert a ModuleScript into ReplicatedStorage. I'm going to call mine UserOwnsGamePassAsync, since that's what the returning function is named. Once you've done that, open the ModuleScript you created and type the following line.

local MarketplaceService = game:GetService("MarketplaceService")

What this does is gets the service named MarketplaceService for you. You can then use this variable anytime you need MarketplaceService. Next up, type out the function like so.

local MarketplaceService = game:GetService("MarketplaceService")

local function UserOwnsGamePassAsync(Player: Player, GamePassId: number): boolean
end

This is where we're going to be putting all the code for checking gamepass ownership. We're gonna type out the first line in the function now.

local MarketplaceService = game:GetService("MarketplaceService")

local function UserOwnsGamePassAsync(Player: Player, GamePassId: number): boolean
    local Success, Result = pcall(MarketplaceService.UserOwnsGamePassAsync, MarketplaceService, Player.UserId, GamePassId)
end

What this is doing is running the code, but it's running it so that if something goes wrong (like the gamepass doesn't exist, or if the player doesn't exist, or anything else), the script won't break entirely. It's kind of like a safety net for your code.

local MarketplaceService = game:GetService("MarketplaceService")

local function UserOwnsGamePassAsync(Player: Player, GamePassId: number): boolean
    local Success, Result = pcall(MarketplaceService.UserOwnsGamePassAsync, MarketplaceService, Player.UserId, GamePassId)
    return Success and Result
end

What this code is doing is returning the boolean of the player's ownership of the gamepass (either true or false) if the function didn't fail, but it'll return false if the program failed.

local MarketplaceService = game:GetService("MarketplaceService")

local function UserOwnsGamePassAsync(Player: Player, GamePassId: number): boolean
    local Success, Result = pcall(MarketplaceService.UserOwnsGamePassAsync, MarketplaceService, Player.UserId, GamePassId)
    return Success and Result
end

return UserOwnsGamePassAsync

And since we're using a ModuleScript, we have to return something, in this case, we're returning UserOwnsGamePassAsync.

Usage

To use the code, simply require the ModuleScript in ReplicatedStorage, and call it whenever you need it.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserOwnsGamePassAsync = require(ReplicatedStorage.UserOwnsGamePassAsync)

local function PlayerAdded(Player: Player)
    local GamePassCheck: boolean = UserOwnsGamePassAsync(Player, 1234567)
    print(GamePassCheck)
end

Players.PlayerAdded:Connect(PlayerAdded)

UserOwnsGamePassAsync, with Promises!

This section is much more complicated than the previous, but it showcases lpghatguy's Promise library. It requires an external ModuleScript for this code to work however.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Promise = require(ReplicatedStorage.Promise) -- The reason we're not requiring the module straight from the website is because
-- this code will become unusable on the client if we do. You can find the module on evaera's GitHub.

Now we're gonna create a new Promise, using the Promise.async method.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Promise = require(ReplicatedStorage.Promise)

local function UserOwnsGamePassAsync(Player, GamePassId)
    return Promise.defer(function(Resolve, Reject)
    end)
end

return UserOwnsGamePassAsync

Now, we need to implement the actual check into the code.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Promise = require(ReplicatedStorage.Promise)

local function UserOwnsGamePassAsync(Player, GamePassId)
    return Promise.defer(function(Resolve, Reject)
        local Success, Value = pcall(MarketplaceService.UserOwnsGamePassAsync, MarketplaceService, Player.UserId, GamePassId);
        (Success and Resolve or Reject)(Value)
    end)
end

return UserOwnsGamePassAsync

Yes, that semicolon is required. If you don't include it, the Lua engine won't be sure if it's another function call or the start of a new line.

Usage, with Promises!

Using this code is more verbose as well, but I still think it's a neat concept. The code is almost the same, it's just a little longer.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserOwnsGamePassAsync = require(ReplicatedStorage.UserOwnsGamePassAsync)

local function PlayerAdded(Player)
    UserOwnsGamePassAsync(Player, 1234567)
        :andThen(function(PlayerOwns)
            print(PlayerOwns)
            if PlayerOwns then
                -- Give them cool stuff!
            end
        end)
        :catch(function(Error)
            warn("UserOwnsGamePassAsync has failed! Error:", Error)
        end)
end

Players.PlayerAdded:Connect(PlayerAdded)

Pretty simple, right?