Pular para o conteúdo
getplace

Documentação para criadores

Como preparar os arquivos, como o Getplace protege o seu app e como conferir a licença dentro dele.

Como a distribuição funciona

  1. Você envia um arquivo por plataforma no portal. O Getplace confere o tipo pelo conteúdo.
  2. O arquivo é cifrado com XChaCha20-Poly1305 em blocos de 1 MiB, com uma chave exclusiva daquela versão, e o original é apagado do servidor.
  3. Quando alguém com licença baixa o app, a chave é selada para o par de chaves daquele dispositivo. Nenhum outro aparelho consegue abrir o pacote.
  4. O app Getplace decifra, instala e abre o seu app, entregando junto um token de licença assinado.

Pacotes Universal (web/WebAssembly) rodam dentro do Getplace e só são decifrados em memória: fora do Getplace eles não abrem. Apps nativos (Windows, Linux, Android, macOS) ficam instalados no sistema depois do download; para que eles também só funcionem com licença, confira o token dentro do app, como mostrado abaixo. Para sistemas com servidor próprio (CRMs, ERPs), a proteção mais forte é conferir a licença no servidor.

Preparar o arquivo

O token de licença

Ao abrir o seu app, o Getplace entrega um token assim:

O token tem duas partes em base64url separadas por ponto: os dados em JSON e a assinatura Ed25519 desses dados.

{
  "v": 1,
  "lic": 4821,                  // número da licença (0 quando é o próprio criador testando)
  "app": "seu-app",             // confira se é o identificador do SEU app
  "usuario": "9f2c41d07ab35e81c6d2",  // identificador anônimo do usuário, fixo para o seu app
  "dispositivo": "51aa09e3c4be72d01f9c",
  "tipo": "compra",             // pass, compra, assinatura, cortesia ou dono
  "valida_ate": null,           // fim do período pago (pass/assinatura) ou null
  "iat": 1792108800,            // emitido em (Unix)
  "exp": 1794700800             // vence em (Unix): depois disso, peça um token novo
}

Chave pública Ed25519 do Getplace (base64):

1Z3X3L1qT4vwmAaxHgCSAyCqkkuXOeem5+k8Ajd2hxE=

Regras para aceitar um token: assinatura válida, app igual ao identificador do seu app e exp no futuro. Apps do Pass recebem tokens que valem até 7 dias; compras, até 30 dias. O Getplace renova sozinho quando há internet.

Exemplos de verificação

PHP

const CHAVE_GETPLACE = '1Z3X3L1qT4vwmAaxHgCSAyCqkkuXOeem5+k8Ajd2hxE=';

function ler_licenca(string $token, string $meu_app): ?array {
    $p = explode('.', $token);
    if (count($p) !== 2) return null;
    $b64 = fn($x) => base64_decode(strtr($x, '-_', '+/'));
    $json = $b64($p[0]);
    if (!sodium_crypto_sign_verify_detached($b64($p[1]), $json, base64_decode(CHAVE_GETPLACE))) return null;
    $d = json_decode($json, true);
    return ($d['app'] === $meu_app && $d['exp'] > time()) ? $d : null;
}

Node.js

const crypto = require('crypto');
const CHAVE = Buffer.from('1Z3X3L1qT4vwmAaxHgCSAyCqkkuXOeem5+k8Ajd2hxE=', 'base64');
const pub = crypto.createPublicKey({
  key: Buffer.concat([Buffer.from('302a300506032b6570032100', 'hex'), CHAVE]),
  format: 'der', type: 'spki'
});

function lerLicenca(token, meuApp) {
  const [dados, assinatura] = token.split('.');
  const json = Buffer.from(dados, 'base64url');
  if (!crypto.verify(null, json, pub, Buffer.from(assinatura, 'base64url'))) return null;
  const d = JSON.parse(json);
  return d.app === meuApp && d.exp > Date.now() / 1000 ? d : null;
}

const licenca = lerLicenca(process.env.GETPLACE_LICENCA || '', 'seu-app');
if (!licenca) { console.error('Abra este app pelo Getplace.'); process.exit(1); }

Python (PyNaCl)

import base64, json, os, time
from nacl.signing import VerifyKey
from nacl.exceptions import BadSignatureError

CHAVE = VerifyKey(base64.b64decode('1Z3X3L1qT4vwmAaxHgCSAyCqkkuXOeem5+k8Ajd2hxE='))

def b64u(s):
    return base64.urlsafe_b64decode(s + '=' * (-len(s) % 4))

def ler_licenca(token, meu_app):
    try:
        dados, assinatura = token.split('.')
        json_bytes = b64u(dados)
        CHAVE.verify(json_bytes, b64u(assinatura))
    except (ValueError, BadSignatureError):
        return None
    d = json.loads(json_bytes)
    return d if d['app'] == meu_app and d['exp'] > time.time() else None

Verificação online

Para sistemas com servidor, confira o token também no Getplace. Essa consulta detecta reembolsos e assinaturas vencidas na hora.

POST https://getplace.store/api/?r=licenca/verificar
Content-Type: application/json

{"token": "TOKEN_RECEBIDO_DO_APP"}

Resposta:
{"valida": true, "motivo": "ok", "dados": { ...conteúdo do token... }}

Motivos possíveis quando valida é falso: assinatura, vencido, revogada, sem_pass, assinatura_vencida.

Tempo de uso no Pass

Você não precisa integrar nada. O Getplace mede o tempo em que o seu app fica aberto e envia ao servidor a cada 5 minutos, com limite diário por pessoa. Uso do próprio criador não conta. No começo de cada mês o Fundo do mês anterior é fechado e o valor aparece no seu Financeiro.