Documentação
OAuth para aplicativos
Implemente Authorization Code com PKCE, consentimento, troca, rotação e revogação de tokens.
Aplicativos instaláveis usam OAuth 2.0 Authorization Code com PKCE. O dono do restaurante entra no portal da Takeat, revisa as permissões e autoriza o app. O backend do parceiro troca o código de uso único por access e refresh tokens.
Use este fluxo para SaaS e produtos conectados a vários restaurantes. Para uma automação controlada por um único restaurante, prefira a API key.
Cliente público, sem client secret
O aplicativo recebe um client ID público no formato tk_app_.... Não existe
client_secret no fluxo de instalação. A segurança depende de PKCE, state,
redirect URIs exatas e troca de tokens no backend.
Antes de começar
Cadastre o aplicativo com a Takeat e defina:
- nome, descrição e identidade que o restaurante verá no consentimento;
- ambiente de teste ou produção;
- uma ou mais redirect URIs HTTPS completas e exatas;
- somente os escopos necessários;
- limites de requisição adequados à integração.
Você receberá o client_id público e a URL do portal Entrar com a Takeat do
ambiente. Use sempre o portal e a API do mesmo ambiente.
| Componente | URL |
|---|---|
| Portal de autorização | ${TAKEAT_OAUTH_PORTAL_URL}/authorize |
| Troca, renovação e revogação | https://public-api.takeat.app/oauth/* em produção |
| Recursos de dados | https://public-api.takeat.app/v1/* em produção |
Fluxo resumido
sequenceDiagram
participant App as App parceiro
participant Portal as Entrar com a Takeat
participant Owner as Dono do restaurante
participant API as Nova API V1.0
App->>App: Gera state + PKCE
App->>Portal: Redirect com client_id e code_challenge
Portal->>Owner: Login e consentimento
Owner->>Portal: Autoriza os escopos
Portal->>App: Callback com code + state
App->>App: Valida state
App->>API: POST /oauth/token + code_verifier
API->>App: access_token + refresh_token
App->>API: GET /v1/* com Bearer1. Gere state e PKCE
Antes do redirect, gere e associe a uma tentativa de instalação:
state: valor aleatório, opaco, de uso único e com expiração curta;code_verifier: valor aleatório Base64URL com 43 a 128 caracteres;code_challenge: SHA-256 do verifier codificado em Base64URL sem padding;code_challenge_method: sempreS256.
Exemplo em Node.js:
import { createHash, randomBytes } from "node:crypto";
const state = randomBytes(32).toString("base64url");
const codeVerifier = randomBytes(64).toString("base64url");
const codeChallenge = createHash("sha256")
.update(codeVerifier)
.digest("base64url");Persista state, code_verifier, redirect URI e contexto do usuário no
backend. Não envie o verifier na URL e não use um identificador previsível como
state sem assinatura e expiração.
2. Redirecione para o consentimento
Monte a URL no backend e redirecione o navegador:
${TAKEAT_OAUTH_PORTAL_URL}/authorize
?client_id=tk_app_EXEMPLO
&redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback
&code_challenge=CHALLENGE_BASE64URL
&code_challenge_method=S256
&state=VALOR_OPACO| Parâmetro | Origem | Regra |
|---|---|---|
client_id | Takeat | ID público tk_app_... do ambiente correto |
redirect_uri | Seu app | Deve coincidir exatamente com uma URI cadastrada |
code_challenge | Seu backend | Derivado do verifier desta tentativa |
code_challenge_method | Fixo | Sempre S256 |
state | Seu backend | Aleatório, correlacionado, expirável e de uso único |
scope | Opcional | Informativo; a concessão usa os escopos cadastrados do app |
O portal autentica o dono, mostra o aplicativo e seus escopos e devolve o
navegador à redirect_uri. O restaurante é derivado da sessão Takeat do dono;
seu app não envia restaurant_id no consentimento.
3. Receba e valide o callback
Em caso de aprovação:
https://app.example.com/oauth/callback?code=tk_code_...&state=...Antes de usar o code:
- compare
stateem tempo constante com o valor associado à sessão; - rejeite valor ausente, divergente, expirado ou já consumido;
- recupere o
code_verifierno backend; - marque a tentativa como consumida;
- trate
error=access_deniedcomo recusa do usuário, não como falha interna.
O código expira em aproximadamente cinco minutos e é de uso único. Nunca o registre nem o encaminhe ao frontend depois do callback.
4. Troque o código por tokens
Faça a requisição no backend com formulário URL encoded:
curl -X POST "https://public-api.takeat.app/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=tk_app_EXEMPLO" \
--data-urlencode "code=tk_code_EXEMPLO" \
--data-urlencode "redirect_uri=https://app.example.com/oauth/callback" \
--data-urlencode "code_verifier=VERIFIER_ORIGINAL"Resposta:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "tk_refresh_...",
"scope": "products:read table-sessions:read"
}O access_token atual dura 15 minutos. Vincule o refresh token à instalação do
restaurante e armazene-o criptografado. Uma instalação não pode compartilhar
tokens com outra.
5. Use o Bearer token
curl "https://public-api.takeat.app/v1/products" \
-H "Authorization: Bearer $TAKEAT_ACCESS_TOKEN"O restaurante é inferido da instalação. A API retorna 403 quando o token não
possui o escopo exigido pela operação.
6. Renove e rotacione
curl -X POST "https://public-api.takeat.app/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=tk_app_EXEMPLO" \
--data-urlencode "refresh_token=$TAKEAT_REFRESH_TOKEN"Cada renovação devolve um novo refresh token. Substitua o valor antigo e o novo em uma única transação. Se duas instâncias tentarem renovar ao mesmo tempo, coordene a operação com lock ou compare-and-swap. Reutilizar um refresh token já consumido revoga toda a família de tokens da instalação.
7. Revogue ou desinstale
Revogue um access ou refresh token:
curl -X POST "https://public-api.takeat.app/oauth/revoke" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=tk_app_EXEMPLO" \
--data-urlencode "token=$TAKEAT_TOKEN_TO_REVOKE" \
--data-urlencode "token_type_hint=refresh_token"A revogação é idempotente. Revogar o aplicativo ou negar novamente o consentimento encerra a instalação e impede novas renovações.
Escopos
| Escopo | Recurso |
|---|---|
menu:read | Cardápio publicado |
table-sessions:read | Comandas, pedidos e pagamentos |
payment-methods:read | Métodos de pagamento |
products:read | Produtos |
products:write | Criar, editar e alterar disponibilidade de produtos |
complements:read | Complementos |
complements:write | Editar complementos, preços, fiscal e disponibilidade, individualmente ou em lote |
financial:read | Lançamentos e totais financeiros |
brands:read | Marcas e identificação fiscal do restaurante |
nfe-received:read | NF-e recebidas e seus detalhes fiscais |
inputs:read | Insumos ativos e posição de estoque |
intermediaries:read | Produtos intermediários ativos |
clube:read | Clientes do Clube de Fidelidade |
Solicite o menor conjunto possível. A Takeat pode editar as permissões de um app
já instalado, mantendo seu client_id. Adicionar ou remover qualquer escopo
revoga as autorizações de todos os restaurantes conectados, os códigos
pendentes e os access/refresh tokens existentes. Reordenar a mesma lista ou
alterar somente os dados públicos do app não revoga o consentimento.
Ao receber 401 com o token antigo ou invalid_grant na renovação, ofereça
Reconectar restaurante e inicie um novo fluxo com state e PKCE. Cada
restaurante deve revisar e autorizar a lista atual; renovar o token não concede
permissões novas. A autorização de um restaurante não reconecta os demais.
O portal envia approved_scopes em POST /oauth/consent, vinculando a aprovação
à lista exibida. Se o cadastro mudar com a página aberta, a API responde
409 invalid_scope: o portal atualiza a lista e espera outra aprovação explícita.
Esse campo é do portal; o aplicativo parceiro continua usando o redirect padrão.
Erros comuns
| Situação | Causa provável | Ação |
|---|---|---|
invalid_request | Campo obrigatório ausente ou método de autenticação misturado | Envie somente os campos do grant usado |
access_denied | Dono recusou ou sessão não pode autorizar | Preserve o contexto e permita tentar novamente |
invalid_client | client_id inválido, ambiente errado ou app revogado | Confirme cadastro e ambiente |
| Redirect URI recusada | URI diferente do cadastro, inclusive path ou barra final | Use correspondência exata |
invalid_grant na troca | Código expirado, reutilizado ou verifier incorreto | Reinicie o fluxo completo |
invalid_grant no refresh | Token expirado, revogado, consumido ou instalação inativa | Exija nova autorização |
HTTP 401 na API | Access token inválido, expirado ou revogado | Renove uma vez; se falhar, reconecte |
HTTP 403 na API | Escopo insuficiente | Não repita; solicite consentimento adequado |
HTTP 429 | Limite por minuto ou por dia atingido | Respeite Retry-After, aplique backoff e reduza polling |
Checklist de segurança
- Valide
statee use PKCE S256 em toda autorização. - Troque o código e armazene tokens somente no backend.
- Não coloque tokens, código ou verifier em cookies legíveis por JavaScript, local storage, analytics, URLs internas ou logs.
- Criptografe refresh tokens em repouso e separe-os por instalação.
- Mascare
Authorization,code,code_verifiererefresh_tokenna observabilidade. - Não cole credenciais reais em prompts de IA. Forneça apenas nomes de variáveis e exemplos fictícios.
- Revogue instalações abandonadas e trate reutilização de refresh token como incidente de segurança.
O formato desta explicação segue a progressão prática do guia público de OAuth do Cardápio Web — preparação, PKCE, autorização, callback, tokens, escopos, renovação, revogação e erros — adaptada aos contratos da Takeat.