Integração financeira pendente. As operações financeiras retornam 503 após autenticação; os exemplos abaixo descrevem o contrato previsto e não comprovam disponibilidade em produção.

Introdução

A API PayHub é uma interface REST versionada em /api/v1. As operações financeiras devem ser encaminhadas ao sistema principal, responsável pelo processamento, recebimento e confirmação dos pagamentos. O PayHub não mantém uma operação financeira independente.

Seu sistema → API PayHub → Backend PayHub → serviço de pagamentos

Primeiros passos

Crie sua integração e obtenha as chaves em API e Desenvolvedores. Chamadas financeiras só estarão disponíveis após validação da conexão e do ambiente correspondente.

Criando uma integração

Cada integração representa um sistema externo (loja, app, ERP) e pertence a um ambiente: Sandbox (test) ou Live. O acesso financeiro exige associação a uma conta autorizada no sistema principal; a conexão dos ambientes ainda não está habilitada.

Gerando as chaves

Cada par tem uma Public Key (pk_test_… / pk_live_…) e uma Secret Key (sk_test_… / sk_live_…). A Secret Key aparece uma única vez; o PayHub guarda apenas um hash. Você pode revogar ou rotacionar a qualquer momento.

Autenticação

Envie a Secret Key no cabeçalho Authorization. Nunca use a Secret Key no navegador ou em apps móveis. Limite: 120 requisições por minuto por chave.

Authorization: Bearer sk_live_XXXXXXXX

Criando cobranças Pix

Use o cabeçalho opcional Idempotency-Key para evitar cobranças duplicadas: a mesma chave retorna a mesma cobrança.

POST/api/v1/payments

Cria uma cobrança Pix no serviço de pagamentos e retorna o QR Code e o código copia e cola.

Autenticação: Authorization: Bearer sk_...

ParâmetroTipoDescrição
amountintegerValor em centavos (mín. 100)
descriptionstringOpcional
external_idstringSeu identificador do pedido
customer.namestringObrigatório
customer.emailstringOpcional
customer.phonestringOpcional
customer.documentstringCPF/CNPJ, só números
curl -X POST "https://SEU_DOMINIO/api/v1/payments" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1042" \
  -d '{"amount":4990,"external_id":"pedido-1042","customer":{"name":"Ana Souza","email":"ana@exemplo.com"}}'

Resposta

{
  "id": "2b8c…",
  "object": "payment",
  "status": "pending",
  "amount": 4990,
  "currency": "BRL",
  "method": "pix",
  "external_id": "pedido-1042",
  "created_at": "2026-01-01T12:00:00Z",
  "pix": {
    "qr_code": "…",
    "copy_paste": "000201…",
    "expires_at": "…"
  }
}

Erros possíveis: 401 unauthorized, 422 invalid_request, 429 rate_limited, 503 processor_unavailable

Consultando pagamentos

GET/api/v1/payments/{id}

Retorna o pagamento e seu status atual.

Autenticação: Authorization: Bearer sk_...

curl -X GET "https://SEU_DOMINIO/api/v1/payments/pay_id" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY"

Resposta

{
  "id": "2b8c…",
  "object": "payment",
  "status": "pending",
  "amount": 4990,
  "currency": "BRL",
  "method": "pix",
  "external_id": "pedido-1042",
  "created_at": "2026-01-01T12:00:00Z"
}

Erros possíveis: 401 unauthorized, 404 not_found

Listando transações

GET/api/v1/transactions

Lista paginada das transações da integração.

Autenticação: Authorization: Bearer sk_...

ParâmetroTipoDescrição
pageintegerPágina (padrão 1)
limitinteger1–100 (padrão 20)
statusstringpending, approved, failed, expired, refunded
curl -X GET "https://SEU_DOMINIO/api/v1/transactions" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY"

Resposta

{
  "object": "list",
  "page": 1,
  "limit": 20,
  "total": 1,
  "data": [
    {
      "id": "2b8c…",
      "object": "payment",
      "status": "pending",
      "amount": 4990,
      "currency": "BRL",
      "method": "pix",
      "external_id": "pedido-1042",
      "created_at": "2026-01-01T12:00:00Z"
    }
  ]
}

Erros possíveis: 401 unauthorized, 422 invalid_request

Clientes

GET/api/v1/customers/{id}

Dados do cliente. O documento é sempre retornado mascarado.

Autenticação: Authorization: Bearer sk_...

curl -X GET "https://SEU_DOMINIO/api/v1/customers/pay_id" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY"

Resposta

{
  "id": "…",
  "object": "customer",
  "name": "Ana Souza",
  "email": "ana@exemplo.com",
  "document": "***.456.***-**"
}

Erros possíveis: 401 unauthorized, 404 not_found

Reembolsos

Somente pagamentos aprovados podem ser reembolsados. O reembolso fica em processing até o serviço de pagamentos confirmar.

POST/api/v1/refunds

Solicita um reembolso total ou parcial.

Autenticação: Authorization: Bearer sk_...

ParâmetroTipoDescrição
payment_iduuidID do pagamento
amountintegerOpcional; padrão é o valor total
reasonstringMotivo
external_idstringOpcional
curl -X POST "https://SEU_DOMINIO/api/v1/refunds" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1042" \
  -d '{"payment_id":"2b8c…","reason":"Pedido cancelado"}'

Resposta

{
  "id": "…",
  "object": "refund",
  "status": "processing",
  "amount": 4990
}

Erros possíveis: 404 not_found, 409 not_refundable, 422 invalid_amount, 503 processor_unavailable

GET/api/v1/refunds/{id}

Consulta um reembolso.

Autenticação: Authorization: Bearer sk_...

curl -X GET "https://SEU_DOMINIO/api/v1/refunds/pay_id" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY"

Resposta

{
  "id": "…",
  "object": "refund",
  "status": "completed",
  "amount": 4990
}

Erros possíveis: 404 not_found

Webhooks

Eventos: payment.created, payment.pending, payment.approved, payment.failed, payment.expired, payment.refunded. Eles são disparados apenas por mudanças reais de status.

Cada entrega traz payhub-event-id (único, use para ignorar repetições) e payhub-signature: t=TIMESTAMP,v1=HMAC, onde HMAC = HMAC-SHA256(segredo, `${t}.${corpo}`). Rejeite eventos com mais de 5 minutos. O reenvio manual está disponível; novas tentativas automáticas e sincronização de eventos financeiros ainda não foram habilitadas.

// Node.js — verificação
import crypto from "node:crypto";
function verify(raw, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${raw}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Códigos de erro

{ "error": { "code": "unauthorized", "message": "Secret Key inválida ou revogada." } }

400/422 invalid_request        Corpo ou parâmetros inválidos
401     unauthorized           Chave ausente, inválida ou revogada
404     not_found              Recurso não existe nesta integração
409     not_refundable         Pagamento não pode ser reembolsado
429     rate_limited           Limite por minuto excedido
500     internal_error         Erro inesperado
503     processor_unavailable  Serviço de pagamentos indisponível

Exemplos de integração

Fluxo típico de checkout: crie a cobrança, mostre o QR Code ao cliente e libere o pedido somente ao receber payment.approved no seu webhook. Nunca trate um pagamento pendente como aprovado.

curl -X POST "https://SEU_DOMINIO/api/v1/payments" \
  -H "Authorization: Bearer $PAYHUB_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1042" \
  -d '{"amount":15900,"external_id":"pedido-2001","customer":{"name":"Carlos Lima"}}'