Dev Product Cancel and Still Works

  1. What do you want to achieve? Simple SkipStage Dev product that skips a stage/checkpoint when you purchase dev product

  2. What is the issue? Even if i hit cancel on the Dev Product prompt it still skips a stage even when i didnt buy it

  3. What solutions have you tried so far? Look on devforum but i think its a unique thing. tried PromptProductPurchaseFinished but that didnt work.

-- Reference to the TextButton and Player
local button = script.Parent -- Assuming the script is in the TextButton
local player = game.Players.LocalPlayer

-- Reference to the Stage Value in leaderstats
local leaderstats = player:WaitForChild("leaderstats")
local stage = leaderstats:WaitForChild("Stage")

-- Access the checkpoints variable declared in the other script
local checkpoints = game.Workspace:WaitForChild("Checkpoints")

-- Set the maximum stage
local maxStage = 25

-- Set the Developer Product ID for stage skip
local productID = "1634282918" -- Replace with your actual Product ID

local purchaseInProgress = false

-- Function to handle stage skipping
local function skipStage()
	if purchaseInProgress then
		return -- Don't allow multiple purchases
	end

	-- Check if the player can afford the stage skip and if the stage is below the maximum
	if stage.Value < maxStage then
		purchaseInProgress = true
		local success, errorMessage = pcall(function()
			game:GetService("MarketplaceService"):PromptProductPurchase(player, productID)
		end)

		if not success then
			purchaseInProgress = false
			warn(errorMessage)
		end
	else
		warn("You have reached the maximum stage.")
	end
end

-- Function to handle the completion of the purchase prompt
local function onProductPurchaseCompleted(purchaseSuccess)
	purchaseInProgress = false

	if purchaseSuccess then
		-- Increment the stage by 1, but not beyond the maximum stage
		if stage.Value < maxStage then
			stage.Value = stage.Value + 1
			-- Teleport the player to the new stage's checkpoint
			player.Character:MoveTo(checkpoints[stage.Value].Position)
		else
			warn("You have reached the maximum stage.")
		end
	else
		-- Print an error message if the purchase fails
		warn("Purchase failed")
	end
end

-- Connect the button click event to the skipStage function
button.MouseButton1Click:Connect(skipStage)

-- Connect the purchase prompt completion event
game:GetService("MarketplaceService").PromptProductPurchaseFinished:Connect(onProductPurchaseCompleted)

Just want it to only skip a stage when I hit purchase, This script is a local script under a UI purchase button, if there is a better location and script please let me know.

2 Likes

You’re just detecting when a purchase ends. I’m not sure what the behavior of PromptProductPurchaseFinished is, but try using ProcessReceipt from MarketplaceService to detect whether or not they actually purchased the product and handle it accordingly.

Here’s a reference for use of ProcessReceipt:

Dev product have to be handled in both client and server.


Basically, all you have to do in client side (local script) is to prompt the purchase, which mean you are asking the CoreSystem to show the purchase CoreGui that is related of your product ID.

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer

local productId = 0000000  -- Change this to your developer product ID

-- Function to prompt purchase of the developer product
local function promptPurchase()
	MarketplaceService:PromptProductPurchase(player, productId)
end

Once the purchase prompt is activated, and the product CoreGui showed up, you now need to handle the product effects and check if played bought the product in a script in ServerScriptService.

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local productFunctions = {}

-- 0000000 being the product ID
productFunctions[0000000] = function(receipt, player)
	-- Do your skip stage code
end

-- 0000000 being the product ID
productFunctions[0000000] = function(receipt, player)
	-- Do your other product code
end

local function processReceipt(receiptInfo)
	local userId = receiptInfo.PlayerId
	local productId = receiptInfo.ProductId

	local player = Players:GetPlayerByUserId(userId)
	if player then
		-- Get the handler function associated with the developer product ID and attempt to run it
		local handler = productFunctions[productId]
		local success, result = pcall(handler, receiptInfo, player)
		if success then
			-- The user has received their benefits!
			-- return PurchaseGranted to confirm the transaction.
			return Enum.ProductPurchaseDecision.PurchaseGranted
		else
			warn("Failed to process receipt:", receiptInfo, result)
		end
	end

	-- the user's benefits couldn't be awarded.
	-- return NotProcessedYet to try again next time the user joins.
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt

Crygen’s response is more in depth and noticed that you were doing this all on the client. What they said is right: should fix your issue.

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