Classe motore
MarketplaceService
*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.
Sommario
Metodi
Eventi
PromptBulkPurchaseFinished(player: Instance,status: Enum.MarketplaceBulkPurchasePromptStatus,results: Dictionary):RBXScriptSignal |
PromptBundlePurchaseFinished(player: Instance,bundleId: number,wasPurchased: boolean):RBXScriptSignal |
PromptGamePassPurchaseFinished(player: Instance,gamePassId: number,wasPurchased: boolean):RBXScriptSignal |
PromptProductPurchaseFinished(userId: number,productId: number,isPurchased: boolean):RBXScriptSignal |
PromptPurchaseFinished(player: Instance,assetId: number,isPurchased: boolean):RBXScriptSignal |
PromptRobloxSubscriptionPurchaseFinished(user: Player,didTryPurchasing: boolean):RBXScriptSignal |
PromptSubscriptionPurchaseFinished(user: Player,subscriptionId: string,didTryPurchasing: boolean):RBXScriptSignal |
Richiami
ProcessReceipt(receiptInfo: Dictionary):Enum.ProductPurchaseDecision |
Riferimento API
Metodi
BindReceiptHandler
MarketplaceService:BindReceiptHandler(
Parametri
Restituzioni
Campioni di codice
MarketplaceService:BindReceiptHandler
-- NOTA: Se il tuo gestore concede benefici persistenti (valuta, oggetti), usa
-- DataStoreService:UpdateAsync() sull'ID della richiesta di trasferimento per prevenire
-- la concessione doppia quando lo stesso ricevimento è consegnato a più server.
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Gestisci i ricevimenti dei mittenti (il giocatore che ha inviato Robux)
MarketplaceService:BindReceiptHandler(
Enum.ReceiptType.RobuxTransferSender,
function(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Il giocatore non è su questo server; deferisci in modo che il ricevimento venga
-- riconsegnato a qualsiasi server in cui si trova attualmente
return Enum.ReceiptDecision.NotProcessedYet
end
print(
`{player.Name} ha inviato {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Concedi qualsiasi riconoscimento lato mittente o aggiorna l'interfaccia utente qui
return Enum.ReceiptDecision.Processed
end
)
-- Gestisci i ricevimenti dei destinatari (il giocatore che ha ricevuto Robux)
MarketplaceService:BindReceiptHandler(
Enum.ReceiptType.RobuxTransferReceiver,
function(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
return Enum.ReceiptDecision.NotProcessedYet
end
print(
`{player.Name} ha ricevuto {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Concedi qualsiasi beneficio lato destinatario o aggiorna l'interfaccia utente qui
return Enum.ReceiptDecision.Processed
end
)GetDeveloperProductsAsync
Restituzioni
Campioni di codice
MarketplaceService:GetDeveloperProductsAsync
local MarketplaceService = game:GetService("MarketplaceService")
local developerProducts = MarketplaceService:GetDeveloperProductsAsync():GetCurrentPage()
for _, developerProduct in pairs(developerProducts) do
for field, value in pairs(developerProduct) do
print(field .. ": " .. value)
end
print(" ")
endGetProductInfo
GetProductInfoAsync
Parametri
| Valore predefinito: "Asset" |
Restituzioni
Campioni di codice
Ottenere informazioni sul prodotto
local MarketplaceService = game:GetService("MarketplaceService")
local ASSET_ID = 125378389
local asset = MarketplaceService:GetProductInfoAsync(ASSET_ID)
print(asset.Name .. " :: " .. asset.Description)Visualizzazione degli sconti sui prezzi
local MarketplaceService = game:GetService("MarketplaceService")
local PASS_ID = 12345678
local textLabel = script.Parent
local DiscountTypeDisplay = {
RobloxPlusSubscription = "Sconto Roblox Plus",
}
local productInfo = MarketplaceService:GetProductInfoAsync(PASS_ID, Enum.InfoType.GamePass)
print(string.format("Prezzo originale: %d", productInfo.UserBasePriceInRobux))
for _, discount in ipairs(productInfo.PriceDiscountDetails) do
local displayName = DiscountTypeDisplay[discount.Type] or "Altro sconto"
print(string.format("%s (%d%%): -%d", displayName, discount.Percent, discount.AmountInRobux))
end
print(string.format("Prezzo da pagare: %d", productInfo.PriceInRobux))Visualizzazione delle Opzioni Temporizzate Disponibili
local MarketplaceService = game:GetService("MarketplaceService")
local info = MarketplaceService:GetProductInfoAsync(105589844216517, Enum.InfoType.Asset)
if info.TimedOptions then
for _, option in info.TimedOptions do
local days = option.Duration / 86400
print(string.format("%d giorni - %d Robux", days, option.Price))
end
endGetRobloxSubscriptionDetailsAsync
Parametri
Restituzioni
Campioni di codice
Controlla i dettagli dell'abbonamento Roblox
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
local success, details = pcall(function()
return MarketplaceService:GetRobloxSubscriptionDetailsAsync(player)
end)
if success and details.IsSubscribed then
-- 1. Controlla la Fedeltà (ad es., Abbonato per > 60 giorni)
local threeMonths = 60 * 24 * 60 * 60
if details.StartTime and (os.time() - details.StartTime.UnixTimestamp) > threeMonths then
print("Assegnazione della skin 'Veterano dell'Abbonamento di 3 Mesi'!")
end
-- 2. Controlla l'Attribuzione
if details.IsOriginExperience then
print("Attribuzione confermata: Utente abbonato tramite questa esperienza.")
else
print("Utente abbonato altrove (Sito Web o un'altra Esperienza).")
end
end
end)GetSubscriptionProductInfoAsync
Parametri
Restituzioni
GetUsersPriceLevelsAsync
Parametri
Restituzioni
{PriceLevelInfo}
Campioni di codice
Ottieni i livelli di prezzo per un elenco di utenti
-- Ottieni il MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Definisci una funzione per recuperare i livelli di prezzo per un elenco di utenti
local function getPriceLevels(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- Mappa ogni PriceLevelInfo a una tabella di ricerca UserId -> PriceLevel
local lookup = {}
for _, info in ipairs(result) do
lookup[info.UserId] = info.PriceLevel
end
return lookup
else
warn("Errore nel recuperare i livelli di prezzo:", result)
return nil
end
end
-- Esempio usando ID segnaposto
local user1Id = 123456789
local user2Id = 987654321
-- Chiama la funzione e salva il risultato
local priceLevels = getPriceLevels({user1Id, user2Id})
-- Se ha avuto successo, stampa il livello di ciascun utente
if priceLevels then
print("Livello di prezzo per l'Utente 1:", priceLevels[user1Id])
print("Livello di prezzo per l'Utente 2:", priceLevels[user2Id])
else
print("Impossibile recuperare i livelli di prezzo.")
endGetUserSubscriptionDetailsAsync
Restituzioni
GetUserSubscriptionPaymentHistoryAsync
Restituzioni
Campioni di codice
MarketplaceService:GetUserSubscriptionPaymentHistoryAsync
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local SUBSCRIPTION_ID = "EXP-0"
local function checkSubscriptionHistory(player: Player)
local subscriptionHistory = {}
local success, err = pcall(function()
subscriptionHistory = MarketplaceService:GetUserSubscriptionPaymentHistoryAsync(player, SUBSCRIPTION_ID)
end)
if not success then
warn(`Errore durante il controllo della storia degli abbonamenti: {err}`)
return
end
if next(subscriptionHistory) then
-- L'utente ha una storia di abbonamento negli ultimi 12 mesi.
-- Stampa i dettagli di ogni voce di pagamento dalla storia degli abbonamenti.
print(`Il giocatore {player.Name} si è abbonato a {SUBSCRIPTION_ID} in precedenza:`)
for entryNum, paymentEntry in subscriptionHistory do
local paymentStatus = tostring(paymentEntry.PaymentStatus)
local cycleStartTime = paymentEntry.CycleStartTime:FormatLocalTime("LLL", "en-us")
local cycleEndTime = paymentEntry.CycleEndTime:FormatLocalTime("LLL", "en-us")
print(`{entryNum}: {paymentStatus} ({cycleStartTime} - {cycleEndTime})`)
end
else
print(`Il giocatore {player.Name} non si è mai abbonato a {SUBSCRIPTION_ID} in precedenza.`)
end
end
-- Chiama checkSubscriptionHistory per i giocatori già nel gioco
for _, player in ipairs(Players:GetPlayers()) do
checkSubscriptionHistory(player)
end
-- Chiama checkSubscriptionHistory per tutti i giocatori futuri
Players.PlayerAdded:Connect(checkSubscriptionHistory)GetUserSubscriptionStatusAsync
Restituzioni
Campioni di codice
Controlla lo stato dell'abbonamento dell'utente
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local subscriptionID = "EXP-00000"
local function checkSubStatus(player)
local subStatus = {}
local success, message = pcall(function()
-- restituisce IsRenewing e IsSubscribed
subStatus = MarketplaceService:GetUserSubscriptionStatusAsync(player, subscriptionID)
end)
if not success then
warn("Errore durante il controllo se il giocatore ha un abbonamento: " .. tostring(message))
return
end
if subStatus["IsSubscribed"] then
print(player.Name .. " è abbonato con " .. subscriptionID)
-- Dai al giocatore i permessi associati all'abbonamento
end
end
Players.PlayerAdded:Connect(checkSubStatus)PlayerOwnsAsset
PlayerOwnsAssetAsync
Restituzioni
Campioni di codice
Controlla il possesso degli oggetti
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- L'oggetto che stiamo controllando: https://www.roblox.com/catalog/30331986/Midnight-Shades
local ASSET_ID = 30331986
local ASSET_NAME = "Midnight Shades"
local function onPlayerAdded(player)
local success, doesPlayerOwnAsset =
pcall(MarketplaceService.PlayerOwnsAssetAsync, MarketplaceService, player, ASSET_ID)
if not success then
local errorMessage = doesPlayerOwnAsset
warn(`Errore durante il controllo se {player.Name} possiede {ASSET_NAME}: {errorMessage}`)
return
end
if doesPlayerOwnAsset then
print(`{player.Name} possiede {ASSET_NAME}`)
else
print(`{player.Name} non possiede {ASSET_NAME}`)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)PlayerOwnsBundle
PlayerOwnsBundleAsync
Restituzioni
Campioni di codice
Controlla il possesso del bundle
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- Il bundle che stiamo controllando: https://www.roblox.com/bundles/589/Junkbot
local BUNDLE_ID = 589
local BUNDLE_NAME = "Junkbot"
Players.PlayerAdded:Connect(function(player)
local success, doesPlayerOwnBundle = pcall(function()
return MarketplaceService:PlayerOwnsBundleAsync(player, BUNDLE_ID)
end)
if success == false then
print("La chiamata a PlayerOwnsBundleAsync è fallita: ", doesPlayerOwnBundle)
return
end
if doesPlayerOwnBundle then
print(player.Name .. " possiede " .. BUNDLE_NAME)
else
print(player.Name .. " non possiede " .. BUNDLE_NAME)
end
end)PromptBulkPurchase
Parametri
Restituzioni
()
Campioni di codice
Cliente di Acquisto in Blocchi
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local promptBulkPurchaseEvent = ReplicatedStorage:WaitForChild("PromptBulkPurchaseEvent")
local part = Instance.new("Part")
part.Parent = workspace
local clickDetector = Instance.new("ClickDetector")
clickDetector.Parent = part
clickDetector.MouseClick:Connect(function()
promptBulkPurchaseEvent:FireServer({
{ Type = Enum.MarketplaceProductType.AvatarAsset, Id = "16630147" },
{ Type = Enum.MarketplaceProductType.AvatarBundle, Id = "182" },
})
end)Server di acquisto in blocco promemoria
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptBulkPurchaseEvent = Instance.new("RemoteEvent")
promptBulkPurchaseEvent.Name = "PromptBulkPurchaseEvent"
promptBulkPurchaseEvent.Parent = ReplicatedStorage
--Ascolta il RemoteEvent che si attiva da un Client e poi attiva il prompt di acquisto in blocco
promptBulkPurchaseEvent.OnServerEvent:Connect(function(player, items)
MarketplaceService:PromptBulkPurchase(player, items, {})
end)Acquisto di Opzioni Temporizzate
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local ASSET_ID = 105589844216517
Players.PlayerAdded:Connect(function(player)
local info = MarketplaceService:GetProductInfoAsync(ASSET_ID, Enum.InfoType.Asset)
if info.TimedOptions and #info.TimedOptions > 0 then
-- Trova l'opzione con la durata più breve
local shortest = info.TimedOptions[1]
for _, option in info.TimedOptions do
if option.Duration < shortest.Duration then
shortest = option
end
end
local items = {
{
Type = Enum.MarketplaceProductType.AvatarAsset,
Id = tostring(ASSET_ID),
PurchaseOptions = {
{ Type = Enum.PurchaseOption.TimedOption, Value = shortest.Duration },
},
}
}
MarketplaceService:PromptBulkPurchase(player, items, {})
end
end)PromptBundlePurchase
PromptCancelSubscription
PromptGamePassPurchase
PromptPremiumPurchase
PromptProductPurchase
MarketplaceService:PromptProductPurchase(
):()
Parametri
| Valore predefinito: true |
| Valore predefinito: "Default" |
Restituzioni
()
Campioni di codice
MarketplaceService:PromptProductPurchase
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local productId = 0000000 -- Cambia questo con l'ID del tuo prodotto da sviluppatore
-- Funzione per richiedere l'acquisto del prodotto dello sviluppatore
local function promptPurchase()
MarketplaceService:PromptProductPurchase(player, productId)
end
promptPurchase()PromptPurchase
MarketplaceService:PromptPurchase(
):()
Parametri
| Valore predefinito: true |
| Valore predefinito: "Default" |
Restituzioni
()
Campioni di codice
LocalScript (Client)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local promptPurchaseEvent = ReplicatedStorage:WaitForChild("PromptPurchaseEvent")
local part = Instance.new("Part")
part.Parent = workspace
local clickDetector = Instance.new("ClickDetector")
clickDetector.Parent = part
clickDetector.MouseClick:Connect(function()
promptPurchaseEvent:FireServer(16630147)
end)Script (Server)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptPurchaseEvent = Instance.new("RemoteEvent")
promptPurchaseEvent.Name = "PromptPurchaseEvent"
promptPurchaseEvent.Parent = ReplicatedStorage
-- Ascolta il RemoteEvent attivarsi da un Client e poi attiva la richiesta di acquisto
promptPurchaseEvent.OnServerEvent:Connect(function(player, id)
MarketplaceService:PromptPurchase(player, id)
end)PromptRobloxSubscriptionPurchase
Parametri
Restituzioni
()
Campioni di codice
Acquisto Abbonamento Roblox Plus
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local teleporter = script.Parent
local showModal = true
local EXCLUSIVE_AREA_POSITION = Vector3.new(1200, 200, 60)
-- Concedi il premio e teletrasporta il giocatore che si abbona nell'area esclusiva
local function grantRewardAndTeleport(player)
player:RequestStreamAroundAsync(EXCLUSIVE_AREA_POSITION)
local character = player.Character
if character and character.Parent then
local currentPivot = character:GetPivot()
character:PivotTo(currentPivot * CFrame.new(EXCLUSIVE_AREA_POSITION))
end
end
-- Rileva le parti del personaggio che toccano il teletrasportatore
teleporter.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if not player then
return
end
if not player:GetAttribute("CharacterPartsTouching") then
player:SetAttribute("CharacterPartsTouching", 0)
end
player:SetAttribute("CharacterPartsTouching", player:GetAttribute("CharacterPartsTouching") + 1)
if player.HasRobloxSubscription then
-- Il giocatore ha già Roblox Plus; concede immediatamente il premio
grantRewardAndTeleport(player)
else
-- Invita all'abbonamento a Roblox Plus, in ritardo a una volta ogni pochi secondi
if not showModal then
return
end
showModal = false
task.delay(5, function()
showModal = true
end)
MarketplaceService:PromptRobloxSubscriptionPurchase(player)
end
end)
-- Rileva le parti del personaggio che escono dal teletrasportatore
teleporter.TouchEnded:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player and player:GetAttribute("CharacterPartsTouching") then
player:SetAttribute("CharacterPartsTouching", player:GetAttribute("CharacterPartsTouching") - 1)
end
end)
-- Concedi il premio quando il server conferma un cambiamento di abbonamento
-- Collega il cambiamento di HasRobloxSubscription per ogni giocatore
Players.PlayerAdded:Connect(function(player)
player:GetPropertyChangedSignal("HasRobloxSubscription"):Connect(function()
if player.HasRobloxSubscription
and player:GetAttribute("CharacterPartsTouching")
and player:GetAttribute("CharacterPartsTouching") > 0
then
grantRewardAndTeleport(player)
end
end)
end)PromptRobuxTransferAsync
Restituzioni
Campioni di codice
MarketplaceService:PromptRobuxTransferAsync
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Esempio: trasferire Robux quando un giocatore attiva un RemoteEvent
local transferEvent = game.ReplicatedStorage:WaitForChild("RequestTransfer")
transferEvent.OnServerEvent:Connect(function(sender, receiverUserId, amount)
-- Valida gli input
if not sender or not sender:IsA("Player") then
return
end
if typeof(receiverUserId) ~= "number" or receiverUserId <= 0 then
warn("receiverUserId non valido")
return
end
if typeof(amount) ~= "number" or amount <= 0 then
warn("importo non valido")
return
end
local success, result = pcall(function()
return MarketplaceService:PromptRobuxTransferAsync(sender, receiverUserId, amount)
end)
if success then
print(`Trasferimento avviato con TransferRequestId: {result}`)
else
warn(`Trasferimento fallito: {result}`)
end
end)PromptSubscriptionPurchase
RankProductsAsync
Parametri
Restituzioni
{RankedItem}
Campioni di codice
Ottieni un elenco di prodotti classificati in base agli ID prodotto forniti
-- Ottieni il MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Crea l'array di prodotti che desideri classificare
local productIdentifiers = {
{InfoType = Enum.InfoType.GamePass, Id = 123},
{InfoType = Enum.InfoType.Product, Id = 456},
{InfoType = Enum.InfoType.Product, Id = 789}
}
-- Chiama in una chiamata protetta per gestire gli errori in modo elegante
local success, rankedProducts = pcall(function()
return MarketplaceService:RankProductsAsync(productIdentifiers)
end)
if not success then
error("Impossibile classificare i prodotti")
end
-- Carica gli oggetti restituiti nel negozio.
for i, rankedItem in ipairs(rankedProducts) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logica per aggiungere prodotti nel negozio
endRecommendTopProductsAsync
Parametri
Restituzioni
{RankedItem}
Campioni di codice
Ottieni un elenco classificato dei migliori prodotti per il tuo negozio in esperienza
-- Ottieni il MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Crea un array di tipi di prodotto da includere. In questo caso sia passaggi di gioco che prodotti per sviluppatori
local productTypes = {Enum.InfoType.GamePass, Enum.InfoType.Product}
-- Chiama in una chiamata protetta per gestire gli errori in modo elegante
local success, topRankedItems = pcall(function()
return MarketplaceService:RecommendTopProductsAsync(productTypes)
end)
if not success then
error("Impossibile classificare i prodotti")
end
-- Carica gli articoli restituiti nel negozio. Assicurati di filtrare eventuali articoli non idonei da topRankedItems come prodotti per sviluppatori che l'utente non può più acquistare
for i, rankedItem in ipairs(topRankedItems) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logica per aggiungere prodotti nel negozio
endEventi
PromptBulkPurchaseFinished
MarketplaceService.PromptBulkPurchaseFinished(
Parametri
PromptBundlePurchaseFinished
PromptGamePassPurchaseFinished
MarketplaceService.PromptGamePassPurchaseFinished(
Campioni di codice
Gestione dell'acquisto del Gamepass completato
local MarketplaceService = game:GetService("MarketplaceService")
local function gamepassPurchaseFinished(...)
-- Stampa tutti i dettagli del prompt, ad esempio:
-- PromptGamePassPurchaseFinished PlayerName 123456 false
print("PromptGamePassPurchaseFinished", ...)
end
MarketplaceService.PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)PromptProductPurchaseFinished
PromptPurchaseFinished
MarketplaceService.PromptPurchaseFinished(
Campioni di codice
Gestire l'evento PromptPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptPurchaseFinished(player, assetId, isPurchased)
if isPurchased then
print(player.Name, "ha acquistato un oggetto con AssetID:", assetId)
else
print(player.Name, "non ha acquistato un oggetto con AssetID:", assetId)
end
end
MarketplaceService.PromptPurchaseFinished:Connect(onPromptPurchaseFinished)PromptRobloxSubscriptionPurchaseFinished
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished(
Campioni di codice
Gestire l'evento PromptRobloxSubscriptionPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptRobloxSubscriptionPurchaseFinished(player, didTryPurchasing)
if didTryPurchasing then
-- Il giocatore ha tentato di abbonarsi; attendi il cambiamento di HasRobloxSubscription per confermare
print(player.Name, "ha tentato di abbonarsi a Roblox Plus")
else
print(player.Name, "ha chiuso il prompt di abbonamento a Roblox Plus senza acquistare")
end
end
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished:Connect(onPromptRobloxSubscriptionPurchaseFinished)Richiami
ProcessReceipt
Parametri
Restituzioni
Campioni di codice
Callback ProcessReceipt
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Configurazione del data store per tracciare gli acquisti che sono stati elaborati con successo
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local productIdByName = {
fullHeal = 123123,
gold100 = 456456,
}
-- Un dizionario per cercare la funzione di gestione per concedere un acquisto corrispondente a un ID prodotto
-- Queste funzioni restituiscono true se l'acquisto è stato concesso con successo
-- Queste funzioni non devono mai yield poiché vengono chiamate in seguito all'interno di un callback UpdateAsync()
local grantPurchaseHandlerByProductId = {
[productIdByName.fullHeal] = function(_receipt, player)
local character = player.Character
local humanoid = character and character:FindFirstChild("Humanoid")
-- Assicurati che il giocatore abbia un umanoide da curare
if not humanoid then
return false
end
-- Cura il giocatore al pieno della salute
humanoid.Health = humanoid.MaxHealth
-- Indica un concessione riuscita
return true
end,
[productIdByName.gold100] = function(_receipt, player)
local leaderstats = player:FindFirstChild("leaderstats")
local goldStat = leaderstats and leaderstats:FindFirstChild("Gold")
if not goldStat then
return false
end
-- Aggiungi 100 oro allo stato oro del giocatore
goldStat.Value += 100
-- Indica un concessione riuscita
return true
end,
}
-- La funzione di callback principale ProcessReceipt
-- Questa implementazione gestisce la maggior parte degli scenari di errore ma non mitiga completamente gli scenari di errore dei dati incrociati tra server
local function processReceipt(receiptInfo)
local success, result = pcall(
purchaseHistoryStore.UpdateAsync,
purchaseHistoryStore,
receiptInfo.PurchaseId,
function(isPurchased)
if isPurchased then
-- Questo acquisto è già stato registrato come concesso, quindi deve essere stato gestito in precedenza
-- Evita di chiamare il gestore di concessione qui per prevenire la concessione dell'acquisto due volte
-- Anche se il valore nel data store è già true, true viene restituito di nuovo in modo che la variabile di risultato del pcall sia anch'essa true
-- Questo verrà utilizzato in seguito per restituire PurchaseGranted dal processore della ricevuta
return true
end
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Evita di concedere l'acquisto se il giocatore non è nel server
-- Quando si ricollegheranno, questo processore della ricevuta verrà chiamato di nuovo
return nil
end
local grantPurchaseHandler = grantPurchaseHandlerByProductId[receiptInfo.ProductId]
if not grantPurchaseHandler then
-- Se non c'è nessun gestore definito per questo ID prodotto, l'acquisto non può essere elaborato
-- Questo non accadrà mai fintanto che un gestore è impostato per ogni ID prodotto venduto nell'esperienza
warn(`Nessun gestore di acquisto definito per l'ID prodotto '{receiptInfo.ProductId}'`)
return nil
end
local handlerSucceeded, handlerResult = pcall(grantPurchaseHandler, receiptInfo, player)
if not handlerSucceeded then
local errorMessage = handlerResult
warn(
`Il gestore di concessione dell'acquisto ha restituito un errore durante l'elaborazione dell'acquisto da '{player.Name}' dell'ID prodotto '{receiptInfo.ProductId}': {errorMessage}`
)
return nil
end
local didHandlerGrantPurchase = handlerResult == true
if not didHandlerGrantPurchase then
-- Il gestore non ha concesso l'acquisto, quindi registralo come non concesso
return nil
end
-- L'acquisto è ora concesso al giocatore, quindi registralo come concesso
-- Questo verrà utilizzato in seguito per restituire PurchaseGranted dal processore della ricevuta
return true
end
)
if not success then
local errorMessage = result
warn(`Impossibile elaborare la ricevuta a causa di un errore nel data store: {errorMessage}`)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local didGrantPurchase = result == true
return if didGrantPurchase
then Enum.ProductPurchaseDecision.PurchaseGranted
else Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Imposta il callback; questo può essere fatto solo una volta da uno script sul server
MarketplaceService.ProcessReceipt = processReceipt