Hi, I am having an issue in my game where Dev Products just seem to be not working. I have found that if I put the script into a new button on the gui it will work and then the original button will also work and I have tested the exact same script on another game which works completely fine.
This is the code which I know works fine as stated before. It seems to be an issue with the specific place but im not sure what could cause something like this to happen
local devProductId = 3258933939
local player= script.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent
script.Parent.MouseButton1Click:connect(function()
print(player)
game:GetService("MarketplaceService"):PromptProductPurchase(player, devProductId)
end)
local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService.ProcessReceipt = function(receiptInfo)
for i, player in ipairs(game.Players:GetChildren()) do
if player.userId == receiptInfo.PlayerId then
if receiptInfo.ProductId == devProductId then
local P = game.Players:FindFirstChild(player.Name)
P.Luck.Luck.Value += 5000
print("WIN!")
end
end
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
MarketplaceService.ProcessReceipt is a callback, not an event. You can only assign one function to handle all developer product transactions. Having multiple scripts that assign to this member of MarketplaceService will override previous callback(s), rendering the developer products they handled null.
On another note, you already have the player in your loop variable:
for i, player in ipairs(game.Players:GetChildren()) do
local P = game.Players:FindFirstChild(player.Name)
Ive tried to make it in one script using just one process receipt function and it still doesnt work
local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService.ProcessReceipt = function(receiptInfo)
for i, player in ipairs(game.Players:GetChildren()) do
if player.userId == receiptInfo.PlayerId then
if receiptInfo.ProductId == 3258928056 then
player.Luck.Luck.Value += 10
print("WIN!")
end
elseif receiptInfo.ProductId == 3258931532 then
player.Luck.Luck.Value += 100
print("WIN!")
elseif receiptInfo.ProductId == 3258933096 then
player.Luck.Luck.Value += 1000
print("WIN!")
elseif receiptInfo.ProductId == 3258935278 then
player.Luck.Luck.Value += 100000
print("WIN!")
elseif receiptInfo.ProductId == 3258934601 then
player.Luck.Luck.Value += 25000
print("WIN!")
elseif receiptInfo.ProductId == 3258933939 then
player.Luck.Luck.Value += 5000
print("WIN!")
elseif receiptInfo.ProductId == 3260806988 then
player.Boxes.LegendaryBox.Value += 1
print("WIN!")
end
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
Helloooo, there’s a few things I’d change here. One, use Players:GetPlayerByUserId(), there isn’t a need to loop through all the players. Also make sure that the process receipt function is on a server script and the MouseButton1Click is on a local script and if that’s the case for the player variable use game.Players.LocalPlayer no need for all those .parent’s lol.
Thirdly, if I was you I’d store some of the products in a table, so like for example with all the luck ones. So like for example:
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local LuckIds = {
[3258928056] = 10, -- number in the square brackets is the product id, the second number is amount you wanna give
[3258931532] = 100,
[3258933096] = 1000,
-- etc
}
MarketplaceService.ProcessReceipt = function(receiptInfo)
local Player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if LuckIds[receiptInfo.ProductId] then
Player.Luck.Luck.Value += LuckIds[receiptInfo.ProductId]
else
-- do rest here of product ids here
end
end
Yeah i believe i have fixed it using this which is basically the same thing
local Players = game:GetService("Players")
local MarketPlaceService = game:GetService("MarketplaceService")
MarketPlaceService.ProcessReceipt = function(receiptInfo)
local plr = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not plr then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
if receiptInfo.ProductId == 3258928056 then
plr.Luck.Luck.Value += 10
elseif receiptInfo.ProductId == 3258931532 then
plr.Luck.Luck.Value += 100
elseif receiptInfo.ProductId == 3258933096 then
plr.Luck.Luck.Value += 1000
elseif receiptInfo.ProductId == 3258935278 then
plr.Luck.Luck.Value += 100000
elseif receiptInfo.ProductId == 3258934601 then
plr.Luck.Luck.Value += 25000
elseif receiptInfo.ProductId == 3258933939 then
plr.Luck.Luck.Value += 5000
elseif receiptInfo.ProductId == 3260806988 then
plr.Boxes.LegendaryBox.Value += 1
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
This is not a viable way to handle the ProcessReceipt callback.
You need to check and record purchases using a GlobalDataStore and you need to properly return PurchaseGranted if the purchase has been successfully completed OR if the function detects that the purchase in question was already granted using the GlobalDataStore.
Below is a modified code sample originally taken directly from the Creator Documentation that shows how to properly utilize ProcessReceipt. I modified it so it fits your use case.
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Data store setup for tracking purchases that were successfully processed
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
-- Table setup containing product IDs and functions for handling purchases
local productFunctions = {}
-- Developer Product Id 3258928056 for 10 Luck
productFunctions[3258928056] = function(_receipt, player)
if player and player.Luck.Luck then
-- Add the Luck
player.Luck.Luck.Value += 10
-- Indicate a successful purchase
return true
end
end
-- Repeat the code above for the rest of your developer products,
-- making sure you modify the developer ID in the product functions dictionary
-- and the corresponding reward that is given upon purchase
-- The core 'ProcessReceipt' callback function
local function processReceipt(receiptInfo)
-- Check the data store to determine if the product was already granted
local playerProductKey = receiptInfo.PurchaseId
local purchased = false
local success, result, errorMessage
success, errorMessage = pcall(function()
purchased = purchaseHistoryStore:GetAsync(playerProductKey)
end)
-- If the purchase is recorded, the product was already granted
if success and purchased then
return Enum.ProductPurchaseDecision.PurchaseGranted
elseif not success then
error("Data store error:" .. errorMessage)
end
-- Update the purchase record
local success, isPurchaseRecorded = pcall(function()
return purchaseHistoryStore:UpdateAsync(playerProductKey, function(alreadyPurchased)
if alreadyPurchased then
return true
end
-- Find the player who made the purchase in the server
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- The player probably left the game
-- If the player returns, the callback is called again
return nil
end
local handler = productFunctions[receiptInfo.ProductId]
local success, result = pcall(handler, receiptInfo, player)
-- Do not record the purchase if granting the product failed
if not success or not result then
error("Failed to process a product purchase for ProductId: " .. tostring(receiptInfo.ProductId) .. " Player: " .. tostring(player) .. " Error: " .. tostring(result))
return nil
end
-- Record the transaction in purchaseHistoryStore
return true
end)
end)
if not success then
error("Failed to process receipt due to data store error.")
return Enum.ProductPurchaseDecision.NotProcessedYet
elseif isPurchaseRecorded == nil then
-- Did not update the value in the data store
return Enum.ProductPurchaseDecision.NotProcessedYet
else
-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt