Kelas Engine
MarketplaceService
*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.
Rangkuman
Metode
Acara
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 |
Callback
ProcessReceipt(receiptInfo: Dictionary):Enum.ProductPurchaseDecision |
Referensi API
Metode
BindReceiptHandler
MarketplaceService:BindReceiptHandler(
Parameter
Memberikan nilai
Contoh Kode
MarketplaceService:BindReceiptHandler
-- CATATAN: Jika handler Anda memberikan manfaat yang persisten (mata uang, item), gunakan
-- DataStoreService:UpdateAsync() pada TransferRequestId untuk mencegah
-- pemberian ganda ketika tanda terima yang sama dikirim ke beberapa server.
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Tangani tanda terima pengirim (pemain yang mengirim Robux)
MarketplaceService:BindReceiptHandler(
Enum.ReceiptType.RobuxTransferSender,
function(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Pemain tidak ada di server ini; tunda agar tanda terima
-- dikirim ulang ke server tempat mereka berada saat ini
return Enum.ReceiptDecision.NotProcessedYet
end
print(
`{player.Name} mengirim {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Berikan pengakuan sisi pengirim atau perbarui antarmuka di sini
return Enum.ReceiptDecision.Processed
end
)
-- Tangani tanda terima penerima (pemain yang menerima 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} menerima {receiptInfo.CurrencySpent} Robux`
.. ` (TransferRequestId: {receiptInfo.TransferRequestId})`
)
-- Berikan manfaat sisi penerima atau perbarui antarmuka di sini
return Enum.ReceiptDecision.Processed
end
)GetDeveloperProductsAsync
Memberikan nilai
Contoh Kode
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
Parameter
| Nilai Default: "Asset" |
Memberikan nilai
Contoh Kode
Mendapatkan Info Produk
local MarketplaceService = game:GetService("MarketplaceService")
local ASSET_ID = 125378389
local asset = MarketplaceService:GetProductInfoAsync(ASSET_ID)
print(asset.Name .. " :: " .. asset.Description)Menampilkan Diskon Harga
local MarketplaceService = game:GetService("MarketplaceService")
local PASS_ID = 12345678
local textLabel = script.Parent
local DiscountTypeDisplay = {
RobloxPlusSubscription = "Diskon Roblox Plus",
}
local productInfo = MarketplaceService:GetProductInfoAsync(PASS_ID, Enum.InfoType.GamePass)
print(string.format("Harga Asli: %d", productInfo.UserBasePriceInRobux))
for _, discount in ipairs(productInfo.PriceDiscountDetails) do
local displayName = DiscountTypeDisplay[discount.Type] or "Diskon Lain"
print(string.format("%s (%d%%): -%d", displayName, discount.Percent, discount.AmountInRobux))
end
print(string.format("Anda Membayar: %d", productInfo.PriceInRobux))Menampilkan Pilihan Waktu yang Tersedia
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 hari - %d Robux", days, option.Price))
end
endGetRobloxSubscriptionDetailsAsync
Parameter
Memberikan nilai
Contoh Kode
Periksa Detail Langganan 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. Periksa Loyalitas (misalnya, Berlangganan selama > 60 hari)
local threeMonths = 60 * 24 * 60 * 60
if details.StartTime and (os.time() - details.StartTime.UnixTimestamp) > threeMonths then
print("Memberikan skin 'Veteran Langganan 3-Bulan'!")
end
-- 2. Periksa Atribusi
if details.IsOriginExperience then
print("Atribusi dikonfirmasi: Pengguna berlangganan melalui pengalaman ini.")
else
print("Pengguna berlangganan di tempat lain (Situs Web atau Pengalaman lain).")
end
end
end)GetSubscriptionProductInfoAsync
Parameter
Memberikan nilai
GetUsersPriceLevelsAsync
Parameter
Memberikan nilai
{PriceLevelInfo}
Contoh Kode
Dapatkan level harga untuk daftar pengguna
-- Dapatkan MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Definisikan fungsi untuk mengambil level harga untuk daftar pengguna
local function getPriceLevels(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- Pemetaan setiap PriceLevelInfo ke tabel pencarian UserId -> PriceLevel
local lookup = {}
for _, info in ipairs(result) do
lookup[info.UserId] = info.PriceLevel
end
return lookup
else
warn("Kesalahan saat mendapatkan level harga:", result)
return nil
end
end
-- Contoh menggunakan ID placeholder
local user1Id = 123456789
local user2Id = 987654321
-- Panggil fungsi dan simpan hasilnya
local priceLevels = getPriceLevels({user1Id, user2Id})
-- Jika berhasil, cetak level masing-masing pengguna
if priceLevels then
print("Level harga untuk Pengguna 1:", priceLevels[user1Id])
print("Level harga untuk Pengguna 2:", priceLevels[user2Id])
else
print("Gagal untuk mengambil level harga.")
endGetUserSubscriptionDetailsAsync
Memberikan nilai
GetUserSubscriptionPaymentHistoryAsync
Memberikan nilai
Contoh Kode
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(`Kesalahan saat memeriksa riwayat langganan: {err}`)
return
end
if next(subscriptionHistory) then
-- Pengguna memiliki beberapa riwayat langganan dalam 12 bulan terakhir.
-- Cetak rincian setiap entri pembayaran dari riwayat langganan.
print(`Pemain {player.Name} telah berlangganan {SUBSCRIPTION_ID} sebelumnya:`)
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(`Pemain {player.Name} tidak pernah berlangganan {SUBSCRIPTION_ID} sebelumnya.`)
end
end
-- Panggil checkSubscriptionHistory untuk semua pemain yang sudah ada dalam permainan
for _, player in ipairs(Players:GetPlayers()) do
checkSubscriptionHistory(player)
end
-- Panggil checkSubscriptionHistory untuk semua pemain di masa depan
Players.PlayerAdded:Connect(checkSubscriptionHistory)GetUserSubscriptionStatusAsync
Memberikan nilai
Contoh Kode
Periksa Status Langganan Pengguna
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()
-- mengembalikan IsRenewing dan IsSubscribed
subStatus = MarketplaceService:GetUserSubscriptionStatusAsync(player, subscriptionID)
end)
if not success then
warn("Kesalahan saat memeriksa apakah pemain memiliki langganan: " .. tostring(message))
return
end
if subStatus["IsSubscribed"] then
print(player.Name .. " berlangganan dengan " .. subscriptionID)
-- Berikan izin kepada pemain yang terkait dengan langganan
end
end
Players.PlayerAdded:Connect(checkSubStatus)PlayerOwnsAsset
PlayerOwnsAssetAsync
Memberikan nilai
Contoh Kode
Periksa Kepemilikan Item
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- Item yang kami periksa: 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(`Kesalahan saat memeriksa apakah {player.Name} memiliki {ASSET_NAME}: {errorMessage}`)
return
end
if doesPlayerOwnAsset then
print(`{player.Name} memiliki {ASSET_NAME}`)
else
print(`{player.Name} tidak memiliki {ASSET_NAME}`)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)PlayerOwnsBundle
PlayerOwnsBundleAsync
Memberikan nilai
Contoh Kode
Periksa Kepemilikan Bundel
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
-- Bundel yang kami periksa: 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("Panggilan PlayerOwnsBundleAsync gagal: ", doesPlayerOwnBundle)
return
end
if doesPlayerOwnBundle then
print(player.Name .. " memiliki " .. BUNDLE_NAME)
else
print(player.Name .. " tidak memiliki " .. BUNDLE_NAME)
end
end)PromptBulkPurchase
Parameter
Memberikan nilai
()
Contoh Kode
Klien Pembelian Massal Prompt
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 Pembelian Massal Prompts
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptBulkPurchaseEvent = Instance.new("RemoteEvent")
promptBulkPurchaseEvent.Name = "PromptBulkPurchaseEvent"
promptBulkPurchaseEvent.Parent = ReplicatedStorage
--Dengarkan RemoteEvent untuk dipicu dari Client dan kemudian aktifkan prompt pembelian massal
promptBulkPurchaseEvent.OnServerEvent:Connect(function(player, items)
MarketplaceService:PromptBulkPurchase(player, items, {})
end)Membeli Opsi Waktu yang Ditawarkan
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
-- Temukan opsi durasi terpendek
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(
):()
Parameter
| Nilai Default: true |
| Nilai Default: "Default" |
Memberikan nilai
()
Contoh Kode
MarketplaceService:PromptProductPurchase
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local productId = 0000000 -- Ganti ini dengan ID produk pengembang Anda
-- Fungsi untuk meminta pembelian produk pengembang
local function promptPurchase()
MarketplaceService:PromptProductPurchase(player, productId)
end
promptPurchase()PromptPurchase
MarketplaceService:PromptPurchase(
):()
Parameter
| Nilai Default: true |
| Nilai Default: "Default" |
Memberikan nilai
()
Contoh Kode
LocalScript (Klien)
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)Skrip (Server)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local promptPurchaseEvent = Instance.new("RemoteEvent")
promptPurchaseEvent.Name = "PromptPurchaseEvent"
promptPurchaseEvent.Parent = ReplicatedStorage
-- Dengarkan RemoteEvent untuk terpicu dari Klien dan kemudian aktifkan prompt pembelian
promptPurchaseEvent.OnServerEvent:Connect(function(player, id)
MarketplaceService:PromptPurchase(player, id)
end)PromptRobloxSubscriptionPurchase
Parameter
Memberikan nilai
()
Contoh Kode
Pemberitahuan Pembelian Langganan 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)
-- Berikan hadiah dan teleport pemain yang berlangganan ke area eksklusif
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
-- Deteksi bagian karakter yang menyentuh teleporter
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
-- Pemain sudah memiliki Roblox Plus; berikan hadiah segera
grantRewardAndTeleport(player)
else
-- Minta langganan Roblox Plus, dibatasi untuk sekali setiap beberapa detik
if not showModal then
return
end
showModal = false
task.delay(5, function()
showModal = true
end)
MarketplaceService:PromptRobloxSubscriptionPurchase(player)
end
end)
-- Deteksi bagian karakter yang keluar dari teleporter
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)
-- Berikan hadiah ketika server mengonfirmasi perubahan langganan
-- Hubungkan perubahan HasRobloxSubscription untuk setiap pemain
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
Memberikan nilai
Contoh Kode
MarketplaceService:PromptRobuxTransferAsync
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- Contoh: transfer Robux ketika pemain memicu RemoteEvent
local transferEvent = game.ReplicatedStorage:WaitForChild("RequestTransfer")
transferEvent.OnServerEvent:Connect(function(sender, receiverUserId, amount)
-- Validasi input
if not sender or not sender:IsA("Player") then
return
end
if typeof(receiverUserId) ~= "number" or receiverUserId <= 0 then
warn("receiverUserId tidak valid")
return
end
if typeof(amount) ~= "number" or amount <= 0 then
warn("jumlah tidak valid")
return
end
local success, result = pcall(function()
return MarketplaceService:PromptRobuxTransferAsync(sender, receiverUserId, amount)
end)
if success then
print(`Transfer dimulai dengan TransferRequestId: {result}`)
else
warn(`Transfer gagal: {result}`)
end
end)PromptSubscriptionPurchase
RankProductsAsync
Parameter
Memberikan nilai
{RankedItem}
Contoh Kode
Dapatkan daftar produk terperingkat berdasarkan ID produk yang diberikan
-- Dapatkan MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Buat array produk yang ingin Anda beri peringkat
local productIdentifiers = {
{InfoType = Enum.InfoType.GamePass, Id = 123},
{InfoType = Enum.InfoType.Product, Id = 456},
{InfoType = Enum.InfoType.Product, Id = 789}
}
-- Panggil dalam panggilan terlindungi untuk menangani kesalahan dengan baik
local success, rankedProducts = pcall(function()
return MarketplaceService:RankProductsAsync(productIdentifiers)
end)
if not success then
error("Gagal memberi peringkat produk")
end
-- Muat item yang dikembalikan ke dalam toko.
for i, rankedItem in ipairs(rankedProducts) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logika untuk menambahkan produk ke dalam toko
endRecommendTopProductsAsync
Parameter
Memberikan nilai
{RankedItem}
Contoh Kode
Dapatkan daftar terurut dari produk teratas di toko pengalaman Anda
-- Dapatkan MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- Buat array dari tipe produk yang ingin disertakan. Dalam hal ini, baik game passes maupun produk pengembang
local productTypes = {Enum.InfoType.GamePass, Enum.InfoType.Product}
-- Panggil dalam sebuah panggilan terlindungi untuk menangani error dengan baik
local success, topRankedItems = pcall(function()
return MarketplaceService:RecommendTopProductsAsync(productTypes)
end)
if not success then
error("Gagal untuk mengurutkan produk")
end
-- Muat item yang dikembalikan ke dalam toko. Pastikan untuk memfilter item yang tidak memenuhi syarat dari topRankedItems seperti produk pengembang yang tidak dapat lagi dibeli pengguna
for i, rankedItem in ipairs(topRankedItems) do
local productIdentifier = rankedItem.ProductIdentifier
local productInfo = rankedItem.ProductInfo
-- ...
-- Logika untuk menambahkan produk ke dalam toko
endAcara
PromptBulkPurchaseFinished
MarketplaceService.PromptBulkPurchaseFinished(
Parameter
PromptBundlePurchaseFinished
PromptGamePassPurchaseFinished
MarketplaceService.PromptGamePassPurchaseFinished(
Contoh Kode
Menangani Penyelesaian Pembelian Gamepass
local MarketplaceService = game:GetService("MarketplaceService")
local function gamepassPurchaseFinished(...)
-- Cetak semua detail dari prompt, misalnya:
-- PromptGamePassPurchaseFinished PlayerName 123456 false
print("PromptGamePassPurchaseFinished", ...)
end
MarketplaceService.PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)PromptProductPurchaseFinished
PromptPurchaseFinished
MarketplaceService.PromptPurchaseFinished(
Contoh Kode
Menangani Acara PromptPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptPurchaseFinished(player, assetId, isPurchased)
if isPurchased then
print(player.Name, "membeli item dengan AssetID:", assetId)
else
print(player.Name, "tidak membeli item dengan AssetID:", assetId)
end
end
MarketplaceService.PromptPurchaseFinished:Connect(onPromptPurchaseFinished)PromptRobloxSubscriptionPurchaseFinished
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished(
Contoh Kode
Menangani Event PromptRobloxSubscriptionPurchaseFinished
local MarketplaceService = game:GetService("MarketplaceService")
local function onPromptRobloxSubscriptionPurchaseFinished(player, didTryPurchasing)
if didTryPurchasing then
-- Pemain mencoba untuk berlangganan; tunggu perubahan HasRobloxSubscription untuk mengonfirmasi
print(player.Name, "mencoba untuk berlangganan ke Roblox Plus")
else
print(player.Name, "menutup prompt langganan Roblox Plus tanpa membeli")
end
end
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished:Connect(onPromptRobloxSubscriptionPurchaseFinished)Callback
ProcessReceipt
Parameter
Memberikan nilai
Contoh Kode
Panggilan Callback ProsesPenerimaan
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
-- Pengaturan data store untuk melacak pembelian yang telah berhasil diproses
local purchaseHistoryStore = DataStoreService:GetDataStore("PurchaseHistory")
local productIdByName = {
fullHeal = 123123,
gold100 = 456456,
}
-- Sebuah kamus untuk mencari fungsi pengolah untuk memberikan pembelian yang sesuai dengan ID produk
-- Fungsi-fungsi ini mengembalikan true jika pembelian berhasil diberikan
-- Fungsi-fungsi ini tidak boleh pernah yield karena mereka dipanggil di dalam callback UpdateAsync()
local grantPurchaseHandlerByProductId = {
[productIdByName.fullHeal] = function(_receipt, player)
local character = player.Character
local humanoid = character and character:FindFirstChild("Humanoid")
-- Pastikan pemain memiliki humanoid untuk disembuhkan
if not humanoid then
return false
end
-- Sembuhkan pemain sampai penuh
humanoid.Health = humanoid.MaxHealth
-- Indikasikan keberhasilan pemberian
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
-- Tambahkan 100 emas ke statistik emas pemain
goldStat.Value += 100
-- Indikasikan keberhasilan pemberian
return true
end,
}
-- Fungsi callback ProsesPenerimaan inti
-- Implementasi ini menangani sebagian besar skenario kegagalan tetapi tidak sepenuhnya mengurangi skenario kegagalan data lintas server
local function processReceipt(receiptInfo)
local success, result = pcall(
purchaseHistoryStore.UpdateAsync,
purchaseHistoryStore,
receiptInfo.PurchaseId,
function(isPurchased)
if isPurchased then
-- Pembelian ini sudah dicatat sebagai diberikan, jadi pasti sudah ditangani sebelumnya
-- Hindari memanggil pengolah pemberian pembelian di sini untuk mencegah pemberian pembelian dua kali
-- Karena nilai di data store sudah true, true dikembalikan lagi sehingga variabel hasil pcall juga true
-- Ini akan digunakan nanti untuk mengembalikan PurchaseGranted dari pengolah tanda terima
return true
end
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
-- Menghindari pemberian pembelian jika pemain tidak ada di server
-- Ketika mereka bergabung kembali, pengolah tanda terima ini akan dipanggil lagi
return nil
end
local grantPurchaseHandler = grantPurchaseHandlerByProductId[receiptInfo.ProductId]
if not grantPurchaseHandler then
-- Jika tidak ada pengolah yang ditentukan untuk ID produk ini, pembelian tidak dapat diproses
-- Ini tidak akan pernah terjadi selama setiap ID produk yang dijual dalam pengalaman ini memiliki pengolah
warn(`Tidak ada pengolah pembelian yang ditentukan untuk ID produk '{receiptInfo.ProductId}'`)
return nil
end
local handlerSucceeded, handlerResult = pcall(grantPurchaseHandler, receiptInfo, player)
if not handlerSucceeded then
local errorMessage = handlerResult
warn(
`Pengolah pemberian pembelian mengalami kesalahan saat memproses pembelian dari '{player.Name}' untuk ID produk '{receiptInfo.ProductId}': {errorMessage}`
)
return nil
end
local didHandlerGrantPurchase = handlerResult == true
if not didHandlerGrantPurchase then
-- Pengolah tidak memberikan pembelian, jadi catat sebagai tidak diberikan
return nil
end
-- Pembelian sekarang diberikan kepada pemain, jadi catat sebagai diberikan
-- Ini akan digunakan nanti untuk mengembalikan PurchaseGranted dari pengolah tanda terima
return true
end
)
if not success then
local errorMessage = result
warn(`Gagal memproses tanda terima karena kesalahan data store: {errorMessage}`)
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local didGrantPurchase = result == true
return if didGrantPurchase
then Enum.ProductPurchaseDecision.PurchaseGranted
else Enum.ProductPurchaseDecision.NotProcessedYet
end
-- Atur callback; ini hanya dapat dilakukan sekali oleh satu skrip di server
MarketplaceService.ProcessReceipt = processReceipt