Classe de moteur
MarketplaceService
*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.
Résumé
Méthodes
Événements
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 |
Rappels
ProcessReceipt(receiptInfo: Dictionary):Enum.ProductPurchaseDecision |
Référence API
Méthodes
BindReceiptHandler
MarketplaceService:BindReceiptHandler(
Paramètres
Retours
Échantillons de code
MarketplaceService:BindReceiptHandler
-- REMARQUE : Si votre gestionnaire accorde des avantages persistants (monnaie, objets), utilisez
-- DataStoreService:UpdateAsync() sur l'ID de demande de transfert pour éviter
-- de doubler la remise lorsque le même reçu est remis à plusieurs serveurs.
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Gérer les reçus de l'expéditeur (le joueur qui a envoyé des Robux)
MarketplaceService:BindReceiptHandler(
Enum.ReceiptType.RobuxTransferSender,
function(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Le joueur n'est pas sur ce serveur ; différer afin que le reçu soit
-- remis à quel que soit le serveur dans lequel il se trouve actuellement
return Enum.ReceiptDecision.NotProcessedYet
end
print(
`{player.Name} a envoyé {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Accorder toute reconnaissance côté expéditeur ou mettre à jour l'interface utilisateur ici
return Enum.ReceiptDecision.Processed
end
)
-- Gérer les reçus du destinataire (le joueur qui a reçu des 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} a reçu {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Accorder tous les avantages côté destinataire ou mettre à jour l'interface utilisateur ici
return Enum.ReceiptDecision.Processed
end
)GetDeveloperProductsAsync
Retours
Échantillons de code
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
Paramètres
| Valeur par défaut : "Asset" |
Retours
Échantillons de code
Obtenir des informations sur le produit
local MarketplaceService = game:GetService("MarketplaceService")
local ASSET_ID = 125378389
local asset = MarketplaceService:GetProductInfoAsync(ASSET_ID)
print(asset.Name .. " :: " .. asset.Description)Affichage des Remises de Prix
local MarketplaceService = game:GetService("MarketplaceService")
local PASS_ID = 12345678
local textLabel = script.Parent
local DiscountTypeDisplay = {
RobloxPlusSubscription = "Remise Roblox Plus",
}
local productInfo = MarketplaceService:GetProductInfoAsync(PASS_ID, Enum.InfoType.GamePass)
print(string.format("Prix Original: %d", productInfo.UserBasePriceInRobux))
for _, discount in ipairs(productInfo.PriceDiscountDetails) do
local displayName = DiscountTypeDisplay[discount.Type] or "Autre Remise"
print(string.format("%s (%d%%): -%d", displayName, discount.Percent, discount.AmountInRobux))
end
print(string.format("Vous Payez: %d", productInfo.PriceInRobux))Affichage des options temporisées disponibles
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 jours - %d Robux", days, option.Price))
end
endGetRobloxSubscriptionDetailsAsync
Paramètres
Retours
Échantillons de code
Vérifier les détails de l'abonnement 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. Vérifier la fidélité (par exemple, abonné pendant > 60 jours)
local threeMonths = 60 * 24 * 60 * 60
if details.StartTime and (os.time() - details.StartTime.UnixTimestamp) > threeMonths then
print("Attribution du skin 'Vétéran d'Abonnement de 3 Mois' !")
end
-- 2. Vérifier l'attribution
if details.IsOriginExperience then
print("Attribution confirmée : L'utilisateur s'est abonné via cette expérience.")
else
print("L'utilisateur s'est abonné ailleurs (site Web ou une autre expérience).")
end
end
end)GetSubscriptionProductInfoAsync
Paramètres
Retours
GetUsersPriceLevelsAsync
Paramètres
Retours
{PriceLevelInfo}
Échantillons de code
Obtenir les niveaux de prix pour une liste d'utilisateurs
-- Obtenir le MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Définir une fonction pour récupérer les niveaux de prix pour une liste d'utilisateurs
local function getPriceLevels(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- Mapper chaque PriceLevelInfo à une table de correspondance UserId -> PriceLevel
local lookup = {}
for _, info in ipairs(result) do
lookup[info.UserId] = info.PriceLevel
end
return lookup
else
warn("Erreur lors de l'obtention des niveaux de prix:", result)
return nil
end
end
-- Exemple utilisant des ID de remplacement
local user1Id = 123456789
local user2Id = 987654321
-- Appeler la fonction et stocker le résultat
local priceLevels = getPriceLevels({user1Id, user2Id})
-- Si cela réussit, afficher le niveau de chaque utilisateur
if priceLevels then
print("Niveau de prix pour l'utilisateur 1:", priceLevels[user1Id])
print("Niveau de prix pour l'utilisateur 2:", priceLevels[user2Id])
else
print("Échec de la récupération des niveaux de prix.")
endGetUserSubscriptionDetailsAsync
Retours
GetUserSubscriptionPaymentHistoryAsync
Retours
Échantillons de code
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(`Erreur lors de la vérification de l'historique des abonnements : {err}`)
return
end
if next(subscriptionHistory) then
-- L'utilisateur a un historique d'abonnement au cours des 12 derniers mois.
-- Imprimez les détails de chaque entrée de paiement de l'historique d'abonnement.
print(`Le joueur {player.Name} s'est abonné à {SUBSCRIPTION_ID} auparavant :`)
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(`Le joueur {player.Name} ne s'est jamais abonné à {SUBSCRIPTION_ID} auparavant.`)
end
end
-- Appeler checkSubscriptionHistory pour tous les joueurs déjà dans le jeu
for _, player in ipairs(Players:GetPlayers()) do
checkSubscriptionHistory(player)
end
-- Appeler checkSubscriptionHistory pour tous les futurs joueurs
Players.PlayerAdded:Connect(checkSubscriptionHistory)GetUserSubscriptionStatusAsync
Retours
Échantillons de code
Vérifier le statut d'abonnement de l'utilisateur
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()
-- renvoie IsRenewing et IsSubscribed
subStatus = MarketplaceService:GetUserSubscriptionStatusAsync(player, subscriptionID)
end)
if not success then
warn("Erreur lors de la vérification si le joueur a un abonnement : " .. tostring(message))
return
end
if subStatus["IsSubscribed"] then
print(player.Name .. " est abonné avec " .. subscriptionID)
-- Donner au joueur les permissions associées à l'abonnement
end
end
Players.PlayerAdded:Connect(checkSubStatus)PlayerOwnsAsset
PlayerOwnsAssetAsync
Retours
Échantillons de code
Vérifiez la propriété d'un objet
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- L'objet que nous vérifions : 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(`Erreur lors de la vérification si {player.Name} possède {ASSET_NAME}: {errorMessage}`)
return
end
if doesPlayerOwnAsset then
print(`{player.Name} possède {ASSET_NAME}`)
else
print(`{player.Name} ne possède pas {ASSET_NAME}`)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)PlayerOwnsBundle
PlayerOwnsBundleAsync
Retours
Échantillons de code
Vérifier la Propriété du Package
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- Le bundle que nous vérifions : 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("L'appel à PlayerOwnsBundleAsync a échoué : ", doesPlayerOwnBundle)
return
end
if doesPlayerOwnBundle then
print(player.Name .. " possède " .. BUNDLE_NAME)
else
print(player.Name .. " ne possède pas " .. BUNDLE_NAME)
end
end)PromptBulkPurchase
Paramètres
Retours
()
Échantillons de code
Client d'Achat en Gros d'Invitations
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)Serveur d'Achat en Gros par Invitation
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptBulkPurchaseEvent = Instance.new("RemoteEvent")
promptBulkPurchaseEvent.Name = "PromptBulkPurchaseEvent"
promptBulkPurchaseEvent.Parent = ReplicatedStorage
--Écoutez le RemoteEvent se déclencher depuis un client et ensuite déclenchez le prompt d'achat en gros
promptBulkPurchaseEvent.OnServerEvent:Connect(function(player, items)
MarketplaceService:PromptBulkPurchase(player, items, {})
end)Achat d'option temporisée
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
-- Trouver l'option de la durée la plus courte
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(
):()
Paramètres
| Valeur par défaut : true |
| Valeur par défaut : "Default" |
Retours
()
Échantillons de code
MarketplaceService:PromptProductPurchase
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local productId = 0000000 -- Changez ceci pour votre ID de produit pour développeur
-- Fonction pour inciter à l'achat du produit pour développeur
local function promptPurchase()
MarketplaceService:PromptProductPurchase(player, productId)
end
promptPurchase()PromptPurchase
MarketplaceService:PromptPurchase(
):()
Paramètres
| Valeur par défaut : true |
| Valeur par défaut : "Default" |
Retours
()
Échantillons de code
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 (Serveur)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptPurchaseEvent = Instance.new("RemoteEvent")
promptPurchaseEvent.Name = "PromptPurchaseEvent"
promptPurchaseEvent.Parent = ReplicatedStorage
-- Écoutez le RemoteEvent se déclencher depuis un Client et ensuite déclenchez l'invite d'achat
promptPurchaseEvent.OnServerEvent:Connect(function(player, id)
MarketplaceService:PromptPurchase(player, id)
end)PromptRobloxSubscriptionPurchase
Paramètres
Retours
()
Échantillons de code
Demande d'achat d'abonnement 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)
-- Accorder la récompense et téléporter le joueur abonné dans la zone exclusive
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
-- Détecter les parties du personnage touchant le téléporteur
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
-- Le joueur a déjà Roblox Plus ; accorder la récompense immédiatement
grantRewardAndTeleport(player)
else
-- Demander l'abonnement Roblox Plus, limité à une fois toutes les quelques secondes
if not showModal then
return
end
showModal = false
task.delay(5, function()
showModal = true
end)
MarketplaceService:PromptRobloxSubscriptionPurchase(player)
end
end)
-- Détecter les parties du personnage quittant le téléporteur
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)
-- Accorder la récompense lorsque le serveur confirme un changement d'abonnement
-- Connecter le changement HasRobloxSubscription pour chaque joueur
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
Retours
Échantillons de code
MarketplaceService:PromptRobuxTransferAsync
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Exemple : transférer des Robux lorsqu'un joueur déclenche un RemoteEvent
local transferEvent = game.ReplicatedStorage:WaitForChild("RequestTransfer")
transferEvent.OnServerEvent:Connect(function(sender, receiverUserId, amount)
-- Valider les entrées
if not sender or not sender:IsA("Player") then
return
end
if typeof(receiverUserId) ~= "number" or receiverUserId <= 0 then
warn("receiverUserId invalide")
return
end
if typeof(amount) ~= "number" or amount <= 0 then
warn("montant invalide")
return
end
local success, result = pcall(function()
return MarketplaceService:PromptRobuxTransferAsync(sender, receiverUserId, amount)
end)
if success then
print(`Transfert initié avec TransferRequestId : {result}`)
else
warn(`Échec du transfert : {result}`)
end
end)PromptSubscriptionPurchase
RankProductsAsync
Paramètres
Retours
{RankedItem}
Échantillons de code
Obtenez une liste de produits classés en fonction des ID de produit fournis
-- Obtenez le MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Créez le tableau de produits que vous souhaitez classer
local productIdentifiers = {
{InfoType = Enum.InfoType.GamePass, Id = 123},
{InfoType = Enum.InfoType.Product, Id = 456},
{InfoType = Enum.InfoType.Product, Id = 789}
}
-- Appelez dans un appel protégé pour gérer les erreurs gracieusement
local success, rankedProducts = pcall(function()
return MarketplaceService:RankProductsAsync(productIdentifiers)
end)
if not success then
error("Échec du classement des produits")
end
-- Chargez les articles retournés dans le magasin.
for i, rankedItem in ipairs(rankedProducts) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logique pour ajouter des produits dans le magasin
endRecommendTopProductsAsync
Paramètres
Retours
{RankedItem}
Échantillons de code
Obtenez une liste classée des meilleurs produits pour votre magasin en expérience
-- Obtenez le MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Créez un tableau de types de produits à inclure. Dans ce cas, les passes de jeu et les produits développeurs
local productTypes = {Enum.InfoType.GamePass, Enum.InfoType.Product}
-- Appelez dans un appel protégé pour gérer les erreurs gracieusement
local success, topRankedItems = pcall(function()
return MarketplaceService:RecommendTopProductsAsync(productTypes)
end)
if not success then
error("Échec du classement des produits")
end
-- Chargez les articles retournés dans le magasin. Assurez-vous de filtrer les articles non éligibles de topRankedItems tels que les produits développeurs que l'utilisateur ne peut plus acheter
for i, rankedItem in ipairs(topRankedItems) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logique pour ajouter des produits dans le magasin
endÉvénements
PromptBulkPurchaseFinished
MarketplaceService.PromptBulkPurchaseFinished(
Paramètres
PromptBundlePurchaseFinished
PromptGamePassPurchaseFinished
MarketplaceService.PromptGamePassPurchaseFinished(
Échantillons de code
Gestion de l'achat de Gamepass terminé
local MarketplaceService = game:GetService("MarketplaceService")
local function gamepassPurchaseFinished(...)
-- Imprimer tous les détails de l'invite, par exemple :
-- PromptGamePassPurchaseFinished PlayerName 123456 false
print("PromptGamePassPurchaseFinished", ...)
end
MarketplaceService.PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)PromptProductPurchaseFinished
PromptPurchaseFinished
MarketplaceService.PromptPurchaseFinished(
Échantillons de code
Gestion de l'événement PromptPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptPurchaseFinished(player, assetId, isPurchased)
if isPurchased then
print(player.Name, "a acheté un objet avec l'AssetID :", assetId)
else
print(player.Name, "n'a pas acheté un objet avec l'AssetID :", assetId)
end
end
MarketplaceService.PromptPurchaseFinished:Connect(onPromptPurchaseFinished)PromptRobloxSubscriptionPurchaseFinished
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished(
Échantillons de code
Gérer l'événement PromptRobloxSubscriptionPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptRobloxSubscriptionPurchaseFinished(player, didTryPurchasing)
if didTryPurchasing then
-- Le joueur a tenté de s'abonner ; attendez le changement de HasRobloxSubscription pour confirmer
print(player.Name, "a tenté de s'abonner à Roblox Plus")
else
print(player.Name, "a fermé l'invite d'abonnement Roblox Plus sans acheter")
end
end
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished:Connect(onPromptRobloxSubscriptionPurchaseFinished)Rappels
ProcessReceipt
Paramètres
Retours
Échantillons de code
Callback ProcessReceipt
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Configuration du data store pour suivre les achats qui ont été correctement traités
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local productIdByName = {
fullHeal = 123123,
gold100 = 456456,
}
-- Un dictionnaire pour rechercher la fonction de gestion qui accorde un achat correspondant à un ID de produit
-- Ces fonctions retournent vrai si l'achat a été accordé avec succès
-- Ces fonctions ne doivent jamais yield car elles sont appelées plus tard dans une fonction de rappel UpdateAsync()
local grantPurchaseHandlerByProductId = {
[productIdByName.fullHeal] = function(_receipt, player)
local character = player.Character
local humanoid = character and character:FindFirstChild("Humanoid")
-- Assurez-vous que le joueur a un humanoïde à guérir
if not humanoid then
return false
end
-- Soignez le joueur à pleine santé
humanoid.Health = humanoid.MaxHealth
-- Indique un accord réussi
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
-- Ajoutez 100 pièces d'or au statut d'or du joueur
goldStat.Value += 100
-- Indique un accord réussi
return true
end,
}
-- La fonction de rappel principale ProcessReceipt
-- Cette implémentation gère la plupart des scénarios d'échec, mais ne mitige pas complètement les scénarios d'échec de données entre serveurs
local function processReceipt(receiptInfo)
local success, result = pcall(
purchaseHistoryStore.UpdateAsync,
purchaseHistoryStore,
receiptInfo.PurchaseId,
function(isPurchased)
if isPurchased then
-- Cet achat a déjà été enregistré comme accordé, donc il a dû être géré précédemment
-- Évitez d'appeler le gestionnaire d'accord ici pour prévenir l'accord double de l'achat
-- Bien que la valeur dans le data store soit déjà vrai, vrai est retourné à nouveau afin que la variable de résultat de pcall soit également vraie
-- Cela sera utilisé plus tard pour retourner PurchaseGranted depuis le processeur de reçus
return true
end
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Évite d'accorder l'achat si le joueur n'est pas sur le serveur
-- Lorsqu'il rejoindra à nouveau, ce processeur de reçus sera appelé à nouveau
return nil
end
local grantPurchaseHandler = grantPurchaseHandlerByProductId[receiptInfo.ProductId]
if not grantPurchaseHandler then
-- S'il n'y a pas de gestionnaire défini pour cet ID de produit, l'achat ne peut pas être traité
-- Cela n'arrivera jamais tant qu'un gestionnaire est défini pour chaque ID de produit vendu dans l'expérience
warn(`Aucun gestionnaire d'achat défini pour l'ID de produit '{receiptInfo.ProductId}'`)
return nil
end
local handlerSucceeded, handlerResult = pcall(grantPurchaseHandler, receiptInfo, player)
if not handlerSucceeded then
local errorMessage = handlerResult
warn(
`Le gestionnaire d'achat a rencontré une erreur lors du traitement de l'achat de '{player.Name}' pour l'ID de produit '{receiptInfo.ProductId}': {errorMessage}`
)
return nil
end
local didHandlerGrantPurchase = handlerResult == true
if not didHandlerGrantPurchase then
-- Le gestionnaire n'a pas accordé l'achat, donc enregistrez-le comme non accordé
return nil
end
-- L'achat est maintenant accordé au joueur, donc enregistrez-le comme accordé
-- Cela sera utilisé plus tard pour retourner PurchaseGranted depuis le processeur de reçus
return true
end
)
if not success then
local errorMessage = result
warn(`Échec du traitement du reçu en raison d'une erreur de data store : {errorMessage}`)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local didGrantPurchase = result == true
return if didGrantPurchase
then Enum.ProductPurchaseDecision.PurchaseGranted
else Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Définissez le rappel ; cela peut uniquement être fait une fois par un script sur le serveur
MarketplaceService.ProcessReceipt = processReceipt