Autenticação — OAuth 2.0
A Partner API usa OAuth 2.0 (Authorization Code com PKCE). O lojista autoriza seu App e você recebe um token de acesso no contexto da loja.
Modelo de integração — 1 App, várias lojas
Existem duas credenciais, em níveis diferentes — entender isso é a chave para integrar a sua plataforma à Sellit:
- Sua plataforma →
client_id+client_secret. Você registra um App e recebe esse par. Ele identifica a sua plataforma e é o mesmo para todos os seus clientes. Aclient_secretfica só no seu backend. - Cada loja do seu cliente →
access_token. Quando um lojista autoriza o seu App, você recebe um token por loja. É ele que vai noAuthorization: Bearerde cada chamada, agindo em nome daquela loja.
access_token + refresh_token por cliente/loja.Gerando o code_verifier e code_challenge (PKCE)
Antes de redirecionar o lojista, gere um par de valores PKCE no seu backend. O code_verifier fica com você; o code_challenge é enviado na URL de autorização.
import { randomBytes, createHash } from "node:crypto"
function generatePkce() {
const verifier = randomBytes(32).toString("base64url") // 43-128 chars
const challenge = createHash("sha256")
.update(verifier)
.digest("base64url")
return { verifier, challenge }
}
const { verifier, challenge } = generatePkce()
// Armazene o verifier na sessão — você vai precisar dele na Etapa 2Visão geral do fluxo
- •
1. Redirecione o lojista para a tela de autorização
Envie o lojista para o endpoint de autorização com os parâmetros do seu App:
GET /oauth/authorizehttps://app.sellitbr.com/oauth/authorize ?response_type=code &client_id=SEU_CLIENT_ID &redirect_uri=https://seuapp.com/oauth/callback &scope=products:read products:write stock:write &state=UM_VALOR_ALEATORIO &code_challenge=CHALLENGE_GERADO_ACIMA &code_challenge_method=S256O lojista verá os escopos solicitados e poderá autorizar ou negar. Em seguida será redirecionado para sua
redirect_uri:Aprovadohttps://seuapp.com/oauth/callback?code=ac_...&state=SEU_STATENegadohttps://seuapp.com/oauth/callback?error=access_denied&state=SEU_STATEVerifique sempre o parâmetro
errorantes de tentar trocar o code. O code expira em 10 minutos e só pode ser usado uma vez. - •
2. Troque o code por tokens
No seu backend, troque o
codepor um access token. Envie aclient_secretapenas server-side.POST /api/oauth/tokencurl -X POST https://app.sellitbr.com/api/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d grant_type=authorization_code \ -d client_id=SEU_CLIENT_ID \ -d client_secret=SUA_CLIENT_SECRET \ -d code=O_CODE_RECEBIDO \ -d redirect_uri=https://seuapp.com/oauth/callback \ -d code_verifier=O_VERIFIER_DO_PKCE200 OK{ "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "rt_...", "scope": "products:read products:write stock:write" } - •
3. Chame a API com o Bearer token
GET /api/v1/productscurl https://app.sellitbr.com/api/v1/products \ -H "Authorization: Bearer SEU_ACCESS_TOKEN" - •
4. Renove o token quando expirar
O access token dura 2 horas. O refresh token dura 30 dias e é rotativo: cada uso emite um novo par (
access_token+refresh_token). Sempre salve o novorefresh_tokenrecebido — o anterior é invalidado imediatamente.POST /api/oauth/tokencurl -X POST https://app.sellitbr.com/api/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d grant_type=refresh_token \ -d client_id=SEU_CLIENT_ID \ -d client_secret=SUA_CLIENT_SECRET \ -d refresh_token=SEU_REFRESH_TOKEN200 OK{ "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "rt_NOVO_TOKEN", "scope": "products:read products:write stock:write" }Se o refresh token expirar (30 dias sem uso) ou for usado mais de uma vez, a resposta retorna400 invalid_grant. Nesse caso, o lojista precisa reautorizar o seu App.
Escopos disponíveis
Solicite apenas os escopos que seu App realmente precisa. O lojista consente cada um.
| Escopo | Permite |
|---|---|
| products:read | Ler produtos |
| products:write | Criar e editar produtos |
| stock:write | Atualizar estoque |
| categories:read | Ler categorias |
| customers:read | Ler clientes |
| orders:read | Ler pedidos |
| orders:write | Atualizar status e reembolsar pedidos |
| shipping:read | Consultar fretes e rastreamento |
| shipping:write | Gerar etiquetas e atualizar envios |
| media:write | Enviar imagens de produtos |
| webhooks:manage | Gerenciar webhooks |
403 insufficient_scope. Token ausente, expirado ou revogado retorna 401 invalid_token.Erros do token endpoint
O endpoint POST /api/oauth/token retorna erros no formato RFC 6749: { "error": "...", "error_description": "..." }.
| Escopo | Permite |
|---|---|
| invalid_client | client_id ou client_secret incorretos. |
| invalid_grant | code ou refresh_token inválido, expirado ou já usado. Para authorization_code, também cobre PKCE incorreto. |
| invalid_request | Parâmetros obrigatórios ausentes (ex.: grant_type, code). |
| unsupported_grant_type | grant_type não é authorization_code nem refresh_token. |