PromptGamePassPurchase/UserOwnsGamePassAsync not working

  1. What do you want to achieve?
    My goal is to accurately tell when a player has purchased a gamepass, and be able to test within Studio.

  2. What is the issue? Include screenshots / videos if possible!

local GamepassID = 1283293039

-- Test Prompt Gamepass
game.Players.PlayerAdded:Connect(function(player)
    print(GamepassID)
    task.wait(10)
    print("PURCHASING")
	MarketplaceService:PromptGamePassPurchase(player, GamepassID)
end)

while task.wait(1) do
    local success, owns = pcall(function()
        return MarketplaceService:UserOwnsGamePassAsync(493784608, GamepassID) -- 493784608 is my user id.
    end)

    print(success, owns)
end

This bottom block returns true false every second without fail no matter whether I accept the prompt or not. I select purchase and I get a confirmation message. Regardless, this issue continues to present itself and will never accurately tell me when the user has a gamepass. Additionally, I am unsure as to whether it is UserOwnsGamePassAsync or PromptGamePassPurchase which has a problem. I think it is more likely the former since I am receiving the prompt and “purchasing” the item.

Other context:

  • I do not actually own the gamepass in my inventory. I deleted it.
  • This is in a script and is running (which is why I am getting the prompt and getting the console messages)
  • I am waiting several minutes to see if it changes and have consistently gotten the same result in multiple attempts.
  • I am running in studio playing as my user, not a test server.

I think the above code is as simple as it gets to test whether the game pass has been purchased.

This is running on the client, right? If you’re checking if the user owns a specific gamepass, you only have use MarketplaceService:UserOwnsGamePassAsync once upon joining (on the server) and then use something like this on the server to process their purchase:

MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player: Player, id: number, wasPurchased: boolean)
	if id == gamepassID and wasPurchased then
		warn(`{player.Name} purchased the gamepass`)
	end
end)

Also MarketplaceService:UserOwnsGamePassAsync has been known to cache data, meaning that it saves the response so if you send the same request again, it will yield the same answer as before.

Also the only case where MarketplaceService.PromptGamePassPurchaseFinished wouldn’t fire is when the player is actively in your game and they buy the gamepass from the experience page (which is kinda weird).

2 Likes

This is running on the server. The client is receiving the pop-up.

Two more things.

  1. I have tried only sending the UserOwnsGamePassAsync well after the user has already “bought” the gamepass and it still returns the same results
  2. If I were to use PromptGamePassPurchaseFinished, I would have to save them in an array of people who has purchased the gamepass then and have the gamepass effects activate from there?
  1. Yeah Roblox is kinda weird about that. But nevertheless I would still only suggest using it once upon joining.
  2. Yeah you would have to save it in an array if it was bought to see who owns it like:
--Server code
local gamepassEffectsEnabled = {}
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
-- check if player owns teh gamepass and if so:
    if owns then
        gamepassEffectsEnabled[player.UserId] = true
    else
        gamepassEffectsEnabled[player.UserId] = false
    end
end)

-- If player buys gamepass during the game:
MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player: Player, id: number, wasPurchased: boolean)
	if id == gamepassID and wasPurchased then
		gamepassEffectsEnabled[player.UserId] = true
	end
end)

-- Clean upon leaving:
Players.PlayerRemoving:Connect(function(player)
    task.wait(8) -- buffer time
    gamepassEffectsEnabled[player.UserId] = nil
end)

2 Likes

Seems like an odd system from how UserOwnsGamePassAsync works from the documentation but it actually works very well. I’ll keep this in mind, thank you.

P.S. I just realized from my own game that you shouldn’t have an 8 second buffer time. What if the player leaves and rejoins 5 seconds later? Then their status will be set to true/false in the table but then 3 seconds later when the buffer ends, their status will be nil, completely removing them from the table. Sorry for the inconveience but I just realized that. The reason I put the buffer is because maybe sometimes on .PlayerRemoving, you need use DataStoreService to store the data within the tables, but I guess you don’t need to do that here.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.