Documentação da API

Documentação da API

Integre pagamentos PIX à sua aplicação com a API da SyntraPay. Cobranças, links de checkout prontos para vender, saques, consulta de saldo, webhooks e monitoramento de infrações MED, tudo via REST.

URL base
https://api.syntrapay.com.br

Todos os valores monetários são inteiros em centavos (ex.: 1490 = R$ 14,90). As respostas usam JSON.

Autenticação

Autentique cada requisição enviando sua chave de API no header Authorization, sem o prefixo Bearer. Gere e gerencie suas chaves no painel em Integrações → Credenciais.

Authorization: sk_live_sua_chave_aqui

Exemplo: primeira cobrança

curl -X POST https://api.syntrapay.com.br/transactions \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 1490 }'

Escopos

Cada chave de API possui escopos que definem quais ações ela pode executar. Selecione os escopos ao criar a chave e conceda apenas o necessário.

payments.createCriar cobranças PIX.
payments.readConsultar cobranças e transações.
transfers.readConsultar transferências.
withdrawals.createCriar saques PIX.
withdrawals.readConsultar saques.
webhooks.manageGerenciar webhooks.
links.readConsultar links de pagamento, métricas e checkouts.
links.manageCriar, editar, duplicar, apagar e restaurar links de pagamento.
Novo · integração assistida por IA

Implementar com IA

Deixe a IA escrever a integração pra você. Escolha o que quer fazer e a linguagem: geramos um prompt com todo o contexto da API já embutido (endpoints, parâmetros, exemplos e regras). Copie e cole no seu assistente, ou abra direto no ChatGPT ou Claude.

1

Escolha a tarefa

Selecione o que quer construir e a sua linguagem.

2

Copie o prompt

Já vem com todo o contexto da API. Ou abra direto no ChatGPT/Claude.

3

Cole e rode

A IA devolve o código pronto. Ajuste sua chave e publique.

Gerador de prompt

O que você quer fazer?

Linguagem

Você é um engenheiro de software sênior. Implemente uma integração com a API de pagamentos PIX da SyntraPay em Node.js (use o fetch nativo; se for API do Next.js, use Route Handlers em app/api).

OBJETIVO: criar uma cobrança PIX e mostrar o QR Code e o código copia-e-cola para o pagador.

CONTEXTO DA API:
- Base URL: https://api.syntrapay.com.br
- Autenticação: envie a chave no header "Authorization: sk_live_sua_chave_aqui" (SEM o prefixo Bearer).
- Todos os valores monetários são inteiros em centavos (ex.: 1490 = R$ 14,90).
- Requisições e respostas em JSON.

ENDPOINTS ENVOLVIDOS:
### Criar cobrança — POST /transactions
Cria uma cobrança PIX e retorna o QR Code (base64) e o código copia-e-cola para o pagador. O valor é sempre em centavos.
Escopo necessário: payments.create
Parâmetros:
    - amount (integer, obrigatório, em body): Valor em centavos (mín. 100 = R$ 1,00). Ex.: 1490 = R$ 14,90.
    - webhook (string, em body): URL para notificar quando o pagamento for aprovado (sobrescreve o webhook global desta cobrança).
    - split_email (string, em body): E-mail de outra conta SyntraPay para dividir o valor (split).
    - split_tax (integer, em body): Percentual destinado ao parceiro no split (1 a 99, padrão 50).
    - customer (object, em body): Dados do pagador para rastreio (name, document). Opcional.
    - products (array, em body): Itens da venda, usados por integrações de tracking (ex.: Utmify).
    - trackingParameters (object, em body): UTMs da campanha (utm_source, utm_medium, etc.).
    - Idempotency-Key (string, em header): Chave única sua para evitar cobranças duplicadas em reenvios. A resposta é repetida por 24h para a mesma chave.
Exemplo de corpo: {"amount":1490}
Resposta 201 Created:
{
  "message": "Transaction created successfully",
  "status": "pending",
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "amount": 1490,
  "qrCodeBase64": "data:image/png;base64,iVBORw0KGgoAAA...",
  "copyPaste": "00020126580014br.gov.bcb.pix...6304ABCD",
  "expiresAt": "2026-07-18T15:30:00.000Z",
  "fee": 44,
  "storeId": "usr_a1b2c3"
}

