DevEx e negócio

Cobre seu sistema de scripting em 3 marcos sem tomar calote

Você entrega o sistema, o cliente diz "vou testar" e desaparece com três semanas do seu trabalho. O conserto é dividir o pagamento em três gamepasses no SEU place e entregar o arquivo só depois do último.

por Gustavo Cantino11 min de leituraIntermediário

Rascunho assistido por IA, revisado, testado e editado por um humano antes de publicar. Ver Política Editorial. · Revisado por Gustavo Cantino, 07/09/2026 Política Editorial

Placa tipográfica com a categoria DevEx e negócio em destaque, o nível intermediário abaixo, e um campo de barras verticais verdes sobre fundo escuro.

Você cobra por um sistema de scripting sem tomar calote fazendo o cliente comprar um gamepass no seu próprio place, dividido em três marcos, e entregando o arquivo final só depois do último pagamento cair. Não existe contrato que a Roblox execute no seu lugar: se o cliente já está com o .rbxm na mão e não pagou, não tem suporte, ticket ou DMCA que resolva em tempo útil. O que existe é sequência de entrega — quem controla a ordem das etapas controla o risco.

O calote não acontece na entrega, acontece na forma de pagamento

O roteiro é sempre o mesmo. Você fecha um sistema de loja com inventário e save por 70.000 Robux, trabalha duas ou três semanas, o cliente pede "só pra ver funcionando no meu jogo". Você manda o modelo, ele responde "boa, vou testar hoje à noite" e nunca mais aparece. Ou pior: aparece o suficiente pra pedir mais três ajustes de graça.

Coloca preço nisso. 70.000 Robux líquidos valem US$ 245 no DevEx (a taxa é 100.000 Robux = US$ 350). Com o dólar a R$ 5,40 — confira a cotação do dia e a taxa do seu banco — são cerca de R$ 1.323 que sumiram junto com o arquivo. Divida por três semanas de trabalho e você acabou de trabalhar por menos que o piso de um estágio.

E tem a parte que quase todo mundo esquece na hora de fazer o orçamento: gamepass e dev product deixam 30% na Roblox. Se você combinou 70.000 Robux e colocou 70.000 no preço do gamepass, chegam 49.000 na sua conta. Você já perdeu 21.000 Robux (US$ 73,50) antes de qualquer calote acontecer.

A outra variação do prejuízo é a mais elegante de todas, e é a que pega dev bom: o cliente te chama pro grupo dele e promete pagar por group payout. Payout de grupo só libera pra quem está no grupo há 14 dias. No dia 12, com o sistema já rodando no jogo dele, você é removido do grupo. O valor nunca foi transferido, não há registro de compra, não há nada pra reclamar. Você foi voluntário.

Cobrança em três marcos, com o dinheiro entrando no seu place

O fluxo abaixo não depende de confiança, e é rápido de montar — dá pra deixar tudo pronto em uns 20 minutos por cliente.

1. Escopo escrito antes do preço. Uma lista de entregáveis, o número de revisões incluídas e o GameId do universo autorizado. O GameId é o que amarra a licença depois, então peça pro cliente rodar print(game.GameId) no place dele e te mandar o número (não é o PlaceId da URL — um universo tem vários places). Sem escopo escrito, "sistema de loja" vira "sistema de loja, mais trade, mais ranking" na terceira semana.

2. Preço bruto = preço líquido ÷ 0,7. Se você quer 70.000 Robux na sua conta, o total dos gamepasses precisa somar 100.000 Robux. Faça essa conta na frente do cliente e mostre na proposta: bruto, líquido e o que você recebe. Isso tira a conversa de "tá caro" e coloca em "a Roblox cobra 30%".

3. Três gamepasses, no seu place, com nome de marco. Crie três gamepasses em um place seu (pode ser privado — o cliente compra direto pela página do gamepass no site) com nomes explícitos: "Marco 1 — Sistema de Loja", "Marco 2", "Marco 3". Divisão que funciona: 40% na assinatura do escopo, 40% na entrega do build de teste, 20% na liberação da licença e do arquivo-fonte. A tabela de marcos está no artefato, com bruto, líquido e o equivalente em dólar de cada parcela.

Por que gamepass e não Pix ou payout: compra de gamepass não tem botão de estorno. O cliente não abre disputa, não cancela, não reverte. O valor entra na sua conta na hora e aparece no seu resumo de vendas com data e comprador. É o único mecanismo dentro da plataforma em que o dinheiro anda numa direção só.

4. Marco 2 entrega um build travado, não o arquivo. Depois do segundo pagamento você entrega o sistema funcionando no jogo do cliente — mas com o módulo de licença ligado, com prazo. O sistema roda 100% durante o teste e desliga sozinho na data que você definiu. O cliente valida no jogo dele, com jogadores reais, e você não abriu mão de nada. Chame a licença na primeira linha de cada script do seu sistema:

Script em ServerScriptService
local License = require(script.Parent.SpawnPointLicense)
if not License.assert() then
	return -- sistema desligado: nada de erro vermelho, só um warn no output
end

5. Marco 3 libera a licença e o fonte. Pago o terceiro gamepass, você troca TRIAL_EXPIRES_AT por 0 (licença sem prazo), confirma o GameId definitivo e manda o .rbxm mais a documentação. A partir daqui o sistema é dele, e é exatamente por isso que esse passo é o último.

6. Só então pense no saque. DevEx exige no mínimo 30.000 Robux por solicitação, conta com Premium ativo, 13 anos ou mais e verificação de identidade. Repare que o Marco 1 do exemplo (28.000 Robux líquidos) não atinge o mínimo isolado — você acumula até bater o piso. E o dinheiro entra como rendimento do exterior: pessoa física declara no carnê-leão, com alíquota que chega a 27,5%. Confirme com um contador antes de tratar o valor cheio como lucro.

Os três arquivos que você manda junto com o orçamento

São três artefatos e cada um resolve um pedaço do problema.

A tabela de marcos você cola direto na conversa com o cliente. Ela mostra bruto, líquido, dólar e o que acontece em cada etapa. Troque só o valor total; as colunas de 70% e de DevEx seguem a mesma conta.

O escopo em JSON vai anexado à proposta. Parece formalidade exagerada pra um freela de Roblox, mas é o documento que você mostra quando o cliente pede a quarta revisão de graça: está escrito que são duas.

O módulo de licença é um ModuleScript que você coloca dentro do sistema entregue. Ele compara game.GameId com a lista de universos autorizados, checa a data limite do teste e, se algo não bate, devolve false e escreve um warn no output com seu contato. Ele não apaga nada, não mexe em DataStore e não quebra o jogo do cliente — sabotagem gera denúncia e queima seu nome no mercado de freela, que é pequeno e fala entre si. O sistema simplesmente não liga.

Uma coisa que você precisa saber antes de confiar demais nele: a checagem é atrito, não criptografia. Quem tem o arquivo pode abrir o módulo e apagar a linha da verificação. É por isso que o módulo protege o build do Marco 2 (que roda no place do cliente, com o script do lado do servidor, sem ele ter o arquivo) e não substitui a regra de entregar o fonte só no final. E nunca faça a checagem no cliente:

ModuleScript em ReplicatedStorage (jeito errado)
if game.PlaceId ~= 123456789 then
	script:Destroy() -- qualquer exploiter desliga isso em 10 segundos
end

Tudo que roda em StarterPlayerScripts ou ReplicatedStorage é lido e alterado por quem quiser. A licença mora em ServerScriptService, junto com o resto do seu sistema.

O erro mais caro: aceitar "entra no meu grupo que eu faço o payout"

Esse é o que custa o valor inteiro do projeto, não uma parcela. Group payout tem carência de 14 dias de participação no grupo, e é o cliente quem decide se você continua no grupo até o dia 14. Já vi essa combinação de regras descrita como "golpe do grupo" em fórum de dev justamente porque ela é legítima do ponto de vista da plataforma: nenhuma regra foi quebrada, nenhuma transação falhou, simplesmente nunca houve transação.

