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.
/api/v1/paymentsCria 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âmetro | Tipo | Descrição |
|---|---|---|
| amount | integer | Valor em centavos (mín. 100) |
| description | string | Opcional |
| external_id | string | Seu identificador do pedido |
| customer.name | string | Obrigatório |
| customer.email | string | Opcional |
| customer.phone | string | Opcional |
| customer.document | string | CPF/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
/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
/api/v1/transactionsLista paginada das transações da integração.
Autenticação: Authorization: Bearer sk_...
| Parâmetro | Tipo | Descrição |
|---|---|---|
| page | integer | Página (padrão 1) |
| limit | integer | 1–100 (padrão 20) |
| status | string | pending, 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
/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.
/api/v1/refundsSolicita um reembolso total ou parcial.
Autenticação: Authorization: Bearer sk_...
| Parâmetro | Tipo | Descrição |
|---|---|---|
| payment_id | uuid | ID do pagamento |
| amount | integer | Opcional; padrão é o valor total |
| reason | string | Motivo |
| external_id | string | Opcional |
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
/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ívelExemplos 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"}}'