Hello, I have a script that should give players different amounts of cash depending on what develop product they purchased. However, each time they buy it, they get given more and more cash. (e.g. if they buy a 1k product, then they will get 1k, 2k, 3k, 4k ect. for each purpose.
I have determined that this issue is the looping of the process reciept function, but I can’t figure out what exactly is causing it.
I saw some other posts about this same issue, but couldn’t really find a solution within it.
My code:
local DS2 = require(1936396537)
local MarketplaceService = game:GetService("MarketplaceService")
local playerMoney = game.ServerStorage:WaitForChild("PlayerMoney")
local RemoteEvent = game.ReplicatedStorage:WaitForChild("MoneyPurchase")
local event = game.ReplicatedStorage:WaitForChild("Donate")
local Marketplace = game:GetService("MarketplaceService")
local DatastoreService = game:GetService("DataStoreService")
local Donations = DatastoreService:GetOrderedDataStore("Donations")
local ChatService = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner"):WaitForChild("ChatService"))
local IDs = {
[1208476645] = 1000,
[1208476646] = 2500,
[1208476644] = 10000,
[1208476642] = 100000,
[1208476643] = 1000000
}
local DonationIDs = {
[1208496944] = 25,
[1208496945] = 50,
[1208496946] = 75,
[1208496947] = 100,
[1208496948] = 250,
[1208497389] = 500,
[1208497480] = 750,
[1208497648] = 1000,
[1208497649] = 2500,
[1208497718] = 5000
}
if not ChatService:GetChannel("All") then
while true do
local ChannelName = ChatService.ChannelAdded:Wait()
if ChannelName == "All" then
break
end
end
end
local DonationAnnouncement = ChatService:AddSpeaker("Donations")
DonationAnnouncement:JoinChannel("All")
DonationAnnouncement:SetExtraData("NameColor", Color3.fromRGB(255, 170, 0))
DonationAnnouncement:SetExtraData("ChatColor", Color3.fromRGB(255, 255, 0))
RemoteEvent.OnServerEvent:Connect(function(plr, amount)
MarketplaceService:PromptProductPurchase(plr, IDs[amount])
end)
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")
-- Table setup containing product IDs and functions for handling purchases
local productFunctions = {}
local function processReceipt(receiptInfo)
print("Purchase Processing")
-- 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 = function()
if IDs[receiptInfo.ProductId] then
playerMoney[player.Name].Value = playerMoney[player.Name].Value + IDs[receiptInfo.ProductId]
print("Awarding money")
DS2("Money", player):Set(playerMoney[player.Name].Value)
print("Money awarded")
DS2("Money", player).Save()
return true
elseif DonationIDs[receiptInfo.ProductId] then
local success, err = pcall(function()
Donations:UpdateAsync(player.UserId, function(old)
local oldValue = old or 0
for key, value in pairs(DonationIDs) do
if receiptInfo.ProductId == key then
spawn(function()DonationAnnouncement:SayMessage(player.Name.." just donated R$"..receiptInfo.CurrencySpent.."! Thank you!", "All")end)
return oldValue + tonumber(value)
end
end
end)
end)
return true
else
warn("ID did not match list")
end
end
-- Call the handler function and catch any errors
local success, result = pcall(handler, receiptInfo, player)
if not success then --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