Se você já está no meio de um projeto nesse formato, o conserto é imediato e é uma frase: "consigo receber por gamepass, aí a compra fica registrada pra nós dois". Se o cliente aceita, o problema acabou. Se ele insiste no payout, pare de escrever código até o primeiro marco entrar. Cliente que argumenta contra registro de pagamento está te dizendo o que pretende fazer.

Duas variações que caem no mesmo balde: criar o gamepass no place do cliente (aí o dinheiro cai na conta dele, não na sua — o gamepass pertence a quem é dono do jogo) e aceitar porcentagem de faturamento futuro em vez de valor fixo. Porcentagem sem acesso ao painel de analytics e sem controle do gamepass é promessa, não pagamento. Se você quiser participação, cobre o fixo integral mais a porcentagem, e assuma que a porcentagem pode dar zero.

O que medir a partir do primeiro contrato

Abra uma planilha e registre três números por orçamento enviado.

O primeiro é a taxa de conversão do Marco 1: quantos orçamentos enviados viraram primeira compra de gamepass. Esse número diz se seu preço e sua proposta fazem sentido pro mercado que você está atendendo.

O segundo é o tempo entre marcos, em dias. Se o Marco 2 leva 20 dias pra ser pago porque o cliente "ainda está testando", seu prazo de teste no módulo de licença está longo demais — 14 dias resolve a maioria dos casos.

O terceiro é o líquido real por hora trabalhada. Some as horas do projeto, divida os Robux líquidos e converta pela taxa do DevEx. É o único número que responde se vale a pena continuar aceitando freela de scripting ou se está na hora de colocar essas mesmas semanas num jogo seu.

Artefato pronto pra usar

Tabela para colar na proposta enviada ao cliente
markdown
# Marcos de pagamento — Sistema de Loja v1

Total combinado (liquido para o dev): **70.000 Robux**
Preco bruto necessario: 70.000 / 0,7 = **100.000 Robux** (a Roblox retem 30% de cada gamepass)
Conversao usada: 100.000 Robux = US$ 350 no DevEx | dolar de referencia R$ 5,40

| Marco | Gatilho | Gamepass (bruto) | Voce recebe (70%) | DevEx (US$) | ~R$ |
|---|---|---|---|---|---|
| 1 | Escopo assinado, antes da primeira linha de codigo | 40.000 | 28.000 | 98,00 | 529,20 |
| 2 | Build de teste rodando no jogo do cliente, com licenca por 14 dias | 40.000 | 28.000 | 98,00 | 529,20 |
| 3 | Licenca sem prazo + arquivo .rbxm + documentacao | 20.000 | 14.000 | 49,00 | 264,60 |
| **Total** | — | **100.000** | **70.000** | **245,00** | **1.323,00** |

Observacoes que ficam na proposta:
- Marco 1 sozinho (28.000) fica abaixo do minimo de 30.000 Robux por solicitacao de DevEx.
- Revisoes incluidas: 2 por marco. A terceira em diante e orcada a 5.000 Robux brutos cada.
- Os 3 gamepasses ficam em place de propriedade do dev. Group payout nao e aceito como forma de pagamento.
ModuleScript chamado SpawnPointLicense em ServerScriptService
lua
--!strict
-- SpawnPointLicense
-- Onde mora: ServerScriptService, dentro da pasta do sistema que voce entrega.
-- Para que serve: liberar o sistema apenas no universo contratado e apenas
-- dentro do prazo do build de teste (Marco 2). No Marco 3, troque
-- TRIAL_EXPIRES_AT por 0 e a licenca passa a valer sem prazo.
-- Ele NAO apaga nada e NAO mexe em DataStore: se a licenca nao vale, o
-- sistema simplesmente nao liga e escreve um aviso no Output.

local RunService = game:GetService("RunService")

export type LicenseResult = {
	ok: boolean,
	reason: string,
}

-- GameId (nao PlaceId) dos universos autorizados.
-- Peca ao cliente para rodar print(game.GameId) no place dele.
local AUTHORIZED_GAME_IDS: { [number]: boolean } = {
	[7654321098] = true,
}

-- Timestamp UTC do fim do teste. Use 0 para licenca definitiva (sem prazo).
-- Exemplo: 1767225600 = 01/01/2026 00:00 UTC
local TRIAL_EXPIRES_AT: number = 1767225600

local SYSTEM_NAME: string = "Sistema de Loja v1"
local CONTACT: string = "Licenca de teste encerrada. Fale com o dev para liberar a versao final."

local License = {}

-- Checagem crua: devolve o resultado e o motivo, sem escrever nada.
function License.check(): LicenseResult
	-- Arquivo local nao publicado (GameId 0) roda livre, para voce desenvolver.
	if RunService:IsStudio() and game.GameId == 0 then
		return { ok = true, reason = "arquivo local nao publicado" }
	end

	if not AUTHORIZED_GAME_IDS[game.GameId] then
		return {
			ok = false,
			reason = string.format("GameId %d nao autorizado", game.GameId),
		}
	end

	if TRIAL_EXPIRES_AT > 0 and os.time() > TRIAL_EXPIRES_AT then
		return { ok = false, reason = "periodo de teste expirado" }
	end

	return { ok = true, reason = "licenca valida" }
end

-- Dias restantes do teste. Retorna math.huge quando a licenca nao tem prazo.
function License.daysLeft(): number
	if TRIAL_EXPIRES_AT <= 0 then
		return math.huge
	end
	return math.max(0, math.floor((TRIAL_EXPIRES_AT - os.time()) / 86400))
end

-- Chame na primeira linha de cada Script do seu sistema:
--   if not License.assert() then return end
function License.assert(): boolean
	local result = License.check()

	if not result.ok then
		warn(string.format("[%s] desativado: %s. %s", SYSTEM_NAME, result.reason, CONTACT))
		return false
	end

	if TRIAL_EXPIRES_AT > 0 then
		print(string.format(
			"[%s] build de teste ativo — %d dia(s) restante(s)",
			SYSTEM_NAME,
			License.daysLeft()
		))
	end

	return true
end

return License
Arquivo escopo.json anexado ao orcamento enviado ao cliente
json
{
  "projeto": "Sistema de Loja v1",
  "dev": "@seu_usuario_roblox",
  "cliente": "@usuario_do_cliente",
  "universo_autorizado": {
    "game_id": 7654321098,
    "como_obter": "cliente roda print(game.GameId) no place de producao"
  },
  "entregaveis": [
    "ModuleScript de inventario com save em DataStore",
    "GUI de loja com 3 categorias e busca",
    "RemoteEvents com validacao no servidor",
    "Documentacao de 1 pagina em portugues"
  ],
  "fora_do_escopo": [
    "trade entre jogadores",
    "ranking global",
    "arte e icones dos itens"
  ],
  "pagamento": {
    "moeda": "Robux",
    "forma": "gamepass em place do dev",
    "group_payout_aceito": false,
    "total_bruto": 100000,
    "total_liquido_dev": 70000,
    "marcos": [
      { "numero": 1, "gatilho": "escopo aprovado", "bruto": 40000, "gamepass_id": 0 },
      { "numero": 2, "gatilho": "build de teste com licenca de 14 dias", "bruto": 40000, "gamepass_id": 0 },
      { "numero": 3, "gatilho": "licenca sem prazo + arquivo .rbxm", "bruto": 20000, "gamepass_id": 0 }
    ]
  },
  "revisoes_incluidas_por_marco": 2,
  "revisao_extra_bruto": 5000,
  "prazo_teste_dias": 14,
  "fonte_entregue_em": "marco 3"
}
Neste artigo