• Studio

  • Studio API

  • Bots

  • Web API

  • Designer Resources

  • Host Resources

  • Globals

    Payments

    The Payments API provides functionality for managing In-World Purchases (IWP) in Highrise Studio.

    Use Payments for:

    • Creating purchasable products (items, bundles, subscriptions)
    • Processing player purchases with real currency (Gold)
    • Tracking purchase history
    • Acknowledging and fulfilling purchases

    Purchase Flow (Server-side):

    1. Set up PurchaseHandler to receive purchase notifications
    2. Grant items/rewards to the player
    3. Call AcknowledgePurchase to confirm fulfillment

    Products are configured in the Highrise Studio dashboard and retrieved via GetProduct/GetProducts.

    TESTING IN STUDIO: You can use goldfish and eel as test product IDs for IWP purchases in Studio even if your world hasn't been uploaded yet. If your world IS uploaded and has IWP configured in Creator Portal, use your actual product IDs instead.

    Rate Limiting: Payment functions have rate limits. Excessive calls will return PaymentsError.RequestThrottled.

    IMPORTANT: Server-side payment methods (GetProduct, AcknowledgePurchase, etc.) are only available on the SERVER. Client-side methods (PromptPurchase, ClosePurchasePrompt) are only available on the CLIENT.

    Properties

    PurchaseHandler

    (purchase: WorldProductPurchase, player: Player) -> ()
    ServerOnly

    Handler that gets called when a player makes a purchase. Set this to process purchases and grant rewards to players. You must call AcknowledgePurchase after fulfilling the purchase.

    TESTING: Test purchases in Studio using product IDs "goldfish" or "eel".

    function self:ServerStart()
        Payments.PurchaseHandler = function(purchase, player)
            print(player.name .. " purchased product: " .. purchase.product_id)
            
            -- Handle different products (test IDs: "goldfish", "eel")
            if purchase.product_id == "goldfish" or purchase.product_id == "premium_coins" then
                -- Grant premium coins
                local transaction = InventoryTransaction.new()
                transaction:GivePlayer(player, "premium_coins", 100)
                Inventory.CommitTransaction(transaction)
            elseif purchase.product_id == "eel" or purchase.product_id == "premium_bundle" then
                -- Grant premium bundle
                local transaction = InventoryTransaction.new()
                transaction:GivePlayer(player, "premium_coins", 500)
                transaction:GivePlayer(player, "exclusive_item", 1)
                Inventory.CommitTransaction(transaction)
            end
            
            -- Always acknowledge the purchase after granting items
            Payments.AcknowledgePurchase(purchase, true)
        end
    end
    

    Methods

    Acknowledges a purchase to confirm it has been fulfilled. Set wasConsumed to true for consumable items, false for permanent items.

    Payments.AcknowledgePurchase(purchase, true)
    

    Parameters

    wasConsumed
    boolean

    Returns

    void

    Acknowledges a purchase to confirm it has been fulfilled. Set wasConsumed to true for consumable items, false for permanent items.

    Payments.AcknowledgePurchase(purchase, true)
    

    Parameters

    wasConsumed
    boolean
    callback
    (error: PaymentsError) -> ()

    Returns

    void

    Closes the purchase prompt if one is currently open on the local client. Has no effect otherwise.

    Must be called with colon syntax (Payments:ClosePurchasePrompt) — calling it with a dot will raise "'self' cannot be null".

    Payments:ClosePurchasePrompt()
    

    Returns

    void

    GetProduct

    ServerOnly

    Retrieves a product by its ID. Use this to get product details like name, description, and price.

    TESTING: Use "goldfish" or "eel" as test product IDs in Studio before your world is uploaded. Once uploaded with IWP configured in Creator Portal, use your actual product IDs.

    -- Test in Studio with built-in test products
    Payments.GetProduct("goldfish", function(product, error)
        if error == PaymentsError.None and product ~= nil then
            print("Product: " .. product.name)
            print("Price: " .. product.price .. " Gold")
            print("Description: " .. product.description)
        end
    end)
    
    -- Use actual product IDs once world is uploaded
    Payments.GetProduct("premium_bundle", function(product, error)
        if error == PaymentsError.None and product ~= nil then
            print("Product: " .. product.name)
        end
    end)
    

    Parameters

    productId
    string
    callback
    (product: WorldProduct, error: PaymentsError) -> ()

    Returns

    void

    GetProducts

    ServerOnly

    Retrieves a list of all available In-World Purchase products.

    TESTING: In Studio, this returns test products "goldfish" and "eel" before your world is uploaded. Once uploaded with IWP configured, this returns your actual configured products.

    Pagination: limit caps how many products are returned in a single page. Pass nil for cursorId to get the first page. Use the returned nextCursorId to fetch the next page. If returned nextCursorId is nil, no more results exist.

    -- Get the first page of products (includes test products in Studio)
    Payments.GetProducts(25, nil, function(products, nextCursorId, error)
        if error == PaymentsError.None then
            print("Available products:")
            for i, product in ipairs(products) do
                print("- " .. product.name .. ": " .. product.price .. " Gold")
            end
        end
    end)
    

    Parameters

    limit
    number
    cursorId
    string
    callback
    (products: {WorldProduct}, nextCursorId: string, error: PaymentsError) -> ()

    Returns

    void

    GetPurchases

    ServerOnly

    Retrieves a list of purchases made by a player for a specific product.

    Pagination: Pass nil for cursorId to get first results. Use returned nextCursorId for next page. If returned nextCursorId is nil, no more results exist.

    Payments.GetPurchases(player, "premium_bundle", 10, nil, function(purchases, nextCursorId, error)
        if error == PaymentsError.None then
            print("Found " .. #purchases .. " purchases")
            for i, purchase in ipairs(purchases) do
                print("Purchase ID: " .. purchase.id .. " on " .. os.date("%Y-%m-%d", purchase.purchase_date))
            end
        end
    end)
    

    Parameters

    player
    productId
    string
    limit
    number
    cursorId
    string
    callback
    (purchases: {WorldProductPurchase}, nextCursorId: string, error: PaymentsError) -> ()

    Returns

    void

    PromptPurchase

    ClientOnly

    Opens the purchase prompt on the local client so the player can buy the given product. The callback receives true if the player pressed the purchase button, false if they cancelled it. Receiving true does not mean the purchase was completed; the PurchaseHandler must call AcknowledgePurchase. Process the purchase there on the server, not here on the client.

    Must be called with colon syntax (Payments:PromptPurchase) — calling it with a dot will raise "'self' cannot be null".

    TESTING: Use "goldfish" or "eel" as test product IDs in Studio before your world is uploaded.

    Payments:PromptPurchase("goldfish", function(success)
        if success then
            print("Player completed the purchase")
        else
            print("Player cancelled or the purchase failed")
        end
    end)
    

    Parameters

    productId
    string
    callback
    (obj: boolean) -> ()

    Returns

    void
    PocketWorlds Icon

    © 2026 Pocket Worlds. All rights reserved.