API de pagamentos PIX
Gere cobranças PIX, acompanhe transações e publique checkouts — com uma única chave de API, respostas previsíveis e liquidação instantânea, rodando na edge.
X-Api-Key
Base: https://app.junglepagamentos.com/api
Introdução
A API é REST, aceita e devolve JSON e vive sob a URL base:
https://app.junglepagamentos.com/apiToda resposta segue o mesmo envelope. Em sucesso, os dados vêm em data;
em erro, a mensagem vem em error.
{
"success": true,
"data": { ... }
}
{
"success": false,
"error": "Mensagem legível"
}
49.90), não em centavos.
Datas são ISO 8601 em UTC (ex.: 2026-07-21T12:34:56.000Z).Autenticação
Autentique cada requisição com sua chave de API no header X-Api-Key.
Gere/rotacione a chave no painel do seller, em Configurações → API.
A chave identifica sua conta e a adquirente ativa; trate-a como segredo.
X-Api-Key: sua_chave_de_api
X-Api-Key retornam 401.
Conta inativa/pendente retorna 403. Nunca exponha a chave no front-end.Para máxima segurança, você pode assinar cada requisição (anti-replay). É opcional e retrocompatível — veja Assinatura anti-replay.
Respostas & erros
Os códigos HTTP seguem a semântica REST:
| Código | Significado |
|---|---|
200 | OK — leitura bem-sucedida (ou replay idempotente de uma cobrança). |
201 | Created — cobrança/sessão criada. |
401 | Não autenticado — X-Api-Key ausente ou inválida. |
403 | Conta não ativa. |
404 | Recurso não encontrado (ex.: transação inexistente ou de outra conta). |
409 | Conflito de Idempotency-Key — veja Idempotência. |
422 | Payload inválido (validação de campos). |
429 | Rate limit excedido — veja Retry-After. |
500 | Erro interno ou falha da adquirente. |
Rate limiting
Os endpoints públicos são limitados por IP em janela fixa. Ao exceder, a API responde
429 com um header Retry-After (segundos). Implemente
backoff exponencial e respeite o Retry-After.
POST Criar cobrança PIX
Cria uma transação PIX e devolve o código copia-e-cola para o pagador.
/gateway/chargesCorpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
product.name obrigatório | string | Nome do produto/pedido. |
product.value obrigatório | number | Valor em reais (ex.: 49.90). |
customer.name obrigatório | string | Nome completo do cliente. |
customer.email obrigatório | string | E-mail válido. |
customer.doc obrigatório | string | CPF ou CNPJ (mín. 11 dígitos). |
customer.docType opcional | "cpf"|"cnpj" | Padrão cpf. |
customer.phone opcional | string | Telefone (DDD + número, só dígitos). |
customer.zip/street/district/city opcional | string | Endereço de faturamento. customer.number e customer.state não são aceitos por esta rota: se enviados, são descartados silenciosamente (sem erro). |
metadata opcional | object | Objeto livre, devolvido nas consultas. |
expiracaoSegundos opcional | number | Validade do QR em segundos. Padrão 3600. |
callbackUrl opcional | string (URL) | URL para receber a notificação de pagamento. Veja Webhooks. |
notifyMed opcional | boolean | Padrão false. Com true (e callbackUrl informada), esta cobrança passa a receber também o webhook transaction.med. Veja Webhooks. |
Headers
| Header | Descrição |
|---|---|
X-Api-Key obrigatório | Sua chave de API. |
Idempotency-Key opcional | Chave única por cobrança para retry seguro. Veja Idempotência. |
Exemplo
curl -X POST https://app.junglepagamentos.com/api/gateway/charges \
-H "X-Api-Key: sua_chave_de_api" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7f3c9a2e-5b1d-4c8a-9e0f-2d6b4a1c8e53" \
-d '{
"product": { "name": "Plano Pro", "value": 49.90 },
"customer": {
"name": "Ana Souza",
"email": "ana@exemplo.com",
"doc": "12345678909",
"docType": "cpf",
"phone": "11987654321"
},
"expiracaoSegundos": 3600,
"callbackUrl": "https://sualoja.com/webhooks/pix"
}'
const res = await fetch("https://app.junglepagamentos.com/api/gateway/charges", {
method: "POST",
headers: {
"X-Api-Key": "sua_chave_de_api",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(), // opcional; reuse o mesmo valor nos retries
},
body: JSON.stringify({
product: { name: "Plano Pro", value: 49.90 },
customer: {
name: "Ana Souza",
email: "ana@exemplo.com",
doc: "12345678909",
docType: "cpf",
phone: "11987654321",
},
expiracaoSegundos: 3600,
}),
});
const { data } = await res.json();
console.log(data.pixCode);
Resposta 201
{
"success": true,
"data": {
"transactionId": "a1b2c3d4-e5f6-...", // use para consultar o status
"pixCode": "00020101...6304ABCD", // copia-e-cola / gere o QR
"expiresAt": "2026-07-21T12:34:56.000Z",
"amount": 49.90, // valor bruto (reais)
"feeAmount": 1.75, // taxa do gateway
"netAmount": 48.15 // líquido do seller
}
}
pixCode é o BR Code (copia-e-cola). Gere o QR a partir dele no
seu front, ou exiba o texto para o cliente colar no app do banco.Idempotência opcional
Envie o header Idempotency-Key para repetir a criação com segurança (timeout,
queda de conexão) sem gerar cobrança duplicada. Sem o header, nada muda.
- Formato: de 1 a 255 caracteres ASCII visíveis
(
0x21–0x7E, sem espaço). Um valor fora disso é ignorado — a requisição é tratada como se não tivesse o header, e a resposta (mesmo status e corpo) traz o headerIdempotency-Key-Status: ignored. Sem o header na requisição, ele não aparece. - Mesmo payload: a ordem das chaves dos objetos JSON não importa; a ordem dos itens de arrays importa.
- Escopo: a conta (workspace) da chave de API.
- Validade: permanente — a chave não expira; use um valor novo por cobrança (ex.: UUID).
- Assinatura: o header fica fora do texto canônico da
assinatura. Um retry assinado precisa de
X-NonceeX-Timestampnovos.
| Resposta | Quando |
|---|---|
201 | Sem chave, ou primeira requisição com a chave — cobrança criada, como sempre. |
200 | Replay: mesma chave e mesmo payload. data idêntico ao do 201 original,
com o header Idempotent-Replayed: true. Nenhuma cobrança nova é criada e nenhum webhook é disparado. |
409 | "Idempotency-Key already used with a different payload" — a chave já foi usada com outro corpo. |
409 | "A charge with this Idempotency-Key is still being processed" — a primeira requisição ainda não terminou; aguarde e repita. Se a cobrança seguir sem PIX por mais de
5 minutos, a resposta passa a ser previous_failed (abaixo): use uma chave nova. |
409 | "The charge for this Idempotency-Key failed; retry with a new Idempotency-Key" — a criação original falhou; tente de novo com outra chave. |
Idempotency-Key: 7f3c9a2e-5b1d-4c8a-9e0f-2d6b4a1c8e53
GET /gateway/transactions/:id.GET Consultar transação
Devolve uma única transação pelo id (o transactionId recebido na
criação). É a forma recomendada de polling e de reconciliação — não há janela de 30 dias.
/gateway/transactions/:idcurl "https://app.junglepagamentos.com/api/gateway/transactions/a1b2c3d4-e5f6-..." \
-H "X-Api-Key: sua_chave_de_api"
{
"success": true,
"data": {
"id": "a1b2c3d4-...",
"status": "PAID",
// ... mesmos campos de cada item da listagem
"createdAt": "2026-07-21T11:34:56.000Z",
"updatedAt": "2026-07-21T12:10:03.000Z"
}
}
{ "success": false, "error": "Transaction not found" }
GET Listar transações
Lista as transações da sua conta com paginação. A ordem é contrato:
createdAt decrescente e, no empate, id decrescente. Use este endpoint
para reconciliação e sincronização incremental; para uma cobrança específica, prefira
GET /gateway/transactions/:id.
/gateway/transactions?page=1&limit=20| Query | Tipo | Descrição |
|---|---|---|
page opcional | number | Página, inteiro ≥ 1. Qualquer outro valor vira 1. |
limit opcional | number | Itens por página, de 1 a 100. Acima de 100 vira 100; 0, negativo ou não numérico vira 20 (padrão). |
status opcional | string | Filtra por PENDING, PAID, FAILED, EXPIRED ou MED (sem diferenciar maiúsculas). Valor inválido é ignorado. |
updatedSince opcional | string (ISO 8601) | Só transações com updatedAt ≥ esta data (o mesmo updatedAt devolvido nos itens). Data ilegível é ignorada. Piso de 90 dias: data anterior a agora − 90 dias é tratada como agora − 90 dias (o valor efetivo volta em meta.filters.updatedSince). |
updatedSince, a listagem cobre só os
últimos 30 dias por createdAt. Com updatedSince, essa janela não se aplica.O objeto meta traz { total, page, limit, pages }. Quando você envia
status ou updatedSince, meta ganha também
filters: { status, updatedSince } com os valores aplicados — null
indica que o parâmetro foi ignorado por ser inválido.
curl "https://app.junglepagamentos.com/api/gateway/transactions?page=1&limit=20" \
-H "X-Api-Key: sua_chave_de_api"
{
"success": true,
"data": [
{
"id": "a1b2c3d4-...",
"status": "PAID",
"acquirerId": "zorapay",
"productName": "Plano Pro",
"amount": 49.90, "feeAmount": 1.75, "netAmount": 48.15,
"pixCode": "00020101...6304ABCD",
"pixExpiresAt": "2026-07-21T12:34:56.000Z",
"paidAt": "2026-07-21T12:10:03.000Z",
"customer": { "name": "Ana Souza", "email": "ana@exemplo.com" },
"metadata": { ... },
"createdAt": "2026-07-21T11:34:56.000Z",
"updatedAt": "2026-07-21T12:10:03.000Z"
}
],
"meta": { "total": 128, "page": 1, "limit": 20, "pages": 7 }
}
Sincronização incremental
- Guarde o maior
updatedAtque você já viu. - Consulte
?updatedSince=com esse valor menos uma pequena sobreposição (ex.: 1–2 minutos), percorrendo todas as páginas. - Deduplique pelo
ide atualize o seu maiorupdatedAt.
curl "https://app.junglepagamentos.com/api/gateway/transactions?updatedSince=2026-07-21T12:08:00.000Z&status=paid&limit=100" \
-H "X-Api-Key: sua_chave_de_api"
// meta: { "total": 3, "page": 1, "limit": 100, "pages": 1,
// "filters": { "status": "PAID", "updatedSince": "2026-07-21T12:08:00.000Z" } }
POST Checkout hospedado
Em vez de gerar o PIX você mesmo, crie uma sessão de checkout e redirecione o
cliente para uma página de pagamento hospedada (com seu template, order bumps, etc.).
A sessão referencia um checkoutId criado no painel.
/checkout/sessions| Campo | Tipo | Descrição |
|---|---|---|
checkoutId obrigatório | string | ID do template de checkout (painel). |
products obrigatório | array | Itens da compra (nome, valor, quantidade). |
customer opcional | object | Dados pré-preenchidos (nome, email, doc, phone). |
{
"success": true,
"data": {
"sessionId": "8feccd9e-...",
"amount": 202.40,
"checkoutUrl": "https://app.junglepagamentos.com/c/8feccd9e-..."
}
}
checkoutUrl. Se o checkout tiver
domínio próprio configurado, a URL já virá com ele.Status de pagamento
Toda transação passa por um destes estados:
| Status | Significado |
|---|---|
| PENDING | Cobrança criada, aguardando o pagamento do cliente. |
| PAID | Pagamento confirmado. paidAt preenchido. |
| FAILED | Falha ao processar / cancelada / estornada. |
| EXPIRED | O QR expirou sem pagamento. |
| MED | Pagamento contestado/devolvido (MED do PIX / chargeback) após ter sido pago. |
Webhooks
Informe uma callbackUrl ao criar a cobrança para ser notificado quando o
status mudar. Anexamos um token à sua URL — valide-o para garantir que a
chamada veio da Jungle Pagamentos.
POST https://sualoja.com/webhooks/pix?token=<token-de-verificacao>
// Responda 2xx para confirmar o recebimento.
Eventos
| Evento | Quando |
|---|---|
transaction.created | Cobrança criada. |
transaction.paid | Pagamento confirmado. |
transaction.failed | Falha / cancelamento. |
transaction.expired | PIX expirou sem pagamento. |
transaction.med opt-in | MED / chargeback: a transação passou a MED.
Payload idêntico aos demais transaction.*, com data.status = "MED".
Pode chegar mais de uma vez: trate de forma idempotente por transactionId + event.
Só é enviado se a cobrança foi criada com notifyMed: true e callbackUrl. |
2xx e siga em frente):
novos eventos podem ser adicionados.Política de entrega
- Até 3 tentativas: espera de 0,5 s antes da 2ª e de 2 s antes da 3ª.
- Timeout de 10 s por tentativa; orçamento total de 15 s por entrega.
- Nova tentativa só em erro de rede, timeout ou resposta
5xx. 2xxe4xxsão finais — um4xxnão é reenviado.3xx: seguimos 1 redirecionamento, desde que para um host público; caso contrário é final.
GET /gateway/transactions/:id ou por
?updatedSince. E não confie apenas no webhook para
liberar o produto: confirme o status consultando a transação antes de entregar.Assinatura anti-replay opcional
Para blindar contra replay, assine a requisição. Se você enviar X-Signature,
exigimos também X-Timestamp e X-Nonce. Clientes que não assinam
continuam funcionando normalmente.
| Header | Descrição |
|---|---|
X-Timestamp | Epoch em ms. Aceito dentro de ±5 min do horário do servidor. |
X-Nonce | Valor único por requisição (evita reuso). |
X-Signature | HMAC-SHA256 (hex) do texto canônico, usando a chave de API crua como segredo. |
{METHOD}\n{path}\n{body}\n{X-Timestamp}\n{X-Nonce}
# ex.: POST\n/api/gateway/charges\n{"product":...}\n1737460000000\nabc123
Idempotency-Key não entra no texto canônico. Ao repetir
uma requisição assinada, gere X-Timestamp e X-Nonce novos (e a assinatura correspondente).X-Api-Key (padrão).
A assinatura é uma camada extra recomendada para integrações server-to-server sensíveis.Boas práticas
- Valores em reais. Envie
valuecomo49.90, não em centavos. - Guarde o
transactionId. É a chave para conciliar o pagamento. - Use
Idempotency-Keynos retries. Repetir a criação com a mesma chave (e o mesmo corpo) não duplica a cobrança. - Não libere só pelo webhook. Confirme o
statusantes de entregar. - Dados do cliente reais. CPF válido, nome completo e telefone (DDD + número) evitam recusa da adquirente.
- Respeite o
429. Faça backoff e honre oRetry-After. - Proteja a chave. Só no back-end; rotacione se vazar.
© Jungle Pagamentos — Documentação da API · PIX na edge da Cloudflare.