REQUISITOS:
- Código pronto para produção, organizado e comentado em português.
- Trate erros pelo envelope { status, code, message } e pelos códigos HTTP retornados.
- Em requisições POST, envie um header "Idempotency-Key" único para evitar duplicidade em reenvios.
- Leia a chave de API de uma variável de ambiente (nunca deixe hardcoded).
- Ao final, mostre um exemplo de uso.

Se faltar alguma informação, me pergunte antes de assumir.
Contexto completo da API

Prefere entregar tudo de uma vez? Copie a referência inteira (auth, endpoints, exemplos, webhooks e erros) e cole no seu assistente ou agente de IA. Depois é só pedir qualquer integração, que ele já tem o contexto.

Funciona com ChatGPT, Claude, Cursor, GitHub Copilot, Windsurf e qualquer LLM que aceite contexto colado.

Cobranças (PIX)

Crie e consulte cobranças PIX. Todos os valores são inteiros em centavos (ex.: 1490 = R$ 14,90).

POST/transactions payments.create

Criar cobrança

Cria uma cobrança PIX e retorna o QR Code (base64) e o código copia-e-cola para o pagador. O valor é sempre em centavos.

Parâmetros

amountbodyobrigatório
integer: Valor em centavos (mín. 100 = R$ 1,00). Ex.: 1490 = R$ 14,90.
webhookbody
string: URL para notificar quando o pagamento for aprovado (sobrescreve o webhook global desta cobrança).
split_emailbody
string: E-mail de outra conta SyntraPay para dividir o valor (split).
split_taxbody
integer: Percentual destinado ao parceiro no split (1 a 99, padrão 50).
customerbody
object: Dados do pagador para rastreio (name, document). Opcional.
productsbody
array: Itens da venda, usados por integrações de tracking (ex.: Utmify).
trackingParametersbody
object: UTMs da campanha (utm_source, utm_medium, etc.).
Idempotency-Keyheader
string: Chave única sua para evitar cobranças duplicadas em reenvios. A resposta é repetida por 24h para a mesma chave.

Campos da resposta

id
string: Identificador único da cobrança.
status
string: Status inicial (pending).
amount
integer: Valor da cobrança em centavos.
qrCodeBase64
string: Imagem do QR Code em data URI (base64).
copyPaste
string: Código PIX copia-e-cola.
expiresAt
string: Data/hora de expiração (ISO 8601).
fee
integer: Taxa aplicada em centavos.
storeId
string: Identificador da sua conta.

Requisição

curl -X POST "https://api.syntrapay.com.br/transactions" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"amount":1490}'

Resposta

201 Created
{
  "message": "Transaction created successfully",
  "status": "pending",
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "amount": 1490,
  "qrCodeBase64": "data:image/png;base64,iVBORw0KGgoAAA...",
  "copyPaste": "00020126580014br.gov.bcb.pix...6304ABCD",
  "expiresAt": "2026-07-18T15:30:00.000Z",
  "fee": 44,
  "storeId": "usr_a1b2c3"
}
400 Bad Request
{
  "status": "error",
  "code": "BAD_REQUEST",
  "message": "400: Amount must be at least 100 cents (R$ 1,00)"
}
GET/transactions/:id payments.read

Consultar cobrança

Consulta os detalhes e o status atual de uma cobrança pelo seu ID. Ao fazer polling do status, use nocache=1 para ler sempre direto do banco.

Parâmetros

idpathobrigatório
string: ID da transação retornado na criação.
nocachequery
string: Defina como 1 para ignorar o cache (útil em polling de status).

Campos da resposta

id
string: Identificador da cobrança.
status
string: PENDING, PAID, FAILED, CANCELED ou EXPIRED.
amount
integer: Valor em centavos.
fee
integer: Taxa em centavos.
payer
object: Dados do pagador ({ name, document }).
paidAt
string: Data/hora do pagamento (ISO) ou null.

Requisição

curl -X GET "https://api.syntrapay.com.br/transactions/9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "status": "PAID",
  "type": "DEPOSIT",
  "reason": "PIX_PAYMENT",
  "amount": 1490,
  "fee": 44,
  "payer": { "name": "João da Silva", "document": "***.456.789-**" },
  "storeId": "usr_a1b2c3",
  "createdAt": "2026-07-18T14:30:00.000Z",
  "paidAt": "2026-07-18T14:31:12.000Z"
}
404 Not Found
{
  "status": "error",
  "code": "NOT_FOUND",
  "message": "404: Not Found - Transaction not found"
}
GET/transactions payments.read

Listar transações

Lista as transações da sua conta (cobranças e saques), com paginação e filtros opcionais.

Parâmetros

startquery
integer: Posição inicial (paginação). Padrão 1.
limitquery
integer: Itens por página. Padrão 50.
statusquery
string: Filtra por status (ex.: PENDING, PAID).
typequery
string: Filtra por tipo (DEPOSIT, WITHDRAWAL).
searchquery
string: Busca por ID ou nome do pagador.

Requisição

curl -X GET "https://api.syntrapay.com.br/transactions?limit=50&status=PAID" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "total": 128,
  "start": 1,
  "limit": 50,
  "count": 50,
  "transactions": [
    {
      "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
      "status": "PAID",
      "type": "DEPOSIT",
      "amount": 1490,
      "fee": 44,
      "createdAt": "2026-07-18T14:30:00.000Z"
    }
  ]
}

Checkout (links de pagamento)

Crie links de pagamento por API e receba sem escrever uma linha de front-end. Cada link vira uma página de checkout hospedada por nós, com o preço, as ofertas adicionais, a aparência e as regras que você definir. O preço vive no link: o comprador nunca envia valor.

1

Você cria o link

POST /payment-links com o título e o preço. A resposta traz o checkoutUrl.

2

O cliente paga

Ele abre a URL, preenche os dados e paga por PIX na página hospedada por nós.

3

Você é avisado

O saldo é creditado e o webhook payment.approved dispara com os dados da venda.

Endereço do checkout

https://pay.syntrapay.com.br/<publicId>
https://pay.syntrapay.com.br/<publicId>/<slug>

O publicId é a identidade do link e nunca muda: use sempre o checkoutUrl devolvido pela API. O slug é apenas decorativo, pode ser alterado ou removido a qualquer momento, e os endereços já divulgados continuam abrindo.

Regras do checkout

O preço vive no link, nunca na requisição do comprador: não existe forma de pagar um valor diferente do configurado.

Criação é deduplicada: a mesma configuração enviada de novo em até 24 horas devolve o link existente (HTTP 200, deduplicated: true) em vez de criar outro. Para forçar um segundo link igual, envie allowDuplicate: true.

O checkout também deduplica: o mesmo comprador pedindo a mesma cotação (mesmo valor, quantidade e ofertas) reaproveita a cotação aberta, então ele nunca fica com dois PIX para a mesma compra.

Valor mínimo de R$ 1,00 por cobrança. O teto é o limite por depósito da sua conta, aplicado no momento do pagamento (se o limite mudar, os links já criados passam a respeitar o novo valor).

Até 200 links não arquivados por conta e até 3 ofertas adicionais por link.

O corpo da requisição é limitado a 64 KB. Escritas: 30 por minuto por conta; leituras: 120 por minuto.

A conta precisa estar ativada para criar ou duplicar links.

Chaves de API criadas antes destes escopos não os possuem: marque links.read e links.manage em Integrações → Credenciais, ou gere uma chave nova.

Imagens, vídeos e redirecionamentos passam por validação de segurança: use URLs públicas e https.

Objeto do link: campos aninhados

Todos são opcionais na criação e na edição, e cada um tem um padrão pronto para vender. Na edição, o que você não enviar permanece como está.

appearance: aparência do checkout

themestring: "light" ou "dark". Padrão: light.
primaryColorstring: Cor dos botões e destaques no formato #RRGGBB. Padrão: #6D3BF5.
buttonTextstring: Texto do botão de pagamento, até 40 caracteres. Padrão: "Pagar agora".
summaryPositionstring: "above" ou "below": resumo do pedido acima ou abaixo dos dados do comprador.
showStepsboolean: Exibe as etapas Dados › Pagamento › Entrega. Padrão: true.

funnel: prova social

