Add song developer product (Music UI)

I am making a Music UI, and I was trying to make a simple add song developer product, but for some reason I just can’t wrap my head around what to do here. Any help would be appreciated, I’ve been stuck for the past 30 minutes.

local devproduct = 1184884262
local player = game.Players.LocalPlayer
local service = game:GetService("MarketplaceService")


function getPlayerFromId(id)
	for i,v in pairs(game.Players:GetPlayers()) do
		if v.userId == id then
			return v
		end
	end
end


script.Parent.MouseButton1Click:Connect(function()
	service:PromptProductPurchase(player, 1184884262)

end)

game.MarketplaceService.ProcessReceipt = function(receiptInfo)
	local player = getPlayerFromId(receiptInfo.PlayerId)
	if player ~= nil then
		if receiptInfo.ProductId == 1184884262 then 
			local songadded = Instance.new("Sound", game.Workspace.Sounds)
			songadded.SoundId = script.Parent.Parent.id.Text
			songadded.Name = "Requested Song"
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted		
end	

1 Like

First of all, only local scripts can access the text the player put in. 2nd, you will need to do tonumber() with the text to get a number out of the text so it can get a song.

1 Like

image

I keep getting this error now, I’m sure the script is right at this point, and yes it is local.

I’m thinking the best approach would be to invoke the client for the song ID.

local remoteFunction = game:GetService('ReplicatedStorage'):WaitForChild('RemoteFunction')
game:GetService('MarketplaceService').ProcessReceipt = function(receiptInfo)
	local player = game:GetService('Players'):GetPlayerByUserId(receiptIInfo.PlayerId)
	if player then
		if receiptInfo.ProductId == 1184884262 then
            local id
			local successful, errorMessage = pcall(function()
                id = remoteFunction:InvokeClient(player)
            end)
            if successful then
                local songadded = Instance.new("Sound")
                songadded.Parent = workspace
    			songadded.Name = "Requested Song"
                songadded.SoundId = id
            else
                return Enum.ProductPurchaseDecision.NotProcessedYet
            end
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted		
end	

Then on the client,

local remoteFunction = game:GetService('ReplicatedStorage'):WaitForChild('RemoteFunction')
local lastRequestedId
button.MouseButton1Click:Connect(function()
-- sorry for weird formatting here, I can't paste an indent properly for some reason
game:GetService('MarketplaceService'):PromptProductPurchase(game:GetService('Players').LocalPlayer, 1184884262)
    lastRequestedId = tonumber(textBox.Text)
end)
remoteFunction.OnClientInvoke = function()
    return lastRequestedId
end

It means you can only do processReceipt in Normal scripts so i suggest you make a remoteEvent and add the processReceipt inside it and then call the event inside LocalScript

The prompt doesn’t come up with this, I do see what you mean though.

So would I put a local script in the remote event? Or just name it LocalScript, sorry if this is a dumb question I’m not really advanced in programming.

1 Like

Yeah, it was just some quick pseudocode, probably won’t work 100% but it’s just to give you an idea.

1 Like

Yesssss Wish u da best of luck <3

1 Like

Here man, I wrote you something that I hope helps you fix it.

This is the server script, make sure it’s in ServerScriptService.

-- Script in ServerScriptService

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

local RemoteEvent = Instance.new("RemoteEvent")
RemoteEvent.Name = "RequestSong"
RemoteEvent.Parent = ReplicatedStorage
RemoteEvent.OnServerEvent:Connect(function(LocalPlayer)
	MarketplaceService:PromptProductPurchase(LocalPlayer, 1184884262)
end)

local RemoteFunction = Instance.new("RemoteFunction")
RemoteFunction.Name = "RequestPlayerSongId"
RemoteFunction.Parent = ReplicatedStorage

function MarketplaceService.ProcessReceipt(ReceiptObject)
	local UserId = ReceiptObject.PlayerId
	local LocalPlayer = Players:GetPlayerByUserId(UserId)

	if LocalPlayer then
		local SoundId = RemoteFunction:InvokeClient(LocalPlayer)
		if rawequal(ReceiptObject.ProductId, 1184884262) then
			local Sound = Instance.new("Sound")
			Sound.Name = "Requested Song"
			Sound.Volume = 0.5
			Sound.Looped = false
			Sound.SoundId = "rbxassetid://" .. RemoteFunction:InvokeClient(LocalPlayer)
		end
	end

	return Enum.ProductPurchaseDecision.PurchaseGranted
end

This next one is the LocalScript, you can put this one where you had your original script.

-- LocalScript

local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GuiButton = script:FindFirstAncestorWhichIsA("GuiButton")

local RemoteEvent = ReplicatedStorage:WaitForChild("RequestSong")
local RemoteFunction = ReplicatedStorage:WaitForChild("RequestPlayerSongId")
RemoteFunction.OnClientInvoke = function()
	return GuiButton.Parent.Parent["id"].Text
end

GuiButton.MouseButton1Click:Connect(function(UDimLocation)
	RemoteEvent:FireServer()
end)

If you encounter issues please let me know.

1 Like

Ensure you wrap your invocation into a pcall to handle any errors (such as the player leaving mid-invoke).

It’s on them if they leave the server, it doesn’t have much an impact on whether they leave or not.
If the pcall is considered, an unsuccessful pcall can be used to return a non-processed Enum.

It does matter and it does have an impact, it’s going to cause issues if no ProductPurchaseDecision enum is returned, such as one function being ran multiple times if no enum is returned. The first line on the documentation tells you this.

If there’s an error, it isn’t returning any ProductPurchaseDecision enum which will cause the function to be ran multiple times.

1 Like