Fluxo OAuth 2.0
Com OAuth, o seller conecta a conta SuperFrete à sua plataforma com dois cliques e você recebe um token de acesso para operar em nome dele, sem que ninguém copie e cole token.
OAuth é para plataformas de e-commerce, ERPs e hubs que atendem muitos sellers. Se você está integrando a sua própria loja, use o token manual: veja Autenticação.
Como funciona
- Você pede as credenciais da sua aplicação à SuperFrete:
client_id,client_secrete aredirect_uricadastrada. - Na sua plataforma, o seller clica em algo como Conectar SuperFrete e você abre a URL de autorização da SuperFrete.
- O seller entra na conta SuperFrete (se ainda não estiver logado) e clica em Autorizar.
- Os servidores da SuperFrete fazem um
GETna suaredirect_uricom umcodetemporário e ostateque você enviou. - O seu backend troca esse
codepor umaccess_tokenemPOST /api/v0/oauth/token. - A partir daí, você usa o
access_tokencomoAuthorization: Bearerem todas as chamadas daquele seller.
Este é o ponto que mais confunde quem já implementou OAuth em outros lugares. Depois do clique em Autorizar, o navegador do seller não é redirecionado para a sua redirect_uri. Quem chama a sua URL é o servidor da SuperFrete, e o seller continua no painel da SuperFrete, na tela de configurações da integração.
Por isso:
- a requisição na
redirect_urinão traz cookies nem a sessão do seller na sua plataforma. Use ostatepara saber de qual seller é aquelecode; - a
redirect_uriprecisa ser pública e responder com status2xxrapidamente. Se ela responder com erro ou não responder, a autorização falha e o seller vê a mensagem "Ocorreu uma falha na autenticação do cliente."; - para trazer o seller de volta, abra a URL de autorização em uma nova aba ou janela e, na sua tela, acompanhe pelo seu backend quando o token daquele seller chegar.
1. Peça as suas credenciais
Preencha o formulário de solicitação de credenciais OAuth. Nele você informa a sua redirect_uri: a URL do seu backend que vai receber o code.
Você recebe um par de credenciais para cada ambiente:
| Credencial | Formato | Onde usar |
|---|---|---|
client_id | Número, por exemplo 1234 | Na URL de autorização e na troca do código |
client_secret | Texto secreto | Somente na troca do código, a partir do seu servidor |
As credenciais de sandbox não funcionam em produção, e vice-versa.
O client_secret nunca deve aparecer no front-end, em app mobile ou em repositório. Guarde em variável de ambiente ou cofre de segredos.
2. Envie o seller para a URL de autorização
Quando o seller decidir conectar a SuperFrete, abra a URL de autorização do ambiente:
| Ambiente | URL de autorização |
|---|---|
| Sandbox | https://sandbox.superfrete.com/#/auth/authorize |
| Produção | https://web.superfrete.com/#/auth/authorize |
Com estes parâmetros na query string:
| Parâmetro | Obrigatório | O que enviar |
|---|---|---|
client_id | Sim | O client_id do ambiente. |
redirect_uri | Sim | A URL cadastrada no formulário, exatamente igual, codificada com encodeURIComponent. |
state | Recomendado | Um valor aleatório e único por tentativa. Guarde no seu banco junto com o ID do seller: é por ele que você identifica o seller quando o code chegar. |
import crypto from 'node:crypto';
const AUTHORIZE_URL = 'https://sandbox.superfrete.com/#/auth/authorize';
export async function buildSuperFreteAuthorizeUrl(sellerId) {
const state = crypto.randomBytes(24).toString('hex');
// Guarde o state com o seller e um prazo curto de validade.
await db.oauthStates.insert({ state, sellerId, createdAt: new Date() });
const params = new URLSearchParams({
client_id: process.env.SUPERFRETE_CLIENT_ID,
redirect_uri: process.env.SUPERFRETE_REDIRECT_URI,
state,
});
return `${AUTHORIZE_URL}?${params}`;
}
O resultado fica assim:
https://sandbox.superfrete.com/#/auth/authorize?client_id=1234&redirect_uri=https%3A%2F%2Fapi.suaplataforma.com.br%2Fsuperfrete%2Fcallback&state=9f2c...
3. O seller autoriza
Se o seller ainda não estiver logado, a SuperFrete pede o login primeiro e depois volta para a tela de autorização.
Na tela de autorização, o seller vê a pergunta Deseja autorizar a integração? e clica em Autorizar. Para algumas plataformas parceiras, a tela também traz um formulário curto sobre a loja.
Depois do clique, a SuperFrete chama a sua redirect_uri. Se ela responder com 2xx, o seller vê Autorização concluída com sucesso! e cai na tela de configurações da integração, onde pode escolher transportadoras e ponto de postagem. A sua integração aparece em Integrações no painel do seller.
4. Receba o code na redirect_uri
A SuperFrete faz esta chamada no seu backend:
GET /superfrete/callback?code=eyJhbGciOiJIUzI1NiIs...&state=9f2c... HTTP/1.1
Host: api.suaplataforma.com.br
Nesse endpoint:
- Confira se o
stateexiste no seu banco e ainda não foi usado. Se não existir, responda400e não faça mais nada. - Troque o
codepelo token imediatamente (passo 5). Ocodevale 10 minutos e só pode ser usado uma vez. - Salve o token junto com o seller e responda
200.
- Node.js (Express)
- PHP
app.get('/superfrete/callback', async (req, res) => {
const { code, state } = req.query;
const pending = await db.oauthStates.findOneAndDelete({ state });
if (!pending || !code) return res.status(400).end();
try {
const token = await exchangeCodeForToken(code, state); // passo 5
await db.sellers.update(pending.sellerId, {
superfreteToken: encrypt(token.access_token),
});
return res.status(200).end();
} catch (error) {
console.error('SuperFrete OAuth exchange failed', error);
return res.status(502).end();
}
});
<?php
$code = $_GET['code'] ?? '';
$state = $_GET['state'] ?? '';
$pending = findAndDeleteOAuthState($state); // a sua tabela de states
if (!$pending || $code === '') {
http_response_code(400);
exit;
}
$token = exchangeCodeForToken($code, $state); // passo 5
if ($token === null) {
http_response_code(502);
exit;
}
saveSellerToken($pending['seller_id'], $token['access_token']);
http_response_code(200);
O seller fica esperando na tela da SuperFrete enquanto a sua redirect_uri responde. Faça só o essencial antes de responder e deixe sincronizações mais pesadas para depois.
5. Troque o code pelo token
Faça um POST a partir do seu servidor:
| Ambiente | Endpoint |
|---|---|
| Sandbox | https://sandbox.superfrete.com/api/v0/oauth/token |
| Produção | https://api.superfrete.com/api/v0/oauth/token |
| Campo | Valor |
|---|---|
grant_type | Sempre authorization_code |
client_id | O seu client_id |
client_secret | O seu client_secret |
code | O code recebido na redirect_uri |
redirect_uri | A mesma URL cadastrada, caractere por caractere |
state | O mesmo state da autorização (opcional) |
O corpo pode ir em JSON ou em application/x-www-form-urlencoded.
- cURL
- Node.js
- PHP
curl --request POST \
--url https://sandbox.superfrete.com/api/v0/oauth/token \
--header "Content-Type: application/json" \
--data '{
"grant_type": "authorization_code",
"client_id": "1234",
"client_secret": "'"$SUPERFRETE_CLIENT_SECRET"'",
"code": "eyJhbGciOiJIUzI1NiIs...",
"redirect_uri": "https://api.suaplataforma.com.br/superfrete/callback",
"state": "9f2c..."
}'
const TOKEN_URL =
'https://sandbox.superfrete.com/api/v0/oauth/token';
export async function exchangeCodeForToken(code, state) {
const response = await fetch(TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'authorization_code',
client_id: process.env.SUPERFRETE_CLIENT_ID,
client_secret: process.env.SUPERFRETE_CLIENT_SECRET,
code,
redirect_uri: process.env.SUPERFRETE_REDIRECT_URI,
state,
}),
});
const body = await response.json();
if (!response.ok) {
// body.error: invalid_request, invalid_client, unauthorized_client...
throw new Error(`${body.error}: ${body.error_description}`);
}
return body; // { access_token, expires_in: "never", token_type: "Bearer" }
}
<?php
function exchangeCodeForToken(string $code, string $state): ?array
{
$url = 'https://sandbox.superfrete.com/api/v0/oauth/token';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'grant_type' => 'authorization_code',
'client_id' => getenv('SUPERFRETE_CLIENT_ID'),
'client_secret' => getenv('SUPERFRETE_CLIENT_SECRET'),
'code' => $code,
'redirect_uri' => getenv('SUPERFRETE_REDIRECT_URI'),
'state' => $state,
]),
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
error_log("SuperFrete OAuth: {$body['error']} - {$body['error_description']}");
return null;
}
return $body; // access_token, expires_in ("never"), token_type ("Bearer")
}
Resposta de sucesso:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": "never",
"token_type": "Bearer"
}
6. Use o token
O access_token funciona exatamente como o token manual. Envie em todas as chamadas daquele seller, com o User-Agent da sua plataforma:
curl --request GET \
--url https://sandbox.superfrete.com/api/v0/user \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "User-Agent: SuaPlataforma/2.3 (dev@suaplataforma.com.br)" \
--header "Accept: application/json"
Consultar usuário é um bom primeiro teste: devolve nome, e-mail, saldo e limites da conta que acabou de autorizar.
Validade, renovação e revogação
- O
access_tokennão expira. A resposta trazexpires_in: "never"e não existe refresh token. Não agende renovação. - O seller pode revogar o acesso a qualquer momento, excluindo a integração em Integrações no painel da SuperFrete. A partir daí, as chamadas com aquele token voltam
401com a mensagemToken inválida!. Trate esse caso marcando a conexão como desfeita e pedindo ao seller para conectar de novo. - Se o seller autorizar outra vez, um novo token é emitido. Substitua o antigo pelo novo.
- O
codevale 10 minutos e é de uso único. Se ele expirar antes da troca, basta o seller autorizar de novo.
Erros comuns
Os erros do endpoint de token seguem o formato do OAuth 2.0:
{
"error": "invalid_client",
"http_status": 401,
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}
| Status | error | error_description | O que fazer |
|---|---|---|---|
400 | invalid_request | Required parameter 'client_id' was missing | Faltou um campo obrigatório. O nome do campo vem na mensagem (client_id, client_secret, redirect_uri ou grant_type). |
400 | invalid_request | Required parameter code was missing | O code não foi enviado. |
400 | unsupported_grant_type | The grant type requested was not recognized | Envie grant_type igual a authorization_code. |
401 | invalid_client | Client authentication failed | client_id ou client_secret errados, credencial de outro ambiente, ou redirect_uri diferente da cadastrada (até uma barra no final faz diferença). |
401 | unauthorized_client | Authorization code has expired | Passaram mais de 10 minutos desde a autorização. Peça para o seller autorizar de novo. |
400 | invalid_request | Cannot decrypt the authorization code | O code chegou incompleto ou alterado, ou é de outro ambiente. Use o valor exatamente como veio na query string. |
500 | server_error | An server error has occurred | Erro inesperado. Também acontece ao reaproveitar um code que já foi trocado: peça uma nova autorização. |
Na tela de autorização, a mensagem Ocorreu uma falha na autenticação do cliente. aparece quando o client_id não existe naquele ambiente, quando a redirect_uri não bate com a cadastrada ou quando a sua redirect_uri não respondeu com 2xx.
Checklist antes de ir para produção
- Fluxo completo testado no sandbox, com as credenciais de sandbox.
-
redirect_uride produção cadastrada, pública, com HTTPS e respondendo2xxem poucos segundos. -
statealeatório por tentativa, validado e descartado depois do uso. -
client_secrete tokens dos sellers guardados só no backend, de preferência criptografados. - Tratamento de
401(Token inválida!) para quando o seller revogar o acesso. - URLs trocadas para produção:
web.superfrete.comna autorização eapi.superfrete.comna troca e nas chamadas.
Próximos passos
- Emita a primeira etiqueta de ponta a ponta
- Receba os eventos dos pedidos por webhook
- Veja a referência de Trocar código OAuth por token
Ficou com alguma dúvida? Escreva para integracao@superfrete.com ou fale com a gente pelo chat.