showOnlineCounterboolean: Exibe o contador de pessoas vendo a oferta agora.
onlineCounterMininteger: Piso do contador (1 a 999). Padrão: 12.
onlineCounterMaxinteger: Teto do contador (1 a 999, nunca menor que o piso). Padrão: 78.
showCompanyWatermarkboolean: Exibe a assinatura da SyntraPay no rodapé. Padrão: true.
showSecurityBadgeboolean: Exibe o selo de compra segura. Padrão: true.

media: vídeo e banner

videoUrlstring: Endereço do vídeo no YouTube ou no Vimeo. Envie null para remover.
videoProviderstring: Somente leitura: "youtube" ou "vimeo", detectado por nós.
videoEmbedUrlstring: Somente leitura: URL de incorporação que geramos a partir do vídeo enviado.
bannerUrlstring: Banner do topo do checkout (https). Recomendado 1200x300.

socialProof: barra de prova social

imageUrlstring: Imagem da barra (https), normalmente prints de depoimentos.
showOnCheckoutboolean: Exibe a barra na tela de checkout.
showOnPaymentTopboolean: Exibe a barra no topo da tela de pagamento PIX.

countdown: contador regressivo

enabledboolean: Liga o contador no topo do checkout.
minutesinteger: Duração em minutos (1 a 1440). Padrão: 15.
bgColorstring: Cor de fundo em #RRGGBB. Padrão: #111827.
textColorstring: Cor do texto em #RRGGBB. Padrão: #FFFFFF.
textAbovestring: Texto acima do relógio, até 80 caracteres.
textBelowstring: Texto abaixo do relógio, até 80 caracteres.
expiredTextstring: Texto exibido quando o tempo acaba, até 80 caracteres.

pixScreen: tela de pagamento PIX

showGuaranteeboolean: Exibe o selo de garantia.
guaranteeDaysinteger: Dias de garantia (1 a 365). Padrão: 7.
showTimerboolean: Exibe o cronômetro de validade do PIX. Padrão: true.
timerMinutesinteger: Minutos exibidos no cronômetro (1 a 1440). Padrão: 15.

fields: dados pedidos ao comprador

nameobject: { visible, required }: nome do comprador.
emailobject: Sempre visível e obrigatório. O cadastro do cliente e o e-mail de confirmação dependem dele, então o que for enviado aqui é ignorado.
phoneobject: { visible, required }: telefone.
documentobject: { visible, required }: CPF ou CNPJ.

postPayment: depois do pagamento

redirectUrlstring: Para onde levar o comprador após pagar (https obrigatório). Só é entregue depois que o pagamento é confirmado.
thankYouMessagestring: Mensagem da tela de obrigado, até 500 caracteres.
sendCustomerEmailboolean: Envia o e-mail de confirmação da compra ao comprador. Padrão: true.

orderBumps[]: ofertas adicionais (máximo 3)

idstring: Gerado por nós (bmp_…). Reenvie o id existente ao editar para preservar a oferta; um id desconhecido vira uma oferta nova.
titlestring: Obrigatório. Até 80 caracteres.
descriptionstring: Até 300 caracteres.
imageUrlstring: Imagem da oferta (https).
priceCentsinteger: Preço em centavos, mínimo 100. O teto é o limite por depósito da conta.
activeboolean: Se a oferta aparece no checkout. Padrão: true.

Venda pelo checkout no webhook

Uma venda feita por link dispara o mesmo evento payment.approved de qualquer cobrança, com dois campos a mais: origin igual a CHECKOUT_LINK e o objeto checkout, que diz qual link vendeu, o que foi comprado e quais ofertas adicionais entraram.

{
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "status": "PAID",
  "amount": 24600,
  "origin": "CHECKOUT_LINK",
  "checkout": {
    "paymentLinkId": "plk_7f3a91c25be04d18a6c3e07b",
    "checkoutSessionId": "chs_5b2e91a7c40d38f6",
    "customerId": "cus_3f81ba07d259",
    "publicId": "k7m2p9qx",
    "slug": "curso-completo",
    "priceMode": "fixed",
    "quantity": 1,
    "unitPriceCents": 19700,
    "baseCents": 19700,
    "bumps": [{ "id": "bmp_9c41ab7d02e5", "title": "Mentoria em grupo", "priceCents": 4900 }],
    "bumpsTotalCents": 4900
  }
}

Saques (PIX)

