How to actually tell when a prompt has finished

I’m trying to find a way to actually tell when a prompt has finished being on screen.


if self.Instance:GetAttribute("Robux") then -- Robux purchase
        print("Next", self.Tycoon.LastFailedPurchase)
        if self.Tycoon.LastFailedPurchase then return end
        
        self.Tycoon.LastFailedPurchase = self.Instance
        
        Knit.GetService("StoreService").PromptPurchase:Fire(Player, self.Instance:GetAttribute("ProductId"), true)
        
        return

-- Seperate script
Knit.GetService("StoreService").ProductPurchased:Connect(function(receiptInfo)
        if not self.LastFailedPurchase then return end -- No touched button
        
        if self.LastFailedPurchase:GetAttribute("Robux") then -- Is a Robux button
            if receiptInfo.ProductId == self.LastFailedPurchase:GetAttribute("ProductId") then
                self:PublishTopic("Button", self.LastFailedPurchase:GetAttribute("Id"))
                print("Finished robux purchase")
                self.LastFailedPurchase = nil
            end
        end
    end)
    
    Knit.GetService("StoreService").ProductPurchasedFailed:Connect(function(id)
        if not self.LastFailedPurchase then return end -- No touched button
        
        if self.LastFailedPurchase:GetAttribute("Robux") then -- Is a Robux button
            if id == self.LastFailedPurchase:GetAttribute("ProductId") then                
                self.LastFailedPurchase = nil
            end
        end
    end)

Issue is, when i buy the product, it sets the LastFailedPurchase to nil, whcih allows me to touch another button and have that prompt. Issue is, the previous prompt is still on screen. So I need an efficient way to confirm the prompt has actually finished appearing screen

Have you tried using the MarketplaceService.PromptPurchaseFinished event?

local Connection

local Finished = false

Connection = MarketplaceService.PromptPurchaseFinished:Connect(function(Player)
    if Player == Players.LocalPlayer then
        Connection:Disconnect()
        Finished = true
    end
end)

repeat
    task.wait()
until Finished

(Above code is for developer products, for gamepasses use MarketplaceService.PromptGamePassPurchaseFinished)

Not sure if the prompt is being created on server or client, but you will probably need that prompt to be created client, so it can display for those who have not bought it, and be deleted on the clients that have.

As stated in the above post, check for PromptPurchaseFinshed, then hide or delete the prompt.

PromptPurchaseFinished fires when a purchase dialogue of an affiliate gear sale or other asset is closed.

The following is the event which is fired when a developer product purchase prompt is closed.

https://developer.roblox.com/en-us/api-reference/event/MarketplaceService/PromptProductPurchaseFinished

I suppose so, but PromptProductPurchaseFinished is deprecated, and PromptPurchaseFinished fires for developer products anyway.

local MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService:PromptPurchase(game.Players.PlayerAdded:Wait(), 1123111658)

MarketplaceService.PromptPurchaseFinished:Connect(function(plr, id, purchased)
	print(plr.Name .. " exited out of the purchase dialog for " .. id .. " and " .. (purchased and "purchased" or "did not purchase"))
end)

Despite this event’s deprecation, this is the only way to detect when a developer product purchase prompt is closed.

Another example of the documentation getting it wrong.

I guess the benefit of “PromptProductPurchaseFinished” is that it specifically fires for developer products only. One could always resort to checking the asset type via “:GetProductInfo()” but that’s an additional API query which can otherwise be avoided.