Org Admin Guide

Payments

Accept Robux payments in-game using Developer Products. Staff create payment links in the dashboard; players pay in-game and the link is automatically marked paid.

How it works#

  • Staff create a Payment Link in the dashboard (Items + Robux total).
  • The link URL is shared with the customer.
  • When the customer joins the game, RoPermsPayments.lua detects their pending link and prompts them with the matching Developer Product.
  • The customer pays the Developer Product. Roblox calls your ProcessReceipt handler.
  • The handler calls RoPerms.CompletePayment(), which marks the link as PAID.
  • The payment link page shows a confirmation in real time.

Drop-in handler

RoPermsPayments.lua is a self-contained Script that handles the entire payment flow. Place it in ServerScriptService and configure the PRODUCTS table — that is the only required customisation for most games.

Step 1 — Create Developer Products#

RoPerms uses Roblox Developer Products (not Gamepasses) for payments because they can be purchased multiple times by the same player.

Create one Developer Product per Robux amount you expect to charge. For example, if you sell services for 500, 1000, and 2500 Robux, create three products. In the Roblox Creator Dashboard, note the numeric Product ID for each.

Step 2 — Configure RoPermsPayments.lua#

Open RoPermsPayments.lua and find the PRODUCTS table. Map each Robux amount to its Developer Product ID:

RoPermsPayments.lualua
local PRODUCTS = {
    -- [Robux amount] = Developer Product ID
    [500]  = 1234567890,
    [1000] = 1234567891,
    [2500] = 1234567892,
}

Also set your API key and base URL near the top:

RoPermsPayments.lualua
local CONFIG = {
    apiKey  = game:GetService("HttpService"):GetSecret("ROPERMS_KEY"),
    baseUrl = "https://roperms.app",

    -- How often (seconds) to poll for pending payment links
    pollInterval = 10,
}

Step 3 — Place the script#

  1. 1

    Copy RoPermsPayments.lua

    Place the file as a Script (not ModuleScript) inside ServerScriptService.
  2. 2

    Do not use a separate ProcessReceipt

    RoPermsPayments.lua sets MarketplaceService.ProcessReceipt. Only one script can set this handler in a place — do not set it elsewhere or the payments will not complete correctly.
  3. 3

    Publish and test

    Publish your place. Create a test payment link in the dashboard for yourself, join the game, and verify you are prompted with the Developer Product. Check the dashboard — the link should flip to PAID after purchase.

SDK functions#

fnGetOpenPaymentstable
RoPerms.GetOpenPayments(player: Player): table

Returns a list of pending payment links for the player. Each entry has id, token, totalRobux, and items fields. Used internally by RoPermsPayments.lua but available if you want a custom payment UI.

lua
local links = RoPerms.GetOpenPayments(player)
for _, link in ipairs(links) do
    print(link.token, link.totalRobux)
end
fnCompletePaymentboolean
RoPerms.CompletePayment(player: Player, linkIdOrToken: string, receiptId: string): boolean

Marks a payment link as PAID. Pass the link's token or ID, and the Roblox receipt ID from ProcessReceipt. Returns true on success. Called automatically by RoPermsPayments.lua inside ProcessReceipt.

lua
-- Inside a custom ProcessReceipt handler:
local function processReceipt(info)
    local player = Players:GetPlayerByUserId(info.PlayerId)
    if not player then return Enum.ProductPurchaseDecision.NotProcessedYet end

    local ok = RoPerms.CompletePayment(player, pendingToken, tostring(info.PurchaseId))
    if ok then
        return Enum.ProductPurchaseDecision.PurchaseGranted
    end
    return Enum.ProductPurchaseDecision.NotProcessedYet
end

Configuring items in the dashboard#

In your org Settings, go to Payment Categories. Create categories (e.g., "Services", "Bundles") and add items with names and Robux prices.

Staff members with the payments.manage capability can then create payment links using items from this catalogue. The total Robux on the link must match one of the Developer Product amounts in your PRODUCTS table, or the in-game prompt will fail to find a matching product.

Amount matching

The Robux amount on a payment link must exactly match a key in the PRODUCTS table. If a staff member creates a link for 750 Robux but you only have products for 500 and 1000, the payment cannot be completed. Set up products for every amount you plan to offer.

Receipt deduplication#

RoPermsPayments.lua uses an OrderedDataStore to track processed receipt IDs. This prevents double-completing a payment if Roblox replays aProcessReceipt call (which can happen on server restart or when the callback times out).