Documentação API
Receba e envie PIX pela API. Uma API RESTful com confirmação por webhook assinado e reenvio automático.
Sumário
Visão Geral
Todas as chamadas usam HTTPS e trocam JSON. O prefixo /v1 é o caminho estável e versionado.
Base URL
https://api.geniuspay.site/v1Formato de Dados
application/jsonDuas unidades diferentes
15000 = R$ 150,00). Já as respostas de consulta e os webhooks devolvem em reais decimais (150.00). Não compare os dois números direto.Autenticação
Toda requisição leva sua chave secreta no header Authorization, como Bearer token.
Sobre a chave
A chave é exibida uma única vez, no momento em que é criada. Guardamos apenas o hash SHA-256, então não há como recuperá-la depois. Se perder, revogue e gere outra no painel, em API Keys.
Não existe chave pública. É um único credencial, secreto, que nunca deve sair do seu servidor: não use em app mobile, front-end, ou qualquer lugar que o cliente final consiga ler.
Ambientes
O ambiente é determinado pela chave, não por uma URL diferente.
| Ambiente | Prefixo | Comportamento |
|---|---|---|
| Sandbox | sk_test_gp_ | Gera um PIX fictício. Nada é cobrado e nenhum dinheiro se move. O pagamento é confirmado manualmente. |
| Produção | sk_live_gp_ | Gera um PIX real através do provedor bancário. O dinheiro entra de verdade. |
Integre e valide todo o fluxo em sandbox antes de trocar a chave. O contrato é idêntico nos dois.
Criar Cobrança
Gera um código PIX copia-e-cola para o seu cliente pagar.
/v1/pix/charge| Campo | Tipo | Regra |
|---|---|---|
amount | inteiro, obrigatório | Valor em centavos. Positivo e inteiro; decimais são rejeitados. |
customer.name | string, obrigatório | Nome do pagador. Mínimo de 3 caracteres. |
customer.document | string, obrigatório | CPF (11 dígitos) ou CNPJ (14). Pontuação é removida; dígitos verificadores são conferidos. |
customer.email | string, opcional | Precisa ser um e-mail válido se enviado. |
| Campo | Descrição |
|---|---|
id | UUID da transação. Guarde: é a chave para conciliar com o webhook. |
qr_code | O payload PIX copia-e-cola. É isto que o cliente cola no app do banco. |
qr_url | Imagem PNG do QR Code já renderizada, 300×300. |
expires_at | Expiração em ISO 8601 UTC. Padrão de 60 minutos. |
Consultar Cobrança
Devolve o estado atual de uma cobrança que você criou.
/v1/pix/charge/:idUma cobrança que não é sua responde 404, igual a uma que não existe: a API não confirma a existência de transação de outro lojista. paid_at vem null enquanto o pagamento não foi compensado.
Enviar PIX
Envia dinheiro do seu saldo para uma chave PIX. Debita o saldo disponível na hora.
/v1/pix/transferIsto move dinheiro real
external_ref é obrigatório justamente por isso: é a sua trava de idempotência. Se a conexão cair e você repetir a chamada com o mesmo external_ref, a API devolve o envio que já existe (com duplicate: true) em vez de mandar de novo.| Campo | Tipo | Regra |
|---|---|---|
amount | inteiro, obrigatório | Valor bruto em centavos, antes da taxa. |
pix_key | string, obrigatório | A chave PIX do destinatário. |
pix_key_type | enum, obrigatório | Um de: cpf, cnpj, email, telefone, aleatoria. |
external_ref | string, obrigatório | Sua chave de idempotência, de 8 a 128 caracteres. Use o id do pagamento no seu sistema. |
description | string, opcional | Até 140 caracteres. |
A taxa sai do valor enviado
Você envia amount, mas o destinatário recebe net_amount: a taxa fixa de R$ 4,00 é descontada do valor, não cobrada por fora.
E o líquido precisa ficar em pelo menos R$ 50,00, mínimo do provedor bancário. Na prática o menor envio possível é R$ 54,00.
processando significa que o provedor aceitou a ordem, não que o dinheiro chegou. A confirmação vem no evento transfer.completed. Se o provedor recusar, o saldo é devolvido automaticamente e você recebe transfer.failed.
Consultar um envio
/v1/pix/transfer/:idMesma lógica da consulta de cobrança: devolve o estado atual, incluindo completed_at e o provider_id.
Simular Pagamento
Marca uma cobrança de sandbox como paga, disparando o webhook real.
/v1/pix/simulate-paymentFunciona apenas com chave de sandbox e em cobranças que ainda estejam em aguardando. Dispara o payment.paid de verdade, então serve para validar o seu handler de webhook antes de ir para produção.
Webhooks
Enviamos um POST para a URL que você cadastrar sempre que uma transação muda de estado.
| Evento | Quando dispara |
|---|---|
payment.paid | O PIX foi pago e compensado. É o único sinal confiável para liberar o produto. |
payment.failed | A cobrança expirou sem pagamento. |
transfer.completed | Um envio de PIX caiu na conta do destinatário. |
transfer.failed | O envio foi recusado. O saldo já voltou para a sua conta. |
Reenvio automático
Se a sua URL não responder 2xx, tentamos de novo, até 6 tentativas, com espera crescente: imediata, +1min, +5min, +15min, +1h, +6h.
- Timeout de 10 segundos por tentativa.
- Responda
2xxrápido e processe de forma assíncrona se precisar. - Trate o recebimento como idempotente, usando
data.idcomo chave. Com reenvio, o mesmo evento chega mais de uma vez com frequência. - Esgotadas as tentativas, use a consulta para recuperar o estado.
Verificando a Assinatura
Cada entrega vem assinada. Valide antes de confiar no conteúdo.
A assinatura é o HMAC-SHA256 do corpo bruto da requisição, usando o segredo whsec_... do seu webhook, em hexadecimal.
Corpo bruto, não reserializado
JSON.parse e depois JSON.stringify de volta, a ordem das chaves e o espaçamento podem mudar e a assinatura nunca vai bater.Status da Transação
| Status | Significado |
|---|---|
aguardando | PIX gerado, esperando pagamento. |
pago | Pago e compensado. Libere o produto neste, e apenas neste, estado. |
processando | Envio aceito pelo provedor, ainda não confirmado. |
concluido | Envio confirmado na conta do destinatário. |
expirado | Passou de expires_at sem pagamento. |
recusado | Envio recusado pelo provedor. Saldo estornado. |
cancelado | Cancelado antes da compensação. |
falhou | Erro no processamento. |
Erros
Erros vêm com status HTTP apropriado e um corpo { "error": "..." }.
| Código | Causa | O que fazer |
|---|---|---|
400 | Payload inválido, CPF/CNPJ com dígito errado, valor fora dos limites, ou saldo insuficiente. | O corpo traz details com o campo problemático. Corrija e reenvie. |
401 | Chave ausente, malformada, revogada ou inativa. | Confira o header Authorization e se a chave continua ativa. |
404 | Recurso não encontrado, ou não pertence à sua conta. | Confira o id. |
409 | Já existe um envio em andamento para este external_ref. | Não reenvie: consulte o envio original. |
429 | Rate limit estourado. | Aguarde e repita com backoff exponencial. |
500 | Erro interno, ou provedor não configurado. | Não reenvie em loop. Avise o contato técnico. |
502 | O provedor bancário recusou ou não respondeu. | No caso de envio, o saldo já foi devolvido. |
Limites
| Limite | Padrão | Observação |
|---|---|---|
| Criar cobrança | 60 / min | Por conta, não por IP. |
| Consultar | 120 / min | Por conta. |
| Enviar PIX | 30 / min | Por conta. |
| Valor por cobrança | até R$ 5.000 | Configurável por conta. |
| Valor por envio | R$ 54 – R$ 5.000 | Abaixo de R$ 54 o líquido não alcança o piso do provedor. |
| Taxa fixa de envio | R$ 4,00 | Descontada do valor enviado. |
| Expiração do PIX | 60 min | Configurável por conta. |
| Tentativas de webhook | 6 | Com espera crescente, até ~7h após o evento. |
Fora de escopo nesta versão