Hi, I have a working donation leaderboard. The script works fine, but I want to add handling for MORE Developer Products, like a seperate +100 cash leaderstat addition. This script is too complicated for me to try and modify so any help appreciated!
ProcessReciept script:
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Data store for tracking purchases that were successfully processed
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
-- Ordered data store for the leaderboard
local donationStore = DataStoreService:GetOrderedDataStore("DonationStore1")
-- Remove event to trigger leaderboard update
local donateEvent = script.Parent.DonateEvent
-- Function that saves a record of the donation
-- The total number of robux donated is saved, not each individual donation
local donateFunction = function(receipt, player)
-- Logic/code for player donating robux
local playerKey = "Player_" .. player.UserId
local newTotal = nil
local success, err = pcall(function()
donationStore:UpdateAsync(playerKey, function(oldValue)
local newValue = oldValue or 0
-- Increase player donations by amount donated
newValue = newValue + receipt.CurrencySpent
newTotal = newValue
return newValue
end)
end)
if (success) then
print("Successful purchase")
-- Signals to update the donate leaderboard
donateEvent:Fire(player, newTotal)
return true
else
print("Purchase failed")
print(err)
return false
end
end
-- The core 'ProcessReceipt' callback function
local function processReceipt(receiptInfo)
-- Determine if the product was already granted by checking the data store
local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
local purchased = false
local success, errorMessage = pcall(function()
purchased = purchaseHistoryStore:GetAsync(playerProductKey)
end)
-- If purchase was 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
-- 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 they come back, the callback will be called again
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Look up handler function from 'productFunctions' table above
--local handler = productFunctions[receiptInfo.ProductId]
local handler = donateFunction
-- Call the handler function and catch any errors
local success, result = pcall(handler, receiptInfo, player)
if not success or not result then
warn("Error occurred while processing a product purchase")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Record transaction in data store so it isn't granted again
local success, errorMessage = pcall(function()
purchaseHistoryStore:SetAsync(playerProductKey, true)
end)
if not success then
error("Cannot save purchase data: " .. errorMessage)
end
-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt
Purchase Script:
local mc = game:GetService("MarketplaceService")
local plr = script.Parent.Parent.Parent.Parent.Parent.Parent
local plrUserId = plr.UserId
local productId = 2698539771
script.Parent.MouseButton1Click:Connect(function()
mc:PromptProductPurchase(plr, 2698539771)
end)
ok so ive heard that you can only call processreceipt once. I got a dono leaderboard but now i wanna add +cash dev products to my shop. idk how to add support to the processreciept script without deleting and messing with the dono reciepts
A callback to process receipts of developer product purchases. This callback should be set once and only once by a single Script. If you’re selling multiple products in your experience, this callback should handle receipts for all of them.
i mean that, since i have to add to the already existing complicated donation dev product process receipt script, (as of the evidence i showed u.) im not sure on how to add some support for NON-donation developer products, without having to rework the whole script.
have one singular function that handles the receipt processing (to avoid repetition), pass the needed parameters to it
then, inside a module script (for example), have a function for each developer product called “OnPurchased” or whatever, and call that function everytime the receipt gets processed to give the player to reward
if there is no reward, just simply put a “return” in the function and that’s it
this is probably a horrible idea but i can’t really think of anything else
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Data store for tracking purchases that were successfully processed
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
-- Ordered data store for the leaderboard
local donationStore = DataStoreService:GetOrderedDataStore("DonationStore1")
-- Remove event to trigger leaderboard update
local donateEvent = script.Parent.DonateEvent
-- Function that saves a record of the donation
-- The total number of robux donated is saved, not each individual donation
local donateFunction = function(receipt, player)
-- Logic/code for player donating robux
local playerKey = "Player_" .. player.UserId
if receipt.ProductId == 2698539771 then
--insert your logic for adding cash to the players leaderstats
--player.leaderstats.Cash.Value += 100
else
local newTotal = nil
local success, err = pcall(function()
donationStore:UpdateAsync(playerKey, function(oldValue)
local newValue = oldValue or 0
-- Increase player donations by amount donated
newValue = newValue + receipt.CurrencySpent
newTotal = newValue
return newValue
end)
end)
end
if (success) then
print("Successful purchase")
-- Signals to update the donate leaderboard
if not receipt.ProductId == 2698539771 then
donateEvent:Fire(player, newTotal)
end
return true
else
print("Purchase failed")
print(err)
return false
end
end
-- The core 'ProcessReceipt' callback function
local function processReceipt(receiptInfo)
-- Determine if the product was already granted by checking the data store
local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
local purchased = false
local success, errorMessage = pcall(function()
purchased = purchaseHistoryStore:GetAsync(playerProductKey)
end)
-- If purchase was 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
-- 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 they come back, the callback will be called again
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Look up handler function from 'productFunctions' table above
--local handler = productFunctions[receiptInfo.ProductId]
local handler = donateFunction
-- Call the handler function and catch any errors
local success, result = pcall(handler, receiptInfo, player)
if not success or not result then
warn("Error occurred while processing a product purchase")
print("\nProductId:", receiptInfo.ProductId)
print("\nPlayer:", player)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Record transaction in data store so it isn't granted again
local success, errorMessage = pcall(function()
purchaseHistoryStore:SetAsync(playerProductKey, true)
end)
if not success then
error("Cannot save purchase data: " .. errorMessage)
end
-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- Set the callback; this can only be done once by one script on the server!
MarketplaceService.ProcessReceipt = processReceipt
Apologies if this doesn’t work as i am doing this on phone, but what i changed is that on the donate function, i add an if statement that checks if the receipts product id is the one for your 100 cash dev product, and if it matches, then fire different logic than if it were a donation, which the examples i put there is that it adds 100 cash to the players Cash leaderstat assuming thats how you’ve coded the cash system to work