Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.
MarketplaceService
Inherits from: Instance → Object
MarketplaceService is responsible for in-experience transactions. The most notable methods are PromptProductPurchase and PromptPurchase, as well as the callback ProcessReceipt which must be defined so that developer product transactions do not fail. BindReceiptHandler is a newer alternative that processes developer product receipts (and Robux transfer receipts) through one or more bound handlers instead of the single ProcessReceipt callback.
MarketplaceService also has methods that fetch information about developer products (GetProductInfoAsync and GetDeveloperProductsAsync), passes (UserOwnsGamePassAsync()), and other assets (PlayerOwnsAssetAsync, PlayerOwnsBundleAsync).
Understanding MarketplaceService is the first step towards learning to monetize an experience on Roblox, as well as learning to use DataStoreService, which is responsible for saving and loading all data related to purchases.
Inherits from: Instance
Memory category: Instances
Tags: NotCreatable, Service
Methods
| Name | Type / Returns | Description |
|---|---|---|
| MarketplaceService:BindReceiptHandler | RBXScriptConnection | Registers a callback to process receipts of a specific type. |
| MarketplaceService:GetDeveloperProductsAsync | Instance | Returns a Pages object which contains information for all of the current experience's developer products. |
| MarketplaceService:GetProductInfo | Dictionary | Returns the product information of an asset using its asset ID. |
| MarketplaceService:GetProductInfoAsync | Dictionary | Returns the product information of an asset using its asset ID. |
| MarketplaceService:GetRobloxSubscriptionDetailsAsync | Dictionary | Returns the subscription details for the given user for the Roblox Subscription ecosystem. |
| MarketplaceService:GetSubscriptionProductInfoAsync | Dictionary | Returns the product information of a subscription for the given subscriptionId. |
| MarketplaceService:GetUsersPriceLevelsAsync | List | Returns the regionalized price levels of users, representing the recommended price for an item in each user's regional market. |
| MarketplaceService:GetUserSubscriptionDetailsAsync | Dictionary | Returns a table that contains the details of the user's subscription for a given subscriptionId. |
| MarketplaceService:GetUserSubscriptionPaymentHistoryAsync | Array | Returns an Array that contains up to one year of the user's subscription payment history for the given subscriptionId. |
| MarketplaceService:GetUserSubscriptionStatusAsync | Dictionary | Returns a table that contains the subscription status of the user for the given subscriptionId. |
| MarketplaceService:OpenShop | () | Opens a personalized in-game Shop for the given player. |
| MarketplaceService:PlayerOwnsAsset | boolean | Returns whether the given user has the given asset. |
| MarketplaceService:PlayerOwnsAssetAsync | boolean | Returns whether the given user has the given asset. |
| MarketplaceService:PlayerOwnsBundle | boolean | Returns whether the given player owns the given bundle. |
| MarketplaceService:PlayerOwnsBundleAsync | boolean | Returns whether the given player owns the given bundle. |
| MarketplaceService:PromptBulkPurchase | () | Prompts a user to purchase multiple avatar items with the given assetId or bundleId. |
| MarketplaceService:PromptBundlePurchase | () | Prompts a user to purchase a bundle with the given bundleId. |
| MarketplaceService:PromptCancelSubscription | () | Prompts a user to cancel a subscription for the given subscriptionId. |
| MarketplaceService:PromptGamePassPurchase | () | Prompts a user to purchase a pass with the given gamePassId. |
| MarketplaceService:PromptPremiumPurchase | () | Prompts a user to purchase Roblox Premium. |
| MarketplaceService:PromptProductPurchase | () | Prompts a user to purchase a developer product with the given productId. |
| MarketplaceService:PromptPurchase | () | Prompts a user to purchase an item with the given assetId. Does not work for USD Creator Store purchases. |
| MarketplaceService:PromptRobloxSubscriptionPurchase | () | Prompts a user to purchase a Roblox Plus subscription. |
| MarketplaceService:PromptRobuxTransferAsync | string | Initiates a Robux transfer from the sender to another user. |
| MarketplaceService:PromptSubscriptionPurchase | () | Prompts a user to purchase a subscription for the given subscriptionId. |
| MarketplaceService:RankProductsAsync | List | Takes a list of product IDs and returns a personalized ordered list of those products. |
| MarketplaceService:RecommendTopProductsAsync | List | - Takes an array of InfoType and returns up to 50 items representing the products a user is most likely to engage with and purchase. |
| MarketplaceService:UserOwnsGamePassAsync | boolean | Returns true if the player with the given UserId owns the pass with the given gamePassId. |
Inherited from Instance
| Name | Type / Returns | Description |
|---|---|---|
| Instance:AddTag | () | Applies a tag to the instance. |
| Instance:children | Instances | Returns an array of the object's children. |
| Instance:ClearAllChildren | () | This method destroys all of an instance's children. |
| Instance:Clone | Instance | Create a copy of an instance and all its descendants, ignoring instances that are not Archivable. |
| Instance:clone | Instance | |
| Instance:Destroy | () | Sets the Instance.Parent property to nil, locks the Instance.Parent property, disconnects all connections, and calls Destroy() on all children. |
| Instance:destroy | () | |
| Instance:FindFirstAncestor | Instance? | Returns the first ancestor of the Instance whose Instance.Name is equal to the given name. |
| Instance:FindFirstAncestorOfClass | Instance? | Returns the first ancestor of the Instance whose Object.ClassName is equal to the given className. |
| Instance:FindFirstAncestorWhichIsA | Instance? | Returns the first ancestor of the Instance for whom Object:IsA() returns true for the given className. |
| Instance:FindFirstChild | Instance? | Returns the first child of the Instance found with the given name. |
| Instance:findFirstChild | Instance | |
| Instance:FindFirstChildOfClass | Instance? | Returns the first child of the Instance whose ClassName is equal to the given class name. |
| Instance:FindFirstChildWhichIsA | Instance? | Returns the first child of the Instance for whom Object:IsA() returns true for the given className. |
| Instance:FindFirstDescendant | Instance? | Returns the first descendant found with the given Instance.Name. |
| Instance:GetActor | Actor? | Returns the Actor associated with the Instance, if any. |
| Instance:GetAttribute | Variant | Returns the value which has been assigned to the given attribute name. |
| Instance:GetAttributeChangedSignal | RBXScriptSignal | Returns an event that fires when the given attribute changes. |
| Instance:GetAttributes | Dictionary | Returns a dictionary of the instance's attributes. |
| Instance:GetChildren | Instances | Returns an array containing all of the instance's children. |
| Instance:getChildren | Instances | |
| Instance:GetDebugId | string | Returns a coded string of the debug ID used internally by Roblox. |
| Instance:GetDescendants | Instances | Returns an array containing all of the descendants of the instance. |
| Instance:GetFullName | string | Returns a string describing the instance's ancestry. |
| Instance:GetStyled | Variant | Returns the styled or explicitly modified value of the specified property, or else the default property value if it hasn't been styled/modified. |
| Instance:GetStyledPropertyChangedSignal | RBXScriptSignal | Returns an event that fires when the given style property changes on the instance. |
| Instance:GetTags | Array | Gets an array of all tags applied to the instance. |
| Instance:HasTag | boolean | Check whether the instance has a given tag. |
| Instance:IsAncestorOf | boolean | Returns true if an Instance is an ancestor of the given descendant. |
| Instance:IsDescendantOf | boolean | Returns true if an Instance is a descendant of the given ancestor. |
| Instance:isDescendantOf | boolean | |
| Instance:IsPropertyModified | boolean | Returns true if the value stored in the specified property is not equal to the code-instantiated default. |
| Instance:QueryDescendants | Instances | Returns an array containing all descendants of the instance that match the selector string. |
| Instance:Remove | () | Sets the object's Parent to nil, and does the same for all its descendants. |
| Instance:remove | () | |
| Instance:RemoveTag | () | Removes a tag from the instance. |
| Instance:ResetPropertyToDefault | () | Resets a property to its default value. |
| Instance:SetAttribute | () | Sets the attribute with the given name to the given value. |
| Instance:WaitForChild | Instance | Returns the child of the Instance with the given name. If the child does not exist, it will yield the current thread until it does. |
Inherited from Object
| Name | Type / Returns | Description |
|---|---|---|
| Object:GetPropertyChangedSignal | RBXScriptSignal | Get an event that fires when a given property of the object changes. |
| Object:IsA | boolean | Returns true if an object's class matches or inherits from a given class. |
| Object:isA | boolean |
MarketplaceService:BindReceiptHandler
BindReceiptHandler registers a callback to process receipts of a specific ReceiptType. You can use it to handle developer product receipts (ReceiptType.DeveloperProduct) and Robux transfer receipts (ReceiptType.RobuxTransferSender and ReceiptType.RobuxTransferReceiver).
For ReceiptType.DeveloperProduct, you can register handlers in two ways:
- Filtered — Pass a
filterarray of developer product IDs so the handler only fires for receipts whoseProductIdis in that array. Use this to route specific products to dedicated handlers. - Catch-all — Omit
filterso the handler fires for any developer product receipt not already claimed by a filtered handler.
For developer products, BindReceiptHandler is an alternative to the legacy ProcessReceipt callback. A bound handler takes precedence; if no bound handler matches a developer product receipt, it falls through to ProcessReceipt. This lets you adopt BindReceiptHandler incrementally without removing an existing ProcessReceipt callback.
The handler callback receives a receipt info dictionary and must return an ReceiptDecision value:
ReceiptDecision.Processed— Indicates the receipt was successfully processed and all benefits have been granted. The receipt is marked as complete.ReceiptDecision.NotProcessedYet— Indicates the receipt has not been processed yet. The receipt remains unresolved and will be delivered again on the next opportunity.
Receipt Info Dictionary
The receipt info dictionary passed to the handler contains the following fields:
| Key | Type | Description |
|---|---|---|
PurchaseId | string | A unique identifier for this specific receipt. |
PlayerId | number | The Class.Player.UserId of the user associated with this receipt. |
PlaceIdWherePurchased | number | The place ID where the transaction was initiated. |
ReceiptType | Enum.ReceiptType | The type of this receipt. |
ProductId | number | The developer product ID. Only present for Enum.ReceiptType.DeveloperProduct receipts. |
CurrencyType | Enum.CurrencyType | The currency used for the purchase. Only present for Enum.ReceiptType.DeveloperProduct receipts. |
CurrencySpent | number | The amount of Robux involved in the transaction. For Enum.ReceiptType.DeveloperProduct receipts, this is the product's price. For Enum.ReceiptType.RobuxTransferSender receipts, this is the amount sent. For Enum.ReceiptType.RobuxTransferReceiver receipts, this is the amount received. |
TransferRequestId | string | The transfer request ID from Class.MarketplaceService:PromptRobuxTransferAsync(). Only present for Enum.ReceiptType.RobuxTransferSender and Enum.ReceiptType.RobuxTransferReceiver receipts. |
Receipt Timing
For Robux transfer receipts, handler is invoked once the transfer settles. A settled receipt is delivered to whichever server the user is currently in (the user does not need to rejoin).
ReceiptType.RobuxTransferReceiver— Delivered to the server the receiver is currently in once the transfer settles. If the receiver is offline at that time, delivery happens the next time they join a server.ReceiptType.RobuxTransferSender— Delivered immediately if the transfer settles synchronously. If the transfer is gated on receiver approval (for example, parental consent), delivery happens once the receiver accepts, to whichever server the sender is currently in or on their next join if they are offline.
For developer product receipts, handler is invoked when the purchase completes while the buyer is on a server. If the handler returns ReceiptDecision.NotProcessedYet, or the buyer is not reachable, the receipt remains unresolved and is redelivered on a later opportunity or the next time the buyer joins a server.
The user must be on a server for handler to fire.
Errors
This method throws an error if:
- A handler is already registered for the same
ReceiptTypeand product ID combination. - A catch-all handler is already registered for the same
ReceiptType.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| transactionType | ReceiptType | The ReceiptType indicating which kind of receipt to handle. | |
| handler | Function | A callback function that receives a receipt info dictionary and must return an ReceiptDecision value. | |
| filter | Array? | An optional array of product IDs. When provided, the handler only fires for receipts matching those product IDs. Not supported for RobuxTransferSender or RobuxTransferReceiver receipt types. |
Returns
| Type | Description |
|---|---|
| RBXScriptConnection | A RBXScriptConnection that can be disconnected to unregister the handler. |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
Code samples: View on Creator Hub (MarketplaceService-BindReceiptHandler1, MarketplaceService-BindReceiptHandler2).
MarketplaceService:GetDeveloperProductsAsync
Returns a Pages object which contains information for all of the current experience's developer products.
Returns
| Type | Description |
|---|---|
| Instance | A Pages object whose entries describe the current experience's developer products. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
Code samples: View on Creator Hub (MarketplaceService-GetDeveloperProductsAsync1).
MarketplaceService:GetProductInfo
Deprecated. This method has been superseded by GetProductInfoAsync().
Returns the product information of an asset using its asset ID.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| assetId | int64 | The asset ID of the specified product. | |
| infoType | InfoType | Asset | An InfoType enum value specifying the type of information being retrieved. |
Returns
| Type | Description |
|---|---|
| Dictionary | A dictionary containing information about the queried item, described in the previous tables. |
| Field | Value |
|---|---|
| tags | ["Yields","Deprecated"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
Code samples: View on Creator Hub (MarketplaceService-GetProductInfo1).
MarketplaceService:GetProductInfoAsync
This method provides information about an asset, developer product, or pass based on the asset ID and the InfoType. If an item with the given ID does not exist, this method throws an error.
Information about the queried item is provided in a dictionary with the following keys. Note that not all information is provided or necessarily relevant for the kind of product you're querying.
| Key | Type | Description |
|---|---|---|
Name | string | The name shown on the asset's page. |
Description | string | The description shown on the asset's page; can be nil if blank. |
PriceInRobux | number | The cost of purchasing the asset using Robux. |
UserBasePriceInRobux | number | The base price of the asset in Robux before any discounts are applied. |
PriceDiscountDetails | Array | An ordered list of discounts representing the difference between UserBasePriceInRobux and PriceInRobux. Each entry contains the following keys: |
Type: The type of discount. "RobloxPlusSubscription" indicates that the discount was applied due to the user’s Roblox Plus subscription. | ||
AmountInRobux: number — The value of the discount in Robux. | ||
Percent: number — The percentage of the discount. | ||
ProductId | number | The product ID if Enum.InfoType is Product. |
ProductType | string | A string describing what the product is. Not to be confused with Enum.MarketplaceProductType. |
Created | string | Timestamp of when the asset was created, for example 2022-01-02T10:30:45Z. Formatted using ISO 8601. |
Updated | string | Timestamp of when the asset was last updated by its creator, for example 2022-02-12T11:22:15Z. Formatted using ISO 8601. |
ContentRatingTypeId | number | Indicates whether the item is marked as 13+ in catalog. |
MinimumMembershipLevel | number | The minimum subscription level necessary to purchase the item. |
IsPublicDomain | boolean | Describes whether the asset can be taken for free. |
TargetId | number | The ID of the product or asset. |
Creator Information
| Key | Type | Description |
|---|---|---|
Creator | table | Dictionary table of information describing the creator of the asset, containing the following fields: |
CreatorType: Either User or Group. | ||
CreatorTargetId: The ID of the creator user or group. | ||
HasVerifiedBadge: Boolean of whether the creator has a verified badge. | ||
Name: The name/username of the creator. | ||
Id: Use CreatorTargetId instead. | ||
Asset Information
| Key | Type | Description |
|---|---|---|
AssetId | number | The asset ID if Enum.InfoType is Asset. |
AssetTypeId | number | The type of asset. See Enum.AssetType for the asset type ID numbers. |
IconImageAssetId | number | The asset ID of the product's icon, or 0 if there isn't one. |
IsForSale | boolean | Describes whether the asset is purchasable. |
IsLimited | boolean | Describes whether the asset is a Roblox Limited that is no longer (if ever) sold. |
IsLimitedUnique | boolean | Describes whether the asset is a unique Roblox Limited ("Limited U") item that only has a fixed number sold. |
IsNew | boolean | Describes whether the asset is marked as "new" in the catalog. |
Remaining | number | The remaining number of times a limited unique item may be sold. |
Sales | number | The number of times the asset has been sold. |
Collectibles Information
| Key | Type | Description |
|---|---|---|
CollectibleItemId | string | The unique item ID of the collectible. |
CollectibleProductId | string | The unique product ID of the collectible. |
CollectiblesItemDetails | table | Dictionary table of information describing the collectible, containing the following fields: |
CollectibleLowestAvailableResaleItemInstanceId: The unique item instance ID of the lowest available resale for the collectible. | ||
CollectibleLowestAvailableResaleProductId: The unique product ID of the lowest available resale for the collectible. | ||
CollectibleLowestResalePrice: The lowest resale price for the collectible in Robux. | ||
IsForSale: Boolean of whether the collectible is available for sale (not resale). | ||
IsLimited: Boolean of whether or not the collectible is limited. | ||
TotalQuantity: The total quantity of the collectible available for purchase (not resale). | ||
Sale Location Settings
| Key | Type | Description |
|---|---|---|
CanBeSoldInThisGame | boolean | Describes whether the asset is purchasable in the current experience. |
SaleLocation | table | Dictionary table of information describing where the item can be sold, containing the following fields: |
SaleLocationType: The type of sale location setting. See Enum.ProductLocationRestriction for the sale location setting ID numbers. | ||
UniverseIds: Array table of universes in which the item can be sold (not currently implemented). | ||
Timed Options
| Key | Type | Description |
|---|---|---|
TimedOptions | array | Optional. An array of available timed options with durations and prices. Only present for assets that support timed ownership. Do not hardcode duration values; always retrieve them from this API as they may change. Each entry contains: |
Duration: number — The duration in seconds (e.g. 259200 for 3 days, 604800 for 7 days). | ||
Price: number — The price in Robux for this duration. | ||
Batching behavior
This method is Transparent Batching capable. If you spawn multiple calls concurrently using task.spawn, the engine automatically combines them into fewer HTTP requests behind the scenes. This is faster and helps you avoid rate limits. See Transparent Batching for details and a code example.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| assetId | int64 | The asset ID of the specified product. | |
| infoType | InfoType | Asset | An InfoType enum value specifying the type of information being retrieved. |
Returns
| Type | Description |
|---|---|
| Dictionary | A dictionary containing information about the queried item, described in the previous tables. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
Code samples: View on Creator Hub (MarketplaceService-GetProductInfo1, MarketplaceService-GetProductInfo2, MarketplaceService-GetProductInfo-TimedOptions, MarketplaceService-GetProductInfo-TransparentBatching).
MarketplaceService:GetRobloxSubscriptionDetailsAsync
This method is a streamlined endpoint to check for a single, platform-wide Roblox subscription product. By providing StartTime (conditionally) and IsOriginExperience to reward long-term loyalists without compromising user data across the platform.
The returned dictionary contains the following fields:
| Field | Type | Description |
|---|---|---|
IsSubscribed | bool | Returns true if the user has an active Roblox Subscription membership. |
IsOriginExperience | bool | Returns true if the user originally subscribed to Roblox Subscription while inside the current Experience (Universe). |
StartTime | DateTime? | A Datatype.DateTime object representing the time when the user’s subscription period first began. Note: For privacy reasons, this field is only returned if IsOriginExperience is true. If the user subscribed in a different experience or on the web, this field will be nil. |
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The user regarding whom to check the subscription status. |
Returns
| Type | Description |
|---|---|
| Dictionary | A dictionary containing subscription details such as IsSubscribed, IsOriginExperience, and optionally StartTime. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
Code samples: View on Creator Hub (MarketplaceService-GetRobloxSubscriptionDetailsAsync1).
MarketplaceService:GetSubscriptionProductInfoAsync
Returns the product information of a subscription for the given subscriptionId. Because it returns a localized price, you can only call this method from a Script with RunContext.Client.
| Key | Type | Description |
|---|---|---|
Name | string | The name of the subscription product. |
Description | string | The description of the subscription product. |
IconImageAssetId | number | The asset ID of the subscription product icon. |
SubscriptionPeriod | Enum.SubscriptionPeriod | The duration of the subscription (for example, Month, Year, etc.). |
DisplayPrice | string | Localized price with the appropriate currency symbol for display (for example, $4.99). For users in unsupported countries, DisplayPrice returns a string without specific price information. |
DisplaySubscriptionPeriod | string | Localized subscription period text for display (for example, /month). Can be used together with DisplayPrice. |
SubscriptionProviderName | string | Name of the subscription benefit provider (for example, the name of the associated experience). |
IsForSale | boolean | True if the subscription product is available for sale. |
PriceTier | number | A number that can be used to compare the price of different subscription products. This is not the actual price of the subscription (for example, 499). |
PriceInRobux | number | The equivalent cost of the subscription in Robux. Returns 0 if the subscription product is not available to be purchased in Robux. |
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| subscriptionId | string | The ID of the subscription to check. |
Returns
| Type | Description |
|---|---|
| Dictionary | A dictionary containing the subscription product information described in the following table. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
MarketplaceService:GetUsersPriceLevelsAsync
Returns the regionalized price levels of users, representing the recommended price for an item in each user's regional market. For example, a price level of 100 means that the suggested price for that user (based on their region and purchasing power) is 100 Robux.
See Protect your trades and gifts for more information.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| userIds | Array | An array of user IDs. |
Returns
| Type | Description |
|---|---|
| List | Returns an array of PriceLevelInfo objects with a dictionary where the keys are user IDs (strings) and their values are the corresponding price levels (integers between 1 and 1000). |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
Code samples: View on Creator Hub (MarketplaceService-GetUsersPriceLevelAsync).
MarketplaceService:GetUserSubscriptionDetailsAsync
Returns a dictionary table containing the details of the user's subscription for the given subscriptionId. The table contains the following keys:
| Key | Type | Description |
|---|---|---|
SubscriptionState | Enum.SubscriptionState | Current state of this particular subscription. |
NextRenewTime | Datatype.DateTime | Renewal time for this current subscription. May be in the past if the subscription is in Enum.SubscriptionState.SubscribedRenewalPaymentPending|SubscribedRenewalPaymentPending state. This field is will be nil if the subscription will not renew, is Enum.SubscriptionState.Expired|Expired, or the user never subscribed. |
ExpireTime | Datatype.DateTime | When this subscription expires. This field will be nil if the subscription is not cancelled or the user never subscribed. |
ExpirationDetails | Library.table | Table containing the details of the subscription expiration. This field will be nil if the subscription is not in the Enum.SubscriptionState.Expired|Expired state. If populated, the table contains a ExpirationReason key of type Enum.SubscriptionExpirationReason describing why the subscription is expired. |
Note that this method can only be called from a Script with RunContext of Server. If you only need to determine the IsSubscribed status of a user, it's recommended to use GetUserSubscriptionStatusAsync as it is faster and more efficient for that particular purpose.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player object whose subscription details you want to check. | |
| subscriptionId | string | The ID of the subscription to check. |
Returns
| Type | Description |
|---|---|
| Dictionary | A dictionary containing the user's subscription details described in the following table. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
MarketplaceService:GetUserSubscriptionPaymentHistoryAsync
Returns an Array that contains up to one year of the user's subscription payment history for the given subscriptionId, sorted from the most recent status to the least recent. You can only call this method from a Script with RunContext.Server.
Each entry in the payment history Array contains the following keys:
| Key | Type | Description |
|---|---|---|
CycleStartTime | Datatype.DateTime | Datatype.DateTime at the start of this particular subscription period. |
CycleEndTime | Datatype.DateTime | Datatype.DateTime at the end of this particular subscription period. |
PaymentStatus | Enum.SubscriptionPaymentStatus | Enum.SubscriptionPaymentStatus.Paid if the user paid for this particular subscription period. Enum.SubscriptionPaymentStatus.Refunded if the user refunded this particular subscription period. |
Payment History Length
Only creators affiliated with the subscription product can access up to one year worth of the user's subscription payment history. Non-associated creators can only get the user's current subscription payment status or an empty Array if the user has no active subscription.
Grace Period
Subscription renewal payments can have some processing time. Payment history doesn't return a table for this period. However, in order to preserve a user's subscription experience during the processing period, GetUserSubscriptionStatusAsync returns IsSubscribed: true for the given user. Don't grant durable items or currency type subscription benefits to the user until after payment has been confirmed for the current cycle.
For example, on August 31, 2023, User A's Subscription B is up for renewal. On September 1, 2023, the payment has yet to be processed. If you call GetUserSubscriptionPaymentHistoryAsync on September 1, 2023 on User A for Subscription B, the first entry of the return value is:
| Key | Value |
|---|---|
CycleStartTime | ... |
CycleEndTime | August 31, 2023 |
PaymentStatus | Enum.SubscriptionPaymentStatus.Paid |
Note that since the user is within the grace period, the cycle they have yet to pay for (September 1, 2023) does not appear in the return value at all. This field only populates after the payment has been received and processed.
At the same time, GetUserSubscriptionStatusAsync returns the following result until the renewal payment process fails or the user cancels:
| Key | Return |
|---|---|
IsSubscribed | True |
IsRenewing | True |
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player whose subscription payment history you want to retrieve. | |
| subscriptionId | string | The ID of the subscription whose payment history you want to retrieve. |
Returns
| Type | Description |
|---|---|
| Array | An array of payment-history entries, ordered from most recent to least recent, as described in the following table. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
Code samples: View on Creator Hub (MarketplaceService-GetUserSubscriptionPaymentHistoryAsync1).
MarketplaceService:GetUserSubscriptionStatusAsync
Returns a table that contains the subscription status of the user for the given subscriptionId. The table contains the following keys:
| Key | Type | Description |
|---|---|---|
IsSubscribed | boolean | True if the user's subscription is active. |
IsRenewing | boolean | True if the user is set to renew this subscription after the current subscription period ends. |
Note that IsSubscribed will be true only when a user has purchased the subscription and the payment has been successfully processed. If the payment for a user's initial subscription purchase is still processing or has failed, IsSubscribed returns false. To understand when a user's subscription status has changed, see the Players.UserSubscriptionStatusChanged event.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player object whose subscription status you want to check. | |
| subscriptionId | string | The ID of the subscription to check for. |
Returns
| Type | Description |
|---|---|
| Dictionary | A dictionary containing the user's subscription status described in the following table. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
Code samples: View on Creator Hub (MarketplaceService-GetUserSubscriptionStatusAsync1).
MarketplaceService:OpenShop
Opens an in-game Shop as an overlay window for the given Player. Shop displays a personalized list of the experience's passes and developer products ranked for the user.
A default Shop is generated automatically for every game and requires no additional developer setup. You can customize which items appear in the shop from Creator Hub.
This method can be called from either a server Script or a LocalScript. When called from a LocalScript, player must match the local player.
You can call this method in response to any user action, such as a button click, the player reaching a specific location, or joining the experience.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Player | The Player for whom to open the shop. If called from a LocalScript, this must be the local player. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-OpenShop).
MarketplaceService:PlayerOwnsAsset
Deprecated. This method has been superseded by PlayerOwnsAssetAsync().
Returns whether the given user has the given asset.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player whose inventory is tested for ownership of the given asset. | |
| assetId | int64 | The asset ID for which the given player's inventory is tested. |
Returns
| Type | Description |
|---|---|
| boolean | Indicates whether the given player's inventory contains the given asset. |
| Field | Value |
|---|---|
| tags | ["Yields","Deprecated"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
MarketplaceService:PlayerOwnsAssetAsync
Returns whether the inventory of a specific user contains an asset, based on the asset ID. This method throws an error if the query fails, so you should wrap calls to this method in pcall().
- This method should not be used for passes since they use a separate ID system. Legacy passes that still depend on an asset ID should use
UserOwnsGamePassAsync()instead of this method. - This method cannot be used to check for developer products since they can be purchased multiple times but not owned themselves. Instead, use a data store to save when a user buys a developer product.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player whose inventory is tested for ownership of the given asset. | |
| assetId | int64 | The asset ID for which the given player's inventory is tested. |
Returns
| Type | Description |
|---|---|
| boolean | Indicates whether the given player's inventory contains the given asset. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
Code samples: View on Creator Hub (MarketplaceService-PlayerOwnsAsset1).
MarketplaceService:PlayerOwnsBundle
Deprecated. This method has been superseded by PlayerOwnsBundleAsync().
Returns whether the given player owns the given bundle.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Player | The Player whose inventory is tested for ownership of the given bundle. | |
| bundleId | int64 | The bundle ID for which the given player's inventory is tested. |
Returns
| Type | Description |
|---|---|
| boolean | Indicates whether the given player's inventory contains the given bundle. |
| Field | Value |
|---|---|
| tags | ["Yields","Deprecated"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
MarketplaceService:PlayerOwnsBundleAsync
Returns whether the inventory of a specific user contains a bundle, based on the bundle ID. This method throws an error if the query fails, so you should wrap calls to this method in pcall().
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Player | The Player whose inventory is tested for ownership of the given bundle. | |
| bundleId | int64 | The bundle ID for which the given player's inventory is tested. |
Returns
| Type | Description |
|---|---|
| boolean | Indicates whether the given player's inventory contains the given bundle. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
Code samples: View on Creator Hub (MarketplaceService-PlayerOwnsBundle1).
MarketplaceService:PromptBulkPurchase
Prompts a user to purchase multiple avatar items with the given assetId or bundleId. Does not work with non-avatar items.
PromptBulkPurchase only allows prompting from server scripts.
For limited items, original copies are prompted until they run out, regardless of the price. Once original copies are out, resale copies are prompted.
A maximum of 20 items can be added to a single bulk purchase prompt.
PurchaseOptions
Each line item can optionally include a PurchaseOptions array to control which purchase option appears in the prompt. If omitted, the user is prompted for a permanent purchase only (default behavior).
PurchaseOptions currently supports only one entry. If more than one option is provided, the API throws an error.
Each entry in PurchaseOptions contains:
| Key | Type | Description |
|---|---|---|
Type | Enum | Enum.PurchaseOption.TimedOption for a timed option, or Enum.PurchaseOption.Permanent for standard purchase. |
Value | number | Required for TimedOption. The duration in seconds. |
Do not hardcode duration values. Available durations and prices are determined by the backend and may change at any time. Always retrieve them from one of the following APIs and pass the values through to PurchaseOptions:
MarketplaceService:GetProductInfoAsync()AvatarEditorService:GetItemDetailsAsync()AvatarEditorService:GetBatchItemDetailsAsync()AvatarEditorService:SearchCatalogAsync()
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Player | The user to prompt to purchase items. | |
| lineItems | Array | An array of avatar items to be included in the bulk purchase. Each line item contains the following structure: lua { Type: MarketplaceProductType, Id: string, PurchaseOptions: { {Type: PurchaseOption, Value: number?} }? } Each line item contains the following pairs: - Type: The corresponding MarketplaceProductType (Enum). - Id: The ID of the asset or bundle. - PurchaseOptions: Optional. An array containing a single purchase option to display in the prompt. If omitted, the permanent purchase is prompted. See the PurchaseOptions section below for details. | |
| options | Dictionary | Not available at this time. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (Prompt-Bulk-Purchase-Local, Prompt-Bulk-Purchase-Server, MarketplaceService-PromptBulkPurchase-TimedOptions).
MarketplaceService:PromptBundlePurchase
Prompts a user to purchase a bundle with the given bundleId.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player to prompt. | |
| bundleId | int64 | The ID of the bundle to purchase. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService:PromptCancelSubscription
Prompts a user to cancel a subscription for the given subscriptionId. Once the user successfully cancels the subscription, the Players.UserSubscriptionStatusChanged event fires.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player to prompt. | |
| subscriptionId | string | The ID of the subscription to cancel. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService:PromptGamePassPurchase
Prompts a user to purchase a pass with the given gamePassId.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player to prompt. | |
| gamePassId | int64 | The pass ID to purchase. This is the TargetId returned by GetProductInfo() when InfoType is GamePass. It is not the pass's asset ID and not its ProductId. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService:PromptPremiumPurchase
Deprecated. This method has been superseded by PromptRobloxSubscriptionPurchase().
Prompts a user to purchase Roblox Premium. To learn more about Premium and about incorporating Premium incentives into your experience, see Engagement-based payouts.
See Also
MarketplaceService.PromptPremiumPurchaseFinishedwhich fires when the Premium purchase UI closes.Players.PlayerMembershipChangedwhich fires when the server recognizes that a user's membership has changed.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The user being prompted to purchase Premium. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| tags | ["Deprecated"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (prompt-premium-upsell).
MarketplaceService:PromptProductPurchase
Prompts a user to purchase a developer product with the given productId.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player to prompt. | |
| productId | int64 | The ID of the developer product to purchase. | |
| equipIfPurchased | boolean | true | Ignored. |
| currencyType | CurrencyType | Default | Ignored. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-PromptProductPurchase1).
MarketplaceService:PromptPurchase
Prompts a user to purchase an item with the given assetId.
- This does not work for USD Creator Store purchases.
- If the item has the Sale Location set as
Experience By Place ID (API Only), you must callMarketplaceService:PromptPurchasefrom a server script. - If prompting a purchase of a limited item:
- (Recommended) Server requests prompt original copies until they run out, regardless of the price. Once original copies run out, resale copies are prompted.
- Client requests prompt from the lowest resale price even if original copies are available.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player to prompt. | |
| assetId | int64 | The ID of the asset to purchase. | |
| equipIfPurchased | boolean | true | Ignored. |
| currencyType | CurrencyType | Default | Ignored. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-PromptPurchase1, market).
MarketplaceService:PromptRobloxSubscriptionPurchase
Prompts a user to purchase a Roblox Plus subscription. When the user successfully subscribes, any experience-defined rewards for the upsell are granted automatically through the engine API.
See Also
MarketplaceService.PromptRobloxSubscriptionPurchaseFinishedwhich fires when the Roblox Plus purchase UI closes.Player.HasRobloxSubscriptionwhich can be observed viaInstance:GetPropertyChangedSignal()to detect when a user's subscription status changes.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player to be prompted to purchase Roblox Plus. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-PromptRobloxSubscriptionPurchase).
MarketplaceService:PromptRobuxTransferAsync
PromptRobuxTransferAsync initiates a Robux transfer from the sender to the user specified by receiverUserId. This is a server-only method and must be called from a Script with RunContext set to Server.
After a successful transfer, both the sender and receiver will have receipts delivered to their respective BindReceiptHandler callbacks:
- The sender's receipt has
ReceiptType.RobuxTransferSender. - The receiver's receipt has
ReceiptType.RobuxTransferReceiver.
Both receipts include a TransferRequestId field matching the transferRequestId returned by this method, which you can use for logging or to correlate sender and receiver receipts.
Receipt Timing
Both receipts are delivered to whichever server the corresponding user is currently in once the transfer settles (neither side needs to rejoin). If a transfer is gated on receiver approval, for example parental consent for the receiver's account, it does not settle until approval lands; receipts are delivered after that point.
- Receiver receipt is delivered to the server the receiver is currently in once the transfer settles, or on their next session join if they are offline.
- Sender receipt is delivered immediately if the transfer settles synchronously. If approval is required, it is delivered to the server the sender is currently in once the receiver accepts, or on the sender's next session join if they are offline.
Errors
This method throws an error if:
- The
senderis not a validPlayerinstance. receiverUserIdis not a positive integer.amountis not a positive integer.- The method is called from the client instead of the server.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| sender | Player | The Player initiating the transfer. Must be a valid player currently in the server. | |
| receiverUserId | int64 | The UserId of the user who will receive the Robux. | |
| amount | int64 | The amount of Robux to transfer. Must be a positive integer. |
Returns
| Type | Description |
|---|---|
| string | A string transferRequestId that uniquely identifies this transfer request. Use this ID to correlate with receipts delivered through BindReceiptHandler. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-PromptRobuxTransferAsync1).
MarketplaceService:PromptSubscriptionPurchase
Prompts a user to purchase a subscription for the given subscriptionId.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player object to be prompted to subscribe. | |
| subscriptionId | string | The ID of the subscription to subscribe to. |
Returns
| Type | Description |
|---|---|
| () |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService:RankProductsAsync
Takes a list of product IDs and returns a personalized ordered list of those products.
This API has a client-side throttling limit of 10 requests per minute. If you exceed this limit, wait 60 seconds and make the request again.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| productIdentifiers | Array | An array of objects identifying the products you want to rank. This array can include up to 50 items. Each ProductIdentifier has: - InfoType: Enum.InfoType - Must be either InfoType.GamePass or InfoType.Product. - Id: number - The ID of the game pass or developer product. lua local ProductIdentifier = { InfoType = Enum.InfoType.GamePass, Id = 123456 } |
Returns
| Type | Description |
|---|---|
| List | The array of ranked items in a personalized order for the current user. Each array has: - ProductIdentifier: The corresponding ID from the input array. - ProductInfo: The standard product info dictionary returned by GetProductInfoAsync. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
Code samples: View on Creator Hub (MarketplaceService-RankProductsSample).
MarketplaceService:RecommendTopProductsAsync
Takes an array of InfoType and returns up to 50 items representing the products a user is most likely to engage with and purchase. If no recommendations can be determined, the method returns an empty list.
This API has a client-side throttling limit of 5 requests per minute. If you exceed this limit, wait 60 seconds and make the request again.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| infoTypes | Array | An array of InfoType values specifying the types of product to retrieve recommendations for. Supported InfoTypes: InfoType.GamePass, InfoType.Product. lua local infoTypes = { Enum.InfoType.GamePass, Enum.InfoType.Product } |
Returns
| Type | Description |
|---|---|
| List | A ranked list of up to 50 items the user is most likely to engage with, based on the provided InfoTypes. If no recommendations can be determined, the method returns an empty list. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
Code samples: View on Creator Hub (MarketplaceService-RecommendTopProductsSample).
MarketplaceService:UserOwnsGamePassAsync
Returns true if the user with the given UserId owns the pass with the given gamePassId (not to be confused with an asset ID). You can use this method on both the client and the server.
Caching Behavior
The results of this function are cached so that repeated calls are returned faster. When the PromptGamePassPurchaseFinished event fires, the cache gets updated to reflect the latest ownership state of the associated game pass.
If the user purchases a game pass outside of the experience while remaining in the same session, the cache is eventually updated, but this process might take several minutes to propagate.
When a user first enters a server after purchasing a game pass, this functions always returns true.
Batching behavior
This method is Transparent Batching capable. If you spawn multiple calls concurrently using task.spawn, the engine automatically combines them into fewer HTTP requests behind the scenes. This is faster and helps you avoid rate limits. See Transparent Batching for details.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| userId | User | The UserId of the Player whose inventory you're checking. | |
| gamePassId | int64 | The pass ID you want to check for. Not to be confused with an asset ID. |
Returns
| Type | Description |
|---|---|
| boolean | Whether the user owns the pass. |
| Field | Value |
|---|---|
| tags | ["Yields"] |
| security | None |
| thread safety | Unsafe |
| capabilities | ["AssetRead"] |
Code samples: View on Creator Hub (MarketplaceService-UserOwnsGamePassAsync-TransparentBatching).
Events
| Name | Type / Returns | Description |
|---|---|---|
| MarketplaceService.PromptBulkPurchaseFinished | Fires when a purchase prompt for bulk avatar items is closed. | |
| MarketplaceService.PromptBundlePurchaseFinished | Fires when a bundle purchase prompt closes. | |
| MarketplaceService.PromptGamePassPurchaseFinished | Fires when a purchase prompt for a pass is closed. | |
| MarketplaceService.PromptPremiumPurchaseFinished | Fires when a purchase prompt for Roblox Premium is closed. | |
| MarketplaceService.PromptProductPurchaseFinished | Fires when a purchase prompt for a developer product is closed. Do not use this event to process purchases. | |
| MarketplaceService.PromptPurchaseFinished | Fires when a purchase prompt for an affiliate gear sale or other asset is closed. Does not fire for developer product or pass prompts. | |
| MarketplaceService.PromptRobloxSubscriptionPurchaseFinished | Fires when a purchase prompt for Roblox Plus is closed. | |
| MarketplaceService.PromptSubscriptionPurchaseFinished | Fires when a purchase prompt for a subscription is closed. |
Inherited from Instance
| Name | Type / Returns | Description |
|---|---|---|
| Instance.AncestryChanged | Fires when the Instance.Parent property of this object or one of its ancestors is changed. | |
| Instance.AttributeChanged | Fires whenever an attribute is changed on the Instance. | |
| Instance.ChildAdded | Fires after an object is parented to this Instance. | |
| Instance.childAdded | ||
| Instance.ChildRemoved | Fires after a child is removed from this Instance. | |
| Instance.DescendantAdded | Fires after a descendant is added to the Instance. | |
| Instance.DescendantRemoving | Fires immediately before a descendant of the Instance is removed. | |
| Instance.Destroying | Fires immediately before (or is deferred until after) the instance is destroyed via Instance:Destroy(). | |
| Instance.StyledPropertiesChanged | Fires whenever any style property is changed on the instance, including when a property is set to nil. |
Inherited from Object
| Name | Type / Returns | Description |
|---|---|---|
| Object.Changed | Fires immediately after a property of the object changes, with some limitations. |
MarketplaceService.PromptBulkPurchaseFinished
This event fires when a purchase prompt for a bulk avatar items closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK.
Note: This is not a trusted event from the client. To check if the user owns the items purchased, use MarketplaceService.PlayerOwnsAssetAsync or MarketplaceService.PlayerOwnsBundleAsync.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player who received the prompt. | |
| status | MarketplaceBulkPurchasePromptStatus | The status of the bulk purchase. | |
| results | Dictionary | The table type containing the line items and their status in the following format: lua { RobuxSpent: number Items: { { type: MarketplaceProductType, id: string, status: MarketplaceItemPurchaseStatus }, ... } } Each line item contains the following pairs: - type: The corresponding MarketplaceProductType (Enum). - id: The ID of the asset or bundle (string). - status: The MarketplaceItemPurchaseStatus of the purchase (Enum) |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService.PromptBundlePurchaseFinished
This event fires when a purchase prompt for a bundle closes. Use PlayerOwnsBundleAsync() to verify ownership instead of trusting this client-originated event.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player who received the prompt. | |
| bundleId | int64 | The ID of the bundle shown in the prompt. | |
| wasPurchased | boolean | Whether the bundle was purchased. |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService.PromptGamePassPurchaseFinished
This event fires when a purchase prompt for a pass closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK.
See Also
- For repeatable developer product purchase prompts, use
PromptProductPurchaseFinished. - For affiliate gear sales or other assets, use
PromptPurchaseFinished. - For more information on saving and replicating user data like purchases and progress, see Implementing player data and purchases.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player who received the prompt. | |
| gamePassId | int64 | The ID number of the pass shown in the prompt. Not to be confused with an asset ID. | |
| wasPurchased | boolean | Indicates if the user pressed OK (true), Cancel (false) on the purchase prompt, or if the purchase prompt errored (false). When PromptGamePassPurchaseFinished fires, it updates the cache used by UserOwnsGamePassAsync() to reflect the current ownership state. PromptGamePassPurchaseFinished should only be listened to in a server script. When used on the server, values such as wasPurchased reflect the final outcome of the purchase attempt. When used in a local script, these values should not be relied on for validation or game logic. |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (handling-gamepass).
MarketplaceService.PromptPremiumPurchaseFinished
This event fires when a purchase prompt for Roblox Premium closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK.
See Also
PromptPremiumPurchaseto prompt a user to purchase Premium.PlayerMembershipChanged, which fires when the server recognizes that a user's membership has changed.
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService.PromptProductPurchaseFinished
IMPORTANT: Do not use the PromptProductPurchaseFinished event to process purchases; instead, use the ProcessReceipt callback. The firing of PromptProductPurchaseFinished does not mean that a user has successfully purchased an item.
This event fires when a purchase prompt for a developer product closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK. The firing of this event does not mean that a user has successfully purchased an item.
While you can use the PromptProductPurchaseFinished event to detect when a user closes a purchase prompt, you should not use it to process purchases because those purchases might still fail in the backend for several reasons. For example, if a Roblox system is offline, or if the product price has changed and the user now doesn't have enough Robux to make the purchase. To process purchases, you must use ProcessReceipt. Using ProcessReceipt allows you to confirm that the purchase has succeeded before you grant the user the item they have purchased.
The PromptProductPurchaseFinished event fires with a Player.UserId instead of a reference to the Player object.
See Also
PromptGamePassPurchaseFinishedto prompt a user to purchase a pass.PromptPurchaseFinishedto prompt a user to purchase affiliate gear or other assets.- For more information on saving and replicating user data like purchases and progress, see Implementing player data and purchases.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| userId | int64 | The UserId of the user who received the developer product prompt. | |
| productId | int64 | The ID number of the developer product shown in the prompt. Not to be confused with an asset ID. | |
| isPurchased | boolean | Indicates if the user pressed OK (true), Cancel (false) on the purchase prompt, or if the purchase prompt errored (false). Do not use this parameter to process developer product purchases. |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
MarketplaceService.PromptPurchaseFinished
This event fires when a purchase prompt for an affiliate gear sale or other asset closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK.
This event does not fire for developer product or pass prompts.
See Also
PromptGamePassPurchaseFinishedto prompt a user to purchase a pass.PromptProductPurchaseFinishedto prompt a user to purchase a developer product.- For more information on saving and replicating user data like purchases and progress, see Implementing player data and purchases.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| player | Instance | The Player who received the prompt. | |
| assetId | int64 | The asset ID of the item shown in the prompt. | |
| isPurchased | boolean | Indicates if the user pressed OK (true), Cancel (false) on the purchase prompt, or if the purchase prompt errored (false). This might not accurately reflect if the purchase itself has been successfully processed. |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-PromptPurchaseFinished1).
MarketplaceService.PromptRobloxSubscriptionPurchaseFinished
This event fires when a purchase prompt for Roblox Plus closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK.
Note that this event firing does not guarantee the subscription was successfully processed. Listen to Player.HasRobloxSubscription via Instance:GetPropertyChangedSignal() on the server to confirm a subscription change before granting rewards.
See Also
PromptRobloxSubscriptionPurchaseto prompt a user to purchase Roblox Plus.Player.HasRobloxSubscription, which can be observed viaInstance:GetPropertyChangedSignal()to detect when a user's subscription status changes.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player who received the prompt. | |
| didTryPurchasing | boolean | Whether the user attempted to purchase Roblox Plus. |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
Code samples: View on Creator Hub (MarketplaceService-PromptRobloxSubscriptionPurchaseFinished).
MarketplaceService.PromptSubscriptionPurchaseFinished
This event fires when a purchase prompt for an affiliate gear sale or other asset closes. For example, when a user receives the purchase prompt and clicks Cancel, or when they receive a success or error message and click OK.
See Also
PromptSubscriptionPurchaseto prompt a user to purchase a subscription.UserSubscriptionStatusChanged, which fires when the server recognizes that a user's membership has changed.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| user | Player | The Player who received the prompt. | |
| subscriptionId | string | The ID of the subscription with a status change. | |
| didTryPurchasing | boolean | Whether the user attempted to purchase the subscription. |
| Field | Value |
|---|---|
| security | None |
| capabilities | ["PromptExternalPurchase"] |
Callbacks
| Name | Type / Returns | Description |
|---|---|---|
| MarketplaceService.ProcessReceipt | ProductPurchaseDecision | A callback to process receipts of developer product purchases. |
MarketplaceService.ProcessReceipt
ProcessReceipt is a callback to process receipts from developer product purchases. You can sell developer products inside an experience using MarketplaceService functions, or outside an experience on the Store tab of your experience details page.
You should only set the ProcessReceipt callback one time in a single server-side Script. This callback must handle the receipts for all developer products you have for sale.
IMPORTANT: It's highly recommended that you properly implement the ProcessReceipt callback in order to sell your developer products. You should use ProcessReceipt to grant users their purchased product over any other granting method. If your ProcessReceipt implementation isn't correct, you will not be able to grant users the products they have purchased on the Store tab of your experience details page.
Guarantees
The ProcessReceipt callback is called for all unresolved developer product purchases when:
- A user successfully completes the purchase of a developer product.
- A successful developer product purchase prompt appears to the user.
- A user joins the server.
A purchase is considered successfully initiated when:
- The purchase is processed on Roblox's backend.
- The funds are placed in escrow.
A purchase is considered resolved when:
- The
ProcessReceiptcallback returns aProductPurchaseDecisionenum ofPurchaseGranted. - The purchase is successfully recorded on Roblox's backend.
Unresolved Developer Product Purchases
An unresolved developer product purchase takes place when a user's purchase of a developer product has not yet been acknowledged by the server through the ProcessReceipt function.
Unresolved developer product purchases are not removed or refunded after the escrow period expires.
Retries and Timeouts
ProcessReceipt has no time-based retry mechanism. If a user makes a purchase that returns a ProductPurchaseDecision enum of NotProcessedYet, the ProcessReceipt callback is only called again on the same server if:
- The user successfully initiates another developer product purchase.
- The user re-joins any server under the same experience.
ProcessReceipt also has no timeout for yielded callbacks. A ProcessReceipt callback can yield for as long as the server is running, and the callback result is still accepted when the result returns.
Limitations
- If you don't implement a
ProcessReceiptcallback, your receipts will be auto-acknowledged. You can't get a receipt back after it has been acknowledged. - When there are multiple purchases pending for a user,
ProcessReceiptcallbacks are called in a non-deterministic order. - The user must be on the server for the
ProcessReceiptcallback to be invoked. - The user does not have to be on the server for the result of the
ProcessReceiptcallback to be recorded on the backend. - The
ProcessReceiptcallback for a specific purchase might run on two different servers at the same time if the user joins the second server before the callback returns on the first server. - The
ProcessReceiptcallback might still fail to be recorded on the backend, even if it returns aProductPurchaseDecisionenum ofPurchaseGranted. When this happens, the purchase remains unresolved.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| receiptInfo | Dictionary | The receiptInfo table passed to this callback contains the following data: - PurchaseId — A unique identifier for the specific purchase. - PlayerId — The user ID of the user who made the purchase. - ProductId — The ID of the purchased product. - PlaceIdWherePurchased — The place ID in which the purchase was made. Depending on where the user is during gameplay, the purchase place's ID can be the same as or different from the current place's ID. - CurrencySpent — The amount of currency spent in the transaction. - CurrencyType — The type of currency spent in the purchase; always CurrencyType.Robux. - ProductPurchaseChannel — How the user acquired the developer product. One of ProductPurchaseChannel. |
Returns
| Type | Description |
|---|---|
| ProductPurchaseDecision | An enum that represents how the developer product receipt was processed. - PurchaseGranted: - Indicates that the experience successfully granted the player the developer product. - Indicates to Roblox that the developer product sale was successful. - NotProcessedYet: - Indicates that the experience failed to grant the player the developer product. |
| Field | Value |
|---|---|
| security | None |
| thread safety | Unsafe |
| capabilities | ["Monetization"] |
Code samples: View on Creator Hub (ProcessReceipt-Example).
Properties
Inherited from Instance
| Name | Type / Returns | Description |
|---|---|---|
| Instance.Archivable | boolean | Determines if an Instance and its descendants can be cloned using Instance:Clone(), and can be saved/published. |
| Instance.archivable | boolean | |
| Instance.Capabilities | SecurityCapabilities | The set of capabilities allowed to be used for scripts inside this container. |
| Instance.IsInSandbox | boolean | Indicates whether the instance is inside a sandboxed container. |
| Instance.Name | string | A non-unique identifier of the Instance. |
| Instance.Parent | Instance | Determines the hierarchical parent of the Instance. |
| Instance.PredictionMode | PredictionMode | Reflects the client-side prediction mode applied to the instance under server-authoritative physics. |
| Instance.RobloxLocked | boolean | A deprecated property that used to protect CoreGui objects. |
| Instance.Sandboxed | boolean | When enabled, the instance can only access abilities in its Capabilities list. |
| Instance.UniqueId | UniqueId | A unique identifier for the instance. |
Inherited from Object
| Name | Type / Returns | Description |
|---|---|---|
| Object.ClassName | string | A read-only string representing the class this Object belongs to. |
| Object.className | string |