Envie saques PIX e consulte o histórico. Aceita CPF, CNPJ, e-mail, telefone, chave aleatória (EVP) ou copia-e-cola.

POST/withdrawals withdrawals.create

Criar saque

Realiza um saque via PIX para uma chave. O valor é em centavos e é descontado do seu saldo disponível junto com a taxa.

Parâmetros

pixKeybodyobrigatório
string: Chave de destino: CPF, CNPJ, e-mail, telefone, EVP ou copia-e-cola.
amountbodyobrigatório
integer: Valor em centavos (mín. 100 = R$ 1,00). Opcional só quando o copia-e-cola já traz o valor.
descriptionbody
string: Descrição que aparece para o recebedor.
webhookbody
string: URL para notificar quando o saque mudar de status.
Idempotency-Keyheader
string: Chave única sua para evitar saques duplicados em reenvios. A resposta é repetida por 24h para a mesma chave.

Campos da resposta

id
string: Identificador do saque.
status
string: Status inicial (pending).
amount
integer: Valor em centavos.
pixKey
string: Chave PIX de destino.
pixKeyType
string: Tipo detectado: CPF, CNPJ, EMAIL, TELEFONE, CHAVE_ALEATORIA ou COPIA_E_COLA.
fee
integer: Taxa do saque em centavos.

Requisição

curl -X POST "https://api.syntrapay.com.br/withdrawals" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"pixKey":"cliente@email.com","amount":5000}'

Resposta

201 Created
{
  "message": "Withdraw request created successfully",
  "status": "pending",
  "id": "f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f",
  "amount": 5000,
  "pixKey": "cliente@email.com",
  "pixKeyType": "EMAIL",
  "fee": 250
}
400 Bad Request
{
  "status": "error",
  "code": "INSUFFICIENT_FUNDS",
  "message": "400: Saldo insuficiente para realizar o saque"
}
GET/withdrawals withdrawals.read

Listar saques

Lista os saques da sua conta, com paginação.

Parâmetros

startquery
integer: Posição inicial (paginação). Padrão 1.
limitquery
integer: Itens por página. Padrão 50.

Requisição

curl -X GET "https://api.syntrapay.com.br/withdrawals" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "total": 12,
  "start": 1,
  "limit": 50,
  "count": 12,
  "withdrawals": [
    {
      "id": "f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f",
      "type": "WITHDRAWAL",
      "status": "PAID",
      "amount": 5000,
      "fee": 250,
      "payer": { "pixKey": "cliente@email.com", "pixKeyType": "EMAIL" },
      "end_to_end": "E12345678202607181430...",
      "createdAt": "2026-07-18T14:30:00.000Z",
      "paidAt": "2026-07-18T14:30:20.000Z"
    }
  ]
}
GET/withdrawals/:id withdrawals.read

Consultar saque

Consulta os detalhes e o status de um saque pelo seu ID.

Parâmetros

idpathobrigatório
string: ID do saque retornado na criação.

Campos da resposta

id
string: Identificador do saque.
status
string: PENDING, PAID, FAILED, CANCELED ou EXPIRED.
amount
integer: Valor em centavos.
taxes
integer: Taxa cobrada em centavos.
pixKey
string: Chave PIX de destino.
pixKeyType
string: Tipo da chave.
receiver
object: Dados do recebedor ({ name, document }).
paidAt
string: Data/hora da liquidação (ISO) ou null.

Requisição

curl -X GET "https://api.syntrapay.com.br/withdrawals/f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

201 Created
{
  "id": "f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f",
  "withdrawStatusId": "Successfull",
  "status": "PAID",
  "amount": 5000,
  "taxes": 250,
  "pixKey": "cliente@email.com",
  "pixKeyType": "EMAIL",
  "receiver": { "name": "Maria Souza", "document": "***.123.456-**" },
  "paidAt": "2026-07-18T14:30:20.000Z"
}
404 Not Found
{
  "status": "error",
  "code": "NOT_FOUND",
  "message": "404: Not Found - Withdrawal not found"
}

Saldo

POST/balance

Consultar saldo

Consulta o saldo da sua conta: disponível, bloqueado, em análise (MED) e total. Não requer corpo na requisição.

Campos da resposta

balance_available
number: Saldo disponível para saque.
balance_locked
number: Saldo bloqueado (lock de tempo).
balance_infractions
number: Saldo retido por infrações MED.
netBalance
number: Saldo líquido.

