Any better ways of using MarketplaceService?

local PendingPosition = {}
Remotes.TeleportBackRequest.OnServerEvent:Connect(function(Player, Position : Vector3)
local Character = Player.Character
local HRP = Character:WaitForChild(“HumanoidRootPart”)
MPS:PromptProductPurchase(Player, 3295854460)
PendingPosition[Player.Name] = Position
end)

MPS.PromptProductPurchaseFinished:Connect(function(UserId, ProductID, Done)
if not Done then return end
local Player = game:GetService(“Players”):GetPlayerByUserId(UserId)
if not Player then return end
if ProductID == 3295854460 then
local Position = PendingPosition[Player.Name]
if not Position then return end
local Character = Player.Character
local HRP = Character:WaitForChild(“HumanoidRootPart”)
HRP.CFrame = CFrame.new(Position)
PendingPosition[Player.Name] = nil
end
end)

Do you think it is possible to not use the PendingPosition table when receiving a purchase offer? Are there ways to make it better or not?

I would appreciate any help.

1 Like

What’s the purpose of PendingPosition?

Formatted Code ( use ``` code ``` )

local PendingPosition = {}

Remotes.TeleportBackRequest.OnServerEvent:Connect(function(Player, Position : Vector3)
	local Character = Player.Character
	local HRP = Character:WaitForChild("HumanoidRootPart")
	
	MPS:PromptProductPurchase(Player, 3295854460)
	PendingPosition[Player.Name] = Position
end)

MPS.PromptProductPurchaseFinished:Connect(function(UserId, ProductID, Done)
	if not Done then return end
	local Player = game:GetService("Players"):GetPlayerByUserId(UserId)
	if not Player then return end
	
	if ProductID == 3295854460 then
		local Position = PendingPosition[Player.Name]
		if not Position then return end
		local Character = Player.Character
		local HRP = Character:WaitForChild("HumanoidRootPart")
		HRP.CFrame = CFrame.new(Position)
		PendingPosition[Player.Name] = nil
	end
	
end)
1 Like

to store player positions if they bought the devproduct

i don’t want to use tables and the MPS.PromptProductPurchaseFinished function for checking the id of every product, and want to find any better ways of this

You don’t need to separate the events.
Can you try this?

Remotes.TeleportBackRequest.OnServerEvent:Connect(function(Player, Position : Vector3)
	local Character = Player.Character
	local HRP = Character:WaitForChild("HumanoidRootPart")
	
	MPS:PromptProductPurchase(Player, 3295854460)
	
	MPS.PromptProductPurchaseFinished:Once(function()
		HRP.CFrame = CFrame.new(Position)
	end)
end)

I’m not sure if you’ll need to check the UserId + ProductID again.
But to make sure there is no bugs, can you test it with two players?

1 Like

yes the :Once event will fire globally, so it’ll bug, i think i have to use connections and :Disconnect for this:

conn = MPS.PromptProductPurchaseFinished:Connect(function(p, assetId, wasPurchased)
    if p == player and assetId == TARGET_ID and wasPurchased then
        hrp.CFrame = CFrame.new(position)
        conn:Disconnect()
    end
end)
MPS:PromptProductPurchase(player, TARGET_ID)
1 Like

After doing a bit of research and testing, I’ve found that both of our scripts fail ( the last 2 ).

Why?
  • If 2 players tried to purchase the devProduct at the same time, one will always cancel the other.
  • And changing Once to Connect won’t work either and will even introduce a memory leak over time.

The first code may work for the time being, but there’s a chance it will fail too :(.

Why?

Here’s what the documentation says:

IMPORTANT: Do not use the PromptProductPurchaseFinished event to process purchases; instead, use the ProcessReceipt callback. The firing of PromptProductPurchaseFinished does not mean that a user has successfully purchased an item.

While you can use the PromptProductPurchaseFinished event to detect when a user closes a purchase prompt, you should not use it to process purchases because those purchases might still fail

https://create.roblox.com/docs/reference/engine/classes/MarketplaceService#PromptProductPurchaseFinished

Sorry, you’ve come here to find a solution and got more problems.

1 Like

ran into the same issue, p doesn’t return a player, it returns a userid

(unless im misunderstanding) :pray:

I think that was a typo, you can fix it pretty easily ( by changing player to player.UserId).


To OP, read this:

And there’s a code example in the docs (link) that you can use.

Sorry if I didn’t help much.

1 Like

this was an typo, also, the PromptProductPurchaseFinished can detect if the product purchased, it shared: userid, productid, done

1 Like

you can always do:
Players:GetPlayerFromUserId() --// gets a player on the server(in-game) by userid

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