Roblox: Gamepasses e Developer Products Seguros
Gere um sistema profissional de monetização para Roblox que diferencia corretamente gamepasses permanentes de developer products consumíveis. O prompt exige uma implementação server-side com MarketplaceService, verificação de propriedade, processamento confiável de recibos e concessão segura de benefícios.
Ideal para desenvolvedores que precisam integrar VIP, multiplicadores, moedas, revives, boosts ou itens compráveis sem confiar no cliente. O resultado solicitado é um Script Luau completo, comentado e pronto para adaptar ao Explorer e aos RemoteEvents já existentes no projeto.
A arquitetura prioriza segurança e resiliência: o servidor é autoritativo, compras de developer products são processadas somente por ProcessReceipt e recibos repetidos não podem conceder recompensas duplicadas. Também inclui orientação objetiva para testar no Roblox Studio e publicar com segurança.
Atue como um desenvolvedor Roblox Luau sênior, especializado em MarketplaceService, monetização segura, DataStore e arquitetura servidor-autoritativa. Gere um único **Script** Luau completo, pronto para colar em **ServerScriptService** (não LocalScript e não ModuleScript), que implemente um sistema robusto de **gamepasses permanentes** e **developer products consumíveis**, incluindo verificação de compra e entrega segura de benefícios. Antes de escrever o código, considere o contexto do meu jogo abaixo. Caso algum campo esteja vazio, mantenha uma seção CONFIG bem identificada com valores placeholder e comentários claros para eu preencher. Não invente objetos, caminhos ou APIs do meu jogo sem marcar explicitamente a adaptação necessária. === CONTEXTO DO MEU JOGO (PREENCHEREI) === - Nome do jogo/experiência: [PREENCHER] - Onde ficam moedas/leaderstats/atributos do jogador: [ex.: player.leaderstats.Coins / Attributes / sistema próprio] - Nome e caminho dos RemoteEvents/RemoteFunctions já existentes: [PREENCHER] - Devo criar RemoteEvents automaticamente se não existirem? [SIM/NÃO] - Gamepasses (nome lógico = ID = benefício): [ex.: VIP = 123456 = tag VIP + multiplicador 2x] - Developer products (nome lógico = ID = recompensa): [ex.: Coins1000 = 987654 = adicionar 1000 Coins] - Existem produtos que concedem item, revive, boost temporário ou outro efeito? Descreva: [PREENCHER] - Sistema de salvamento já existente (DataStore/framework), se houver: [PREENCHER] - Regras de UI e fluxo de compra já existentes: [PREENCHER] === FIM DO CONTEXTO === Requisitos obrigatórios da implementação: 1. Use `MarketplaceService` e `Players`. Centralize os IDs de gamepasses e developer products em tabelas de configuração legíveis, com comentários indicando exatamente onde alterar IDs, nomes e recompensas. 2. Para gamepasses, crie uma função reutilizável como `PlayerOwnsGamePass(player, gamePassId)` que use `MarketplaceService:UserOwnsGamePassAsync(player.UserId, gamePassId)` envolvido em `pcall`. Faça cache por UserId durante a sessão, limpe o cache em `PlayerRemoving` e trate falhas de API sem conceder benefício indevido. Aplique os benefícios de gamepass na entrada do jogador e disponibilize uma função clara para reaplicar benefícios caso seja necessário. 3. Conecte `MarketplaceService.PromptGamePassPurchaseFinished` apenas para atualizar a verificação/aplicar o benefício após uma compra confirmada. Nunca trate esse evento como única fonte de verdade: confirme a propriedade pelo servidor com `UserOwnsGamePassAsync` antes de conceder o benefício permanente. 4. Para developer products, implemente `MarketplaceService.ProcessReceipt` corretamente no servidor. O callback deve identificar o produto por `receiptInfo.ProductId`, localizar o jogador por `receiptInfo.PlayerId`, entregar a recompensa apenas no servidor e retornar `Enum.ProductPurchaseDecision.PurchaseGranted` somente depois de concluir a concessão com sucesso. Se o jogador estiver offline, dados necessários não estiverem prontos, ou ocorrer erro transitório, retorne `NotProcessedYet` para nova tentativa. 5. Garanta idempotência contra recibos duplicados. Use `receiptInfo.PurchaseId` e um mecanismo persistente de registros processados via DataStore (ou integre ao sistema de salvamento informado no contexto). Explique em comentários a estratégia de reserva/confirmação do recibo e evite marcar uma compra como concluída antes de a recompensa ser efetivamente salva/concedida. Se a integração transacional perfeita não for possível devido ao sistema externo do contexto, declare a limitação e implemente a alternativa mais segura possível. 6. Não confie no cliente para valores de moeda, inventário, dano, IDs de produto ou confirmação de compra. Se o contexto incluir RemoteEvents para solicitar prompts de compra, o Script deve conectar `OnServerEvent`, validar rigorosamente `player`, tipo dos argumentos, se o ID solicitado está em uma whitelist configurada e aplicar rate limit por jogador antes de usar `PromptGamePassPurchase` ou `PromptProductPurchase`. O cliente nunca pode informar a recompensa nem chamar uma função que a conceda. 7. Para recompensas, escreva funções isoladas por produto e exemplos seguros para moeda via leaderstats e atributos. Caso o contexto use um sistema próprio, deixe pontos de integração explícitos, sem criar duplicatas de moeda ou inventário. Use `warn` com contexto útil para falhas, mas não exponha dados sensíveis. 8. O código deve usar Luau moderno, `--!strict` quando viável, tipos úteis, `task.spawn`/`task.wait` apenas quando justificado, conexões organizadas e comentários técnicos em português. Não use `loadstring`, HTTP externo, soluções client-side para conceder compra, nem APIs inexistentes. Não sobrescreva um `ProcessReceipt` de outro sistema sem avisar: se houver um handler existente, explique em comentário que é necessário consolidar a lógica em um único dispatcher servidor. Formato obrigatório da resposta: primeiro, apresente uma lista curta de premissas e objetos que devo confirmar. Em seguida, entregue o código integral em **um único bloco Markdown ` ```lua `**, sem trechos omitidos e sem pseudocódigo. Após o bloco, forneça instruções objetivas para: configurar IDs, criar/usar RemoteEvents, habilitar API Services para testes de DataStore quando apropriado, testar gamepasses e developer products no Roblox Studio usando uma experiência publicada/testes de compra, e verificar logs de `ProcessReceipt`. Inclua também uma checklist final de segurança e dos cenários de teste (compra repetida, jogador saindo durante processamento, falha de DataStore e produto inválido).