Requisição

curl -X POST "https://api.syntrapay.com.br/balance" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "codeStatus": 200,
  "balance": {
    "id": "usr_a1b2c3",
    "balance": 1530.50,
    "balance_available": 1530.50,
    "balance_locked": 0,
    "balance_infractions": 0,
    "totalBalances": 8240.00,
    "netBalance": 1530.50,
    "fees": { "saque": 250 }
  }
}

MED: Infrações PIX

Consulte as infrações MED (Mecanismo Especial de Devolução) registradas nas suas transações. Valores em centavos.

GET/infractions

Listar infrações

Lista as infrações MED da sua conta, com um resumo agregado e paginação por intervalo (from/to).

Parâmetros

fromquery
integer: Índice inicial (0-based). Padrão 0.
toquery
integer: Índice final (inclusivo). Padrão 10.
statusquery
string: Filtra por status (ex.: WAITING_PSP, COMPLETED) ou "all".

Campos da resposta

summary.totalCount
integer: Total de infrações.
summary.totalAmount
integer: Soma dos valores (centavos).
summary.waitingPsp
integer: Infrações aguardando o PSP.
summary.completed
integer: Infrações concluídas.
data[].infractionId
string: ID da infração.
data[].type
string: Tipo (ex.: FRAUD, SCAM).
data[].status
string: Status atual da infração.
data[].endToEndId
string: E2E do PIX relacionado.
data[].amount
integer: Valor em centavos.
data[].payerName
string: Nome do pagador (quando disponível).
data[].linkedTransactionId
string: ID da transação vinculada.

Requisição

curl -X GET "https://api.syntrapay.com.br/infractions?from=0&to=10&status=all" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "summary": {
    "totalCount": 3,
    "totalAmount": 45000,
    "waitingPsp": 1,
    "completed": 2
  },
  "range": { "total": 3, "from": 0, "to": 10 },
  "data": [
    {
      "infractionId": "inf_9a8b7c6d",
      "type": "FRAUD",
      "status": "WAITING_PSP",
      "endToEndId": "E12345678202607181430...",
      "reportedBy": "PACS",
      "amount": 15000,
      "currency": "BRL",
      "creationDate": "2026-07-18T12:00:00.000Z",
      "payerName": "João da Silva",
      "linkedTransactionId": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d"
    }
  ]
}

Webhooks

Configure endpoints para receber eventos em tempo real. Ao criar, enviamos um POST de teste. Sua URL deve responder 200/201/202. Cada disparo inclui o header syntrapay-webhook-secret.

Eventos disponíveis

payment.approvedUma cobrança PIX foi paga e o valor creditado.
payment.failedA cobrança falhou, expirou ou foi cancelada.
transfer-approvedUm saque PIX foi concluído com sucesso.
transfer-failedUm saque PIX falhou ou foi rejeitado.
pix.infractionUma infração MED foi registrada em uma transação sua.

Cada disparo inclui os headers syntrapay-signature (sha256=…), syntrapay-timestamp e syntrapay-webhook-secret. A assinatura é o HMAC-SHA256 de `${timestamp}.${corpo_bruto}` usando o signing secret do webhook: valide-a e rejeite timestamps antigos (replay).

Verificar a assinatura (Node.js)

import crypto from "crypto"

function verifyWebhook(rawBody, headers, secret) {
  const ts = headers["syntrapay-timestamp"]
  const sig = (headers["syntrapay-signature"] || "").replace("sha256=", "")
  const expected = crypto
    .createHmac("sha256", secret)
    .update(ts + "." + rawBody)   // HMAC de `${ts}.${corpo}`
    .digest("hex")
  const ok =
    sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
  // Rejeite se !ok ou se |agora - ts| > 300s (replay)
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300
  return ok && fresh
}
GET/webhooks webhooks.manage

Listar webhooks

Lista os webhooks da sua conta. O signing secret é retornado mascarado.

Requisição

curl -X GET "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "webhooks": [
    {
      "id": "665fbe1c9a2d4e0012ab34cd",
      "url": "https://seusite.com/webhooks/syntrapay",
      "events": ["payment.approved", "payment.failed"],
      "active": true,
      "secret": "whsec_ab12...cd34",
      "createdAt": "2026-07-01T10:00:00.000Z"
    }
  ]
}
POST/webhooks webhooks.manage

Criar webhook

Cria um webhook. O signing secret completo é retornado apenas na criação (também pode ser revelado depois com sua senha no painel). Máximo de 10 webhooks por conta.

Parâmetros

urlbodyobrigatório
string: Endpoint HTTPS que receberá os eventos.
eventsbodyobrigatório
array: Lista de eventos (ver tabela de eventos abaixo).

Requisição

curl -X POST "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://seusite.com/webhooks/syntrapay","events":["payment.approved","payment.failed"]}'

Resposta

201 Created
{
  "status": "success",
  "webhook": {
    "id": "665fbe1c9a2d4e0012ab34cd",
    "url": "https://seusite.com/webhooks/syntrapay",
    "events": ["payment.approved", "payment.failed"],
    "active": true,
    "secret": "a1b2c3...64-char-hex-secret",
    "createdAt": "2026-07-18T10:00:00.000Z"
  }
}
400 Bad Request
{
  "status": "error",
  "code": "WEBHOOK_TEST_FAILED",
  "message": "A URL não respondeu ao POST de teste."
}
PATCH/webhooks webhooks.manage

Editar webhook

Atualiza a URL, os eventos ou o status (ativo/inativo) de um webhook. Só os campos enviados são alterados.

Parâmetros

webhookIdbodyobrigatório
string: ID do webhook a editar.
urlbody
string: Nova URL do endpoint.
eventsbody
array: Nova lista de eventos.
activebody
boolean: Ativa ou desativa o webhook.

Requisição

curl -X PATCH "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"665fbe1c9a2d4e0012ab34cd","active":false}'

Resposta

200 OK
{
  "status": "success",
  "webhook": {
    "id": "665fbe1c9a2d4e0012ab34cd",
    "url": "https://seusite.com/webhooks/syntrapay",
    "events": ["payment.approved", "payment.failed"],
    "active": false,
    "createdAt": "2026-07-01T10:00:00.000Z"
  }
}
DELETE/webhooks webhooks.manage

Remover webhook

Remove um webhook permanentemente.

Parâmetros

webhookIdbodyobrigatório
string: ID do webhook a remover.

Requisição

curl -X DELETE "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"665fbe1c9a2d4e0012ab34cd"}'

Resposta

200 OK
{
  "status": "success",
  "message": "Webhook removido com sucesso"
}

Erros

Erros retornam um envelope consistente com status, code e message.

{
  "status": "error",
  "code": "BAD_REQUEST",
  "message": "Descrição do erro em português."
}
UNAUTHORIZED401Chave/token ausente ou inválido no header Authorization.
ACCESS_FORBIDDEN200/403Sem permissão para acessar o recurso.
FORBIDDEN_SCOPE403A chave de API não possui o escopo necessário para a ação.
FORBIDDEN403Conta ainda não ativada.
BAD_REQUEST400Parâmetros ausentes ou inválidos.
VALIDATION_ERROR400Campo de link de pagamento fora das regras. A resposta traz field com o campo exato.
INVALID_URL400URL de imagem, banner ou redirecionamento recusada. Use um endereço público https.
TOO_MANY_BUMPS400Mais de 3 ofertas adicionais no mesmo link.
LINK_LIMIT_REACHED400Limite de 200 links não arquivados por conta atingido.
NOT_ARCHIVED400Tentativa de restaurar um link que não está arquivado.
INSUFFICIENT_FUNDS400Saldo insuficiente para o saque.
INVALID_PIX_KEY400Chave PIX inválida ou não encontrada.
PAYLOAD_TOO_LARGE413Corpo da requisição acima de 64 KB.
RATE_LIMIT_EXCEEDED429Muitas escritas ou leituras de link em pouco tempo.
TOO_MANY_REQUESTS429Limite de requisições atingido. Aguarde e tente novamente.
NOT_FOUND404Recurso não encontrado.
SERVICE_UNAVAILABLE503Não foi possível gerar o endereço do checkout agora. Tente novamente.
INTERNAL_ERROR500Erro interno do servidor.
SyntraPay · API Reference. Dúvidas? Fale com o suporte pelo painel.