Autenticação
A InfraIO Pay tem duas superfícies de API com modelos de autenticação diferentes. Escolha a que combina com quem está chamando:
| Superfície | Prefixo do path | Audiência | Auth |
|---|---|---|---|
| B2B do lojista | /b2b/v1/* | Seu servidor | Assinatura de requisição HMAC-SHA256 |
| Dashboard | Usada pelo dashboard do lojista | Sessões de navegador para o dashboard do lojista | Bearer JWT |
Esta página cobre a superfície B2B, a que você chama do seu servidor com um par de chaves de API. A superfície do dashboard é usada pelo dashboard do lojista da InfraIO Pay e não é uma superfície pública de integração.
Envie sempre o path completo, incluindo o prefixo /b2b, e assine esse
mesmo path (veja abaixo).
Endpoints
| Ambiente | Base URL |
|---|---|
| Teste | https://api-dev.infraio.xyz |
| Live | https://api.infraio.xyz |
Mesmo padrão de URL — o ambiente é controlado pelo prefixo da
chave (pk_test_… vs pk_live_…), não pela URL.
Par de chaves
Você pega dois valores no dashboard do lojista (Developers → API keys → + Add key):
- Chave publicável (
pk_test_…oupk_live_…) — identifica a sua conta. Enviada comoX-Client-ID. Seguro embutir no seu bundle do navegador (o SDK já faz isso). - Chave secreta (
sk_test_…ousk_live_…) — a chave de assinatura HMAC. Só servidor. Trate como uma senha de banco de dados.
Se uma chave secreta cair num bundle de navegador, repo git, linha de log ou chat compartilhado — revogue imediatamente no dashboard. A revogação é instantânea, sem janela de sobreposição. Crie uma chave nova e redeploye.
Assinando uma requisição
Toda chamada para /b2b/v1/* leva três headers:
X-Client-ID: pk_live_70d0becbd7a53047b0dfe88a960d10ad
X-Timestamp: 1715990400
X-Signature: 9a8b7c6d… (hex HMAC-SHA256)A assinatura é calculada sobre uma string canônica:
METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODYMETHOD— verbo HTTP em maiúsculas (POST,GET, …).PATH— path da requisição incluindo o prefixo/b2b, sem o host e sem a query string (por exemplo,/b2b/v1/checkout-sessions/quick). O prefixo precisa estar presente. Parâmetros de query não são assinados — para umGET …?cursor=…&limit=20, assine só o path, não a parte?….TIMESTAMP— unix segundos, como string decimal (por exemplo,"1715990400"), batendo exatamente com oX-Timestamp.BODY— bytes brutos do body da requisição. String vazia paraGET/DELETE.
Assine com HMAC-SHA256 chaveado pela chave secreta, saída hex:
Node / TS
import { createHmac } from "node:crypto";
function sign({ method, path, body, secret }: {
method: string; path: string; body: string; secret: string;
}) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const input = [method.toUpperCase(), path, timestamp, body].join("\n");
const signature = createHmac("sha256", secret).update(input).digest("hex");
return { timestamp, signature };
}Por que HMAC, e não Bearer?
Uma API de token Bearer puro envia o seu único segredo pela rede em toda requisição. Quem capturar um log de proxy com terminação TLS ganha as chaves da sua conta. Assinar com HMAC significa que o segredo nunca viaja — só a assinatura derivada dele, que é de uso único (vinculada àquela requisição exata + aquele minuto exato).
O trade-off: você calcula uma assinatura a cada chamada. Ainda não há um SDK de servidor, mas o helper acima tem cerca de 15 linhas por linguagem.
Tolerância do timestamp
A tolerância é de ±5 minutos (300 segundos). Uma requisição fora
dessa janela é rejeitada com 401 invalid_signature. Duas
implicações:
- Sincronize o relógio do seu servidor via NTP. Um cron de longa duração com relógio desviado vai falhar intermitentemente.
- Não pré-compute e enfileire assinaturas. Se uma requisição fica numa fila de retry por mais de 5 min, a assinatura expira.
Escopos de chave
Chaves secretas carregam um ou mais destes bundles de escopo:
| Escopo | Uso pretendido |
|---|---|
read | Listar/ler pedidos, sessões, reembolsos |
write_order | Criar sessões de checkout, pedidos |
write_refund | Emitir reembolsos, criar tokens de pedido de reembolso |
webhook_manage | Criar/atualizar/deletar endpoints de webhook |
O dashboard emite uma chave “full access” por padrão (os quatro escopos). Você pode criar uma chave com escopo restrito em Developers → API keys → + Add key e marcar só os escopos que a integração precisa.
Os escopos ainda não são aplicados. Os escopos são registrados na
chave e exibidos no dashboard, mas qualquer chave sk_… válida pode
chamar qualquer endpoint /b2b/v1/* do seu lojista. Não conte com os
escopos como fronteira de segurança. Rotacione ou revogue chaves para
restringir o acesso.
Falha na verificação
Se a assinatura, o X-Client-ID ou o timestamp forem inválidos, a
requisição é rejeitada com 401 INVALID_SIGNATURE antes de chegar
à API. Somente as requisições /b2b/v1/* são assinadas dessa forma.
Os webhooks usam um esquema separado (veja abaixo).
Próximos passos
- Erros — formato da resposta em 4xx/5xx.
- Segurança → Chaves de API — rotação, revogação, o que fazer se um segredo vaza.
- Webhooks → Verificação de assinatura
— usa um esquema HMAC diferente (header
X-Signature: sha256=…, assinaX-Timestamp + "." + raw_body, mais umX-Signature-Prevopcional durante a janela de tolerância de 24 horas da rotação). Não misture os esquemas — eles compartilham o algoritmo de hash mas os bytes assinados e a família de segredos (whsec_…vssk_…) são diferentes.