Hello fellow devs!
Now I am publishing Samurai Era and I want to add a new Donate & Pray system
for Big Budda, temples and shrines.
Under this system, if a player donate 5 R$ (buy a developer product) from Proximity Prompt, a player is supposed to play a series of animation tracks including vow and pray.
Now I made 3 animation files and want a player play these animations one by one
if the player purchase the developer product.
I created a local script under StarterCharacterScripts folder
for Proximity Prompt to open the purchase page.
Then I created a server script called Process Receipt under ServerScriptService.
These scripts are as follows:
–Local Script–
Blockquote
local pps = game:GetService(“ProximityPromptService”)
local plr = game:GetService(“Players”).LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild(“Humanoid”)
local hrp = char:WaitForChild(“HumanoidRootPart”)
local Animator = hum:WaitForChild(“Animator”)
local passID = 1283736714
local donateAndPrayPromptForBigBudda = game.Workspace.BigBudda.DonationBox.DonationBoxBody.DonateAndPray
local remoteDonateAndPray = game:GetService(“ReplicatedStorage”):WaitForChild(“DonateAndPray”)
local RS = game:GetService(“ReplicatedStorage”)
local animations = RS.Effects.Animations
local clap2Times = animations.Clap2Times
local deepOjigi = animations.DeepOjigi
local pray = animations.Pray
local function onPromptTriggered(prompt, plr)
if prompt.Name == “DonateAndPray” then
game:GetService(“MarketplaceService”):PromptProductPurchase(plr, passID)
end
end
pps.PromptTriggered:Connect(onPromptTriggered)
Blockquote
–Server Script–
Blockquote
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 = {}
productFunctions[1283736714] = function(_receipt, player)
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local Animator = hum:WaitForChild("Animator")
local passID = 1283736714
local donateAndPrayPromptForBigBudda = game.Workspace.BigBudda.DonationBox.DonationBoxBody.DonateAndPray
local remoteDonateAndPray = game:GetService("ReplicatedStorage"):WaitForChild("DonateAndPray")
local RS = game:GetService("ReplicatedStorage")
local animations = RS.Effects.Animations
local clap2Times = animations.Clap2Times
local deepOjigi = animations.DeepOjigi
local pray = animations.Pray
local clap2TimesTrack = Animator:LoadAnimation(clap2Times)
local deepOjigiTrack = Animator:LoadAnimation(deepOjigi)
local prayTrack = Animator:LoadAnimation(pray)
local animTracks = {deepOjigiTrack, clap2TimesTrack, prayTrack}
for _, eachTrack in pairs (animTracks) do
eachTrack.Priority = Enum.AnimationPriority.Action
eachTrack.Looped = false
end
deepOjigiTrack:Play()
deepOjigiTrack.Stopped:wait()
wait(1)
deepOjigiTrack:Play()
deepOjigiTrack.Stopped:wait()
wait(1)
clap2TimesTrack:Play()
clap2TimesTrack.Stopped:wait()
wait(1)
prayTrack:Play()
prayTrack.Stopped:wait()
wait(1)
deepOjigiTrack:Play()
deepOjigiTrack.Stopped:wait()
wait(1)
player.leaderstats.Luck.Value += 10
return true
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, result, errorMessage
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
-- Determine if the product was already granted by checking the data store
local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
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 they come back, the callback will be called again
return nil
end
local handler = productFunctions[receiptInfo.ProductId]
local success, result = pcall(handler, receiptInfo, player)
-- If granting the product failed, do NOT record the purchase in datastores.
if not success or not result then
error("Failed to process a product purchase for ProductId:", receiptInfo.ProductId, " Player:", player)
return nil
end
-- Record the transcation 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
-- Didn't update the value in 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
Blockquote
What I see now is a player is just repeating vowing all the time in the experience.
I don’t know why it happens.
I will appreciate if someone help me.