Klasa silnika
MarketplaceService
*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.
Podsumowanie
Metody
Zdarzenia
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 |
Wywołania zwrotne
ProcessReceipt(receiptInfo: Dictionary):Enum.ProductPurchaseDecision |
Materiały referencyjne dotyczące interfejsów API
Metody
BindReceiptHandler
MarketplaceService:BindReceiptHandler(
Parametry
Zwroty
Przykłady kodu
MarketplaceService:BindReceiptHandler
-- UWAGA: Jeśli twój handler przyznaje trwałe korzyści (walutę, przedmioty), użyj
-- DataStoreService:UpdateAsync() na TransferRequestId, aby zapobiec
-- podwójnemu przyznawaniu, gdy ten sam paragon jest dostarczany do wielu serwerów.
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Obsłuż paragony nadawcy (gracz, który wysłał Robux)
MarketplaceService:BindReceiptHandler(
Enum.ReceiptType.RobuxTransferSender,
function(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Gracz nie jest na tym serwerze; odłóż, aby paragon został
-- ponownie dostarczony do serwera, na którym aktualnie się znajduje
return Enum.ReceiptDecision.NotProcessedYet
end
print(
`{player.Name} wysłał {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Przyznaj wszelkie potwierdzenia po stronie nadawcy lub zaktualizuj UI tutaj
return Enum.ReceiptDecision.Processed
end
)
-- Obsłuż paragony odbiorcy (gracz, który otrzymał 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} otrzymał {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Przyznaj wszelkie korzyści po stronie odbiorcy lub zaktualizuj UI tutaj
return Enum.ReceiptDecision.Processed
end
)GetDeveloperProductsAsync
Zwroty
Przykłady kodu
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
Parametry
| Wartość domyślna: "Asset" |
Zwroty
Przykłady kodu
Pozyskiwanie informacji o produkcie
local MarketplaceService = game:GetService("MarketplaceService")
local ASSET_ID = 125378389
local asset = MarketplaceService:GetProductInfoAsync(ASSET_ID)
print(asset.Name .. " :: " .. asset.Description)Wyświetlanie zniżek cenowych
local MarketplaceService = game:GetService("MarketplaceService")
local PASS_ID = 12345678
local textLabel = script.Parent
local DiscountTypeDisplay = {
RobloxPlusSubscription = "Zniżka na Roblox Plus",
}
local productInfo = MarketplaceService:GetProductInfoAsync(PASS_ID, Enum.InfoType.GamePass)
print(string.format("Oryginalna cena: %d", productInfo.UserBasePriceInRobux))
for _, discount in ipairs(productInfo.PriceDiscountDetails) do
local displayName = DiscountTypeDisplay[discount.Type] or "Inna zniżka"
print(string.format("%s (%d%%): -%d", displayName, discount.Percent, discount.AmountInRobux))
end
print(string.format("Płacisz: %d", productInfo.PriceInRobux))Wyświetlanie dostępnych opcji czasowych
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 dni - %d Robux", days, option.Price))
end
endGetRobloxSubscriptionDetailsAsync
Parametry
Zwroty
Przykłady kodu
Sprawdź szczegóły subskrypcji 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. Sprawdź lojalność (np. Subskrypcja przez > 60 dni)
local threeMonths = 60 * 24 * 60 * 60
if details.StartTime and (os.time() - details.StartTime.UnixTimestamp) > threeMonths then
print("Przyznawanie skórki 'Weteran Subskrypcji na 3 Miesiące'!")
end
-- 2. Sprawdź atrybucję
if details.IsOriginExperience then
print("Atrybucja potwierdzona: Użytkownik subskrybował przez to doświadczenie.")
else
print("Użytkownik subskrybował gdzie indziej (strona internetowa lub inne doświadczenie).")
end
end
end)GetSubscriptionProductInfoAsync
Parametry
Zwroty
GetUsersPriceLevelsAsync
Parametry
Zwroty
{PriceLevelInfo}
Przykłady kodu
Pobierz poziomy cen dla listy użytkowników
-- Pobierz MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Zdefiniuj funkcję do pobierania poziomów cen dla listy użytkowników
local function getPriceLevels(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- Mapuj każdy PriceLevelInfo do tabeli wyszukiwania UserId -> PriceLevel
local lookup = {}
for _, info in ipairs(result) do
lookup[info.UserId] = info.PriceLevel
end
return lookup
else
warn("Błąd podczas pobierania poziomów cen:", result)
return nil
end
end
-- Przykład z użyciem identyfikatorów zastępczych
local user1Id = 123456789
local user2Id = 987654321
-- Wywołaj funkcję i zapisz wynik
local priceLevels = getPriceLevels({user1Id, user2Id})
-- Jeśli się powiedzie, wydrukuj poziom każdego użytkownika
if priceLevels then
print("Poziom cen dla Użytkownika 1:", priceLevels[user1Id])
print("Poziom cen dla Użytkownika 2:", priceLevels[user2Id])
else
print("Nie udało się pobrać poziomów cen.")
endGetUserSubscriptionDetailsAsync
Zwroty
GetUserSubscriptionPaymentHistoryAsync
Zwroty
Przykłady kodu
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(`Błąd podczas sprawdzania historii subskrypcji: {err}`)
return
end
if next(subscriptionHistory) then
-- Użytkownik ma jakąś historię subskrypcji w ciągu ostatnich 12 miesięcy.
-- Wypisz szczegóły każdej płatności z historii subskrypcji.
print(`Gracz {player.Name} subskrybował {SUBSCRIPTION_ID} wcześniej:`)
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(`Gracz {player.Name} nigdy wcześniej nie subskrybował {SUBSCRIPTION_ID}.`)
end
end
-- Wywołaj checkSubscriptionHistory dla wszystkich graczy już w grze
for _, player in ipairs(Players:GetPlayers()) do
checkSubscriptionHistory(player)
end
-- Wywołaj checkSubscriptionHistory dla wszystkich przyszłych graczy
Players.PlayerAdded:Connect(checkSubscriptionHistory)GetUserSubscriptionStatusAsync
Zwroty
Przykłady kodu
Sprawdź status subskrypcji użytkownika
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()
-- zwraca IsRenewing i IsSubscribed
subStatus = MarketplaceService:GetUserSubscriptionStatusAsync(player, subscriptionID)
end)
if not success then
warn("Błąd podczas sprawdzania, czy gracz ma subskrypcję: " .. tostring(message))
return
end
if subStatus["IsSubscribed"] then
print(player.Name .. " jest subskrybowany z " .. subscriptionID)
-- Przyznaj graczowi uprawnienia związane z subskrypcją
end
end
Players.PlayerAdded:Connect(checkSubStatus)PlayerOwnsAsset
PlayerOwnsAssetAsync
Zwroty
Przykłady kodu
Sprawdź posiadanie przedmiotu
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- Przedmiot, którego szukamy: 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(`Błąd podczas sprawdzania, czy {player.Name} posiada {ASSET_NAME}: {errorMessage}`)
return
end
if doesPlayerOwnAsset then
print(`{player.Name} posiada {ASSET_NAME}`)
else
print(`{player.Name} nie posiada {ASSET_NAME}`)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)PlayerOwnsBundle
PlayerOwnsBundleAsync
Zwroty
Przykłady kodu
Sprawdź posiadanie pakietu
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- Pakiet, który sprawdzamy: 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("Wywołanie PlayerOwnsBundleAsync się nie powiodło: ", doesPlayerOwnBundle)
return
end
if doesPlayerOwnBundle then
print(player.Name .. " posiada " .. BUNDLE_NAME)
else
print(player.Name .. " nie posiada " .. BUNDLE_NAME)
end
end)PromptBulkPurchase
Parametry
Zwroty
()
Przykłady kodu
Klient Zakupu Hurtowego
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)Serwer zakupu hurtowego
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptBulkPurchaseEvent = Instance.new("RemoteEvent")
promptBulkPurchaseEvent.Name = "PromptBulkPurchaseEvent"
promptBulkPurchaseEvent.Parent = ReplicatedStorage
--Nasłuchuj na RemoteEvent, aby zostało wywołane z klienta, a następnie uruchom okno zakupu hurtowego
promptBulkPurchaseEvent.OnServerEvent:Connect(function(player, items)
MarketplaceService:PromptBulkPurchase(player, items, {})
end)Zakup Opcji Czasowej z Powiadomieniem
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
-- Znajdź opcję o najkrótszym czasie trwania
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(
):()
Parametry
| Wartość domyślna: true |
| Wartość domyślna: "Default" |
Zwroty
()
Przykłady kodu
MarketplaceService:PromptProductPurchase
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local productId = 0000000 -- Zmień to na swój identyfikator produktu dewelopera
-- Funkcja do wywołania prośby o zakup produktu dewelopera
local function promptPurchase()
MarketplaceService:PromptProductPurchase(player, productId)
end
promptPurchase()PromptPurchase
MarketplaceService:PromptPurchase(
):()
Parametry
| Wartość domyślna: true |
| Wartość domyślna: "Default" |
Zwroty
()
Przykłady kodu
LocalScript (Klient)
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)Skrypt (Serwer)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptPurchaseEvent = Instance.new("RemoteEvent")
promptPurchaseEvent.Name = "PromptPurchaseEvent"
promptPurchaseEvent.Parent = ReplicatedStorage
-- Nasłuchuj w wyzwalaniu RemoteEvent z Klienta i następnie uruchom okno zakupu
promptPurchaseEvent.OnServerEvent:Connect(function(player, id)
MarketplaceService:PromptPurchase(player, id)
end)PromptRobloxSubscriptionPurchase
Parametry
Zwroty
()
Przykłady kodu
Zakup subskrypcji 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)
-- Przyznaj nagrodę i teleportuj subskrybującego gracza do ekskluzywnego obszaru
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
-- Wykryj części postaci dotykające teleportera
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
-- Gracz już ma Roblox Plus; przyznaj nagrodę natychmiast
grantRewardAndTeleport(player)
else
-- Zaproś do subskrypcji Roblox Plus, z debouncem co kilka sekund
if not showModal then
return
end
showModal = false
task.delay(5, function()
showModal = true
end)
MarketplaceService:PromptRobloxSubscriptionPurchase(player)
end
end)
-- Wykryj części postaci wychodzące z teleportera
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)
-- Przyznaj nagrodę, gdy serwer potwierdzi zmianę subskrypcji
-- Połącz zmianę HasRobloxSubscription dla każdego gracza
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
Zwroty
Przykłady kodu
MarketplaceService:PromptRobuxTransferAsync
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Przykład: transferuj Robux, gdy gracz wywoła RemoteEvent
local transferEvent = game.ReplicatedStorage:WaitForChild("RequestTransfer")
transferEvent.OnServerEvent:Connect(function(sender, receiverUserId, amount)
-- Walidacja danych wejściowych
if not sender or not sender:IsA("Player") then
return
end
if typeof(receiverUserId) ~= "number" or receiverUserId <= 0 then
warn("Nieprawidłowy receiverUserId")
return
end
if typeof(amount) ~= "number" or amount <= 0 then
warn("Nieprawidłowa kwota")
return
end
local success, result = pcall(function()
return MarketplaceService:PromptRobuxTransferAsync(sender, receiverUserId, amount)
end)
if success then
print(`Transfer zainicjowany z TransferRequestId: {result}`)
else
warn(`Transfer nie powiódł się: {result}`)
end
end)PromptSubscriptionPurchase
RankProductsAsync
Parametry
Zwroty
{RankedItem}
Przykłady kodu
Uzyskaj listę produktów z rankingu na podstawie podanych identyfikatorów produktów
-- Pobierz MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Utwórz tablicę produktów, które chcesz uporządkować
local productIdentifiers = {
{InfoType = Enum.InfoType.GamePass, Id = 123},
{InfoType = Enum.InfoType.Product, Id = 456},
{InfoType = Enum.InfoType.Product, Id = 789}
}
-- Wywołaj w zabezpieczonym wywołaniu, aby obsłużyć błędy w sposób elegancki
local success, rankedProducts = pcall(function()
return MarketplaceService:RankProductsAsync(productIdentifiers)
end)
if not success then
error("Nie udało się uporządkować produktów")
end
-- Załaduj zwrócone przedmioty do sklepu.
for i, rankedItem in ipairs(rankedProducts) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logika dodawania produktów do sklepu
endRecommendTopProductsAsync
Parametry
Zwroty
{RankedItem}
Przykłady kodu
Uzyskaj uszeregowaną listę najlepszych produktów w swoim sklepie wewnątrz doświadczenia
-- Uzyskaj MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Utwórz tablicę typów produktów do uwzględnienia. W tym przypadku zarówno przepustki do gier, jak i produkty dewelopera
local productTypes = {Enum.InfoType.GamePass, Enum.InfoType.Product}
-- Wywołaj w zabezpieczonym wywołaniu, aby obsłużyć błędy w sposób elegancki
local success, topRankedItems = pcall(function()
return MarketplaceService:RecommendTopProductsAsync(productTypes)
end)
if not success then
error("Nie udało się uszeregować produktów")
end
-- Załaduj zwrócone elementy do sklepu. Upewnij się, że filtrujesz wszelkie niekwalifikujące się elementy z topRankedItems, takie jak produkty dewelopera, które użytkownik nie może już zakupić
for i, rankedItem in ipairs(topRankedItems) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logika dodawania produktów do sklepu
endZdarzenia
PromptBulkPurchaseFinished
MarketplaceService.PromptBulkPurchaseFinished(
Parametry
PromptBundlePurchaseFinished
PromptGamePassPurchaseFinished
MarketplaceService.PromptGamePassPurchaseFinished(
Przykłady kodu
Obsługa zakończenia zakupu Gamepass
local MarketplaceService = game:GetService("MarketplaceService")
local function gamepassPurchaseFinished(...)
-- Wydrukuj wszystkie szczegóły powiadomienia, na przykład:
-- PromptGamePassPurchaseFinished PlayerName 123456 false
print("PromptGamePassPurchaseFinished", ...)
end
MarketplaceService.PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)PromptProductPurchaseFinished
PromptPurchaseFinished
MarketplaceService.PromptPurchaseFinished(
Przykłady kodu
Obsługa zdarzenia PromptPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptPurchaseFinished(player, assetId, isPurchased)
if isPurchased then
print(player.Name, "kupił przedmiot o AssetID:", assetId)
else
print(player.Name, "nie kupił przedmiotu o AssetID:", assetId)
end
end
MarketplaceService.PromptPurchaseFinished:Connect(onPromptPurchaseFinished)PromptRobloxSubscriptionPurchaseFinished
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished(
Przykłady kodu
Obsługuje zdarzenie PromptRobloxSubscriptionPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptRobloxSubscriptionPurchaseFinished(player, didTryPurchasing)
if didTryPurchasing then
-- Gracz próbował subskrybować; czekaj na zmianę HasRobloxSubscription, aby potwierdzić
print(player.Name, "próbował subskrybować Roblox Plus")
else
print(player.Name, "zamykał okno subskrypcji Roblox Plus bez zakupu")
end
end
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished:Connect(onPromptRobloxSubscriptionPurchaseFinished)Wywołania zwrotne
ProcessReceipt
Parametry
Przykłady kodu
Wywołanie zwrotne ProcessReceipt
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Ustawienie magazynu danych do śledzenia zakupów, które zostały pomyślnie przetworzone
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local productIdByName = {
fullHeal = 123123,
gold100 = 456456,
}
-- Słownik do wyszukiwania funkcji obsługującej przyznanie zakupu odpowiadającego identyfikatorowi produktu
-- Te funkcje zwracają true, jeśli zakup został pomyślnie przyznany
-- Te funkcje nigdy nie powinny być niezrealizowane, ponieważ są wywoływane później w wywołaniu zwrotnym UpdateAsync()
local grantPurchaseHandlerByProductId = {
[productIdByName.fullHeal] = function(_receipt, player)
local character = player.Character
local humanoid = character and character:FindFirstChild("Humanoid")
-- Upewnij się, że gracz ma humanoida do uzdrowienia
if not humanoid then
return false
end
-- Uzdrowienie gracza do pełnego zdrowia
humanoid.Health = humanoid.MaxHealth
-- Wskazanie pomyślnego przyznania
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
-- Dodanie 100 złota do statystyki złota gracza
goldStat.Value += 100
-- Wskazanie pomyślnego przyznania
return true
end,
}
-- Główna funkcja zwrotna ProcessReceipt
-- Ta implementacja obsługuje większość scenariuszy błędów, ale nie łagodzi całkowicie scenariuszy błędów danych między serwerami
local function processReceipt(receiptInfo)
local success, result = pcall(
purchaseHistoryStore.UpdateAsync,
purchaseHistoryStore,
receiptInfo.PurchaseId,
function(isPurchased)
if isPurchased then
-- Ten zakup został już zarejestrowany jako przyznany, więc musiał być wcześniej obsługiwany
-- Unikaj wywoływania funkcji obsługującej przyznanie zakupu, aby zapobiec podwójnemu przyznaniu zakupu
-- Podczas gdy wartość w magazynie danych jest już prawdziwa, prawda jest zwracana ponownie, aby zmienna wyniku pcall również była prawdziwa
-- To później będzie użyte do zwrócenia PurchaseGranted z przetwornika rachunków
return true
end
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Unika przyznania zakupu, jeśli gracz nie jest na serwerze
-- Gdy dołączy ponownie, ten przetwornik rachunków zostanie wywołany ponownie
return nil
end
local grantPurchaseHandler = grantPurchaseHandlerByProductId[receiptInfo.ProductId]
if not grantPurchaseHandler then
-- Jeśli nie ma zdefiniowanej funkcji obsługującej dla tego identyfikatora produktu, zakup nie może być przetworzony
-- To nigdy nie zdarzy się tak długo, jak funkcja obsługująca jest ustawiona dla każdego identyfikatora produktu sprzedawanego w doświadczeniu
warn(`Nie zdefiniowano funkcji obsługującej zakup dla identyfikatora produktu '{receiptInfo.ProductId}'`)
return nil
end
local handlerSucceeded, handlerResult = pcall(grantPurchaseHandler, receiptInfo, player)
if not handlerSucceeded then
local errorMessage = handlerResult
warn(
`Funkcja obsługująca przyznanie zakupu zgłosiła błąd podczas przetwarzania zakupu od '{player.Name}' dla identyfikatora produktu '{receiptInfo.ProductId}': {errorMessage}`
)
return nil
end
local didHandlerGrantPurchase = handlerResult == true
if not didHandlerGrantPurchase then
-- Funkcja obsługująca nie przyznała zakupu, więc zarejestruj go jako nieprzyznany
return nil
end
-- Zakup jest teraz przyznany graczowi, więc zarejestruj go jako przyznany
-- To później będzie użyte do zwrócenia PurchaseGranted z przetwornika rachunków
return true
end
)
if not success then
local errorMessage = result
warn(`Nie udało się przetworzyć rachunku z powodu błędu w magazynie danych: {errorMessage}`)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local didGrantPurchase = result == true
return if didGrantPurchase
then Enum.ProductPurchaseDecision.PurchaseGranted
else Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Ustaw wywołanie zwrotne; może to być wykonane tylko raz przez jeden skrypt na serwerze
MarketplaceService.ProcessReceipt = processReceipt