Hey everyone,
I’ve created a system for managing all my DevProdcuts in my game. It consists of two main parts:
DevProductManager (Server Module)
This module holds a table where you can easily add new product IDs and define actions for each one. The product ID is the key, and the value is a function that defines what happens when the product is bought. You only need to add the product ID and the corresponding function—everything else happens automatically. It has a Buy Function too, it runs when the player buys something.
DevProductHandler (Server Script)
This script handles all purchases via the ProcessReceipt
function. It checks for valid player data, calls the appropriate function from the DevProductManager
module, and processes the purchase.
How it works:
-
Add product IDs: Just add a new entry to the
ProductIDs
table in theDevProductManager
module. -
Define the action: For each product ID, write the function that should be executed when the player purchases it (e.g., adding money to the player).
-
Everything else is automatic: The script will automatically detect the product ID, execute the function, and handle the purchase.
Code Review Request
I would love a review of my code to see if it’s efficient, clean, and secure. Please check for any potential improvements, issues, or best practices that I may have missed:
Video:
DevProductManager (ModuleScript):
-- //: Function for getting the money value in leaderstats
local function getMoneyValue(plr: Player)
-- Get leaderstats
local leaderstats = plr:FindFirstChild("leaderstats")
if not leaderstats then
warn(plr.Name .. " Has no Leaderstats")
return false
end
-- Get Money Value
local money = leaderstats:FindFirstChild("Money")
if not money then
warn(plr.Name .. " Has no MoneyValue in leaderstats")
return false
end
return money
end
-- //: MAIN
local DevProductManager = {
-- //: List of ProductIDs with functions that run when a player buys them
ProductIDs = {
["3224322508"] = function(plr: Player)
-- Checking Function
local money = getMoneyValue(plr)
if not money then
return false
end
money.Value += 100
print(plr.Name .. " Bought 100 Money for 5 Robux!")
return true
end,
["3224322948"] = function(plr: Player)
-- Checking Function
local money = getMoneyValue(plr)
if not money then
return false
end
money.Value += 500
print(plr.Name .. " Bought 500 Money for 10 Robux!")
return true
end,
["3224323154"] = function(plr: Player)
--- Checking Function
local money = getMoneyValue(plr)
if not money then
return false
end
money.Value += 1000
print(plr.Name .. " Bought 1000 Money for 15 Robux!")
return true
end,
["3224323352"] = function(plr: Player)
-- Checking Function
local money = getMoneyValue(plr)
if not money then
return false
end
money.Value += 5000
print(plr.Name .. " Bought 5000 Money for 20 Robux!")
return true
end,
["Type here you Product ID"] = function(plr: Player)
-- Type here what should happen
end,
}
}
-- //: Function runs when player Buys Something
DevProductManager.Buy = function(plr: Player, productID: number)
-- Check if productID is acutally a number
if typeof(productID) ~= "number" then
warn("ProductID Argument has to be a number!")
return false
end
-- Check if given ProductID exists in the list
local productFunction = DevProductManager.ProductIDs[tostring(productID)]
if productFunction == nil then
warn("ProductID Argument does not exists in the 'ProdcutIDs' table")
return false
end
-- Call the function that belongs to the given ProductID
local func = productFunction(plr)
if func then
return true
else
return false
end
end
return DevProductManager
DevProductHandler (ServerScript):
-- //: Variables
local devProductModule = require(game:GetService("ServerScriptService").Modules.DevProductManager)
local marketplaceService = game:GetService("MarketplaceService")
-- //: Main Function
marketplaceService.ProcessReceipt = function(recieptInfo)
-- //: Check if player is valid
local plr = game.Players:GetPlayerByUserId(recieptInfo.PlayerId)
if not plr then
warn("Player with UserID " .. recieptInfo.PlayerId .. " could not be found.")
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- //: Run the Buy Function, but in pcall
local success, returnValue = pcall(function()
return devProductModule.Buy(plr, recieptInfo.ProductId)
end)
-- //: Debugging
if success then
-- Check if the Buy Function returned true or false
if returnValue then
print("Buy Function Returned True - Purchase granted for Player: " .. plr.Name .. ", Product ID: " .. recieptInfo.ProductId)
return Enum.ProductPurchaseDecision.PurchaseGranted
else
warn("Buy Function Returned False - Purchase Not Processed for Player: " .. plr.Name .. ", Product ID: " .. recieptInfo.ProductId)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
else
-- If something went wrong with the function, log the error and return NotProcessedYet
warn("Error during purchase processing for Player: " .. plr.Name .. ", Product ID: " .. recieptInfo.ProductId)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
end
I would love to hear some feedback!