Secure Roblox Store with Currency, Stock, and Server-Side Validation
This prompt generates a professional store architecture for Roblox, designed for item purchases using an internal in-game currency. The system prioritizes server-side security, preventing client-side exploits from altering prices, balance, stock, or granted rewards.
Ideal for developers who already have or are creating a simulator, RPG, tycoon, survival, or any experience with an economy. The prompt asks for the project-specific context — such as RemoteEvents, folders, currencies, and item names — and returns complete, commented Luau scripts ready to place in Roblox Studio.
In addition to the purchase logic, the result must include robust validation, protection against request spam, failure handling, interface synchronization, and detailed installation instructions and multiplayer testing steps.
Act as a senior Roblox Luau developer, specialized in secure economic systems, client-server architecture, and exploit prevention. Create a complete implementation of a shop for purchasable items with an internal in-game currency, adapted to the context of my project that I will provide below. The result must be production-ready code, readable, modular when necessary, commented in Portuguese, and ready to paste into Roblox Studio. Before writing the code, consider and use this context from my game. If any field is empty, choose a safe Roblox convention, explicitly state the assumption adopted, and keep the names easy to replace: - Currency and location: [e.g., leaderstats/Coins, ProfileService, Coins attribute on the Player] - Displayed currency name: [e.g., Coins, Gold, Gems] - Items sold and prices: [e.g., Sword=250, Potion=50, VIPTrail=1000] - Reward type per item: [Tool in ServerStorage, attribute/value in inventory, consumable, internal pass, cosmetic] - Location of item templates: [e.g., ServerStorage/ShopTools] - Existing RemoteEvents/RemoteFunctions and their locations: [fill in] - Existing interface and hierarchy in the Explorer: [e.g., StarterGui/ShopGui/Frame/ItemsList] - How the shop is opened: [ProximityPrompt, GUI button, NPC, key] - Stock: [unlimited or limited; quantity per item] - Repurchase: [allowed or one-time purchase per player] - Available persistence: [own DataStore, ProfileService, none] - Exact names of objects/folders that cannot be changed: [fill in] Implement the system as an organized package of scripts. Mandatory define the TYPE and exact location of each file in the Explorer before the code. Use this architecture, unless the context above requires a justified adaptation: 1. ModuleScript `ShopCatalog`, in `ReplicatedStorage/Shared`, containing only the public, non-sensitive configuration of the catalog for the UI: stable ID, display name, description, price, icon, category, and presentation data. The client may read prices for display, but the server must own or import an equivalent source of truth and never accept a price sent by the client. 2. Script `ShopServer`, in `ServerScriptService`, responsible for creating/finding the necessary RemoteEvents, validating purchases, checking balance, debiting currency, controlling stock, granting items, and responding with structured results. 3. LocalScript `ShopClient`, in `StarterPlayer/StarterPlayerScripts` or inside `ShopGui` in `StarterGui` (choose the most suitable option for the reported hierarchy), responsible only for the interface, opening/closing, dynamic list rendering, sending the item ID to the server, and visual feedback. It can never grant items, alter currency, or decide whether a purchase is valid. 4. If necessary, include an additional adapter ModuleScript for currency/inventory, explaining how to connect it to my current system without duplicating data. The purchase must work through a RemoteEvent or RemoteFunction with a clear contract. The client must send only the `itemId`; do not send price, currency amount, Tool, arbitrary instance, or any authority data. On the server, validate strictly: valid player, ID type and length, existence of the item in the authorized catalog, non-negative integer price, current balance obtained exclusively on the server, one-time purchase limit, available stock, and delivery possibility. Implement a per-player cooldown/rate limit to prevent spam and duplicate purchases. Use a per-player lock during the transaction. Ensure a safe transactional order: validate everything, reserve/register stock when applicable, debit balance, grant the reward, and perform a coherent rollback if delivery fails. Never trust `LocalPlayer` values, client-editable attributes, or RemoteEvent arguments for currency, damage, inventory, price, or stock. For Tools, keep templates exclusively on the server, preferably in `ServerStorage`, use `:Clone()` only after approval, and deliver to `Backpack` and/or `StarterGear` as I indicate. Avoid duplicates in Backpack, Character, and StarterGear when the purchase is one-time only. For consumables and inventory items, provide a secure integration point and clearly signal exactly where I should connect my DataStore/ProfileService. Do not use DataStore in LocalScript. Do not use `loadstring`, external HTTP, unnecessary loops, legacy `wait()`, or deprecated APIs. The UI must handle success and error responses with messages such as insufficient balance, invalid item, out-of-stock, purchase already completed, request too fast, and internal error. Include visual updates of the balance and the button/item state after a purchase. If my GUI is not ready, create a minimal structure based on `ScreenGui`, `Frame`, `ScrollingFrame`, button template, and labels, explaining the required names. Do not assume objects exist without using `WaitForChild` carefully, checks, and useful diagnostic messages. Deliver the response in this order: (1) architecture summary and assumptions; (2) exact Explorer tree; (3) each complete file, without pseudocode, in separate markdown blocks in the format ```lua, with title containing type and path; (4) short table of the Remotes and their arguments; (5) installation steps; (6) test plan in Roblox Studio, including Start Server with multiple Players, insufficient balance, attempt to use a fake item/ID via client, RemoteEvent spam, final stock, and delivery failure; (7) security checklist. Do not omit essential excerpts, do not deliver partial code, and do not use code outside Lua blocks, except for the requested instructions.