Documentação API
Visão Geral
A API VeniPay permite criar e gerenciar cobranças via PIX, cartão de crédito, débito e boleto de forma programática, além de realizar saques (cash-out) via Pix. Todas as requisições e respostas utilizam JSON sobre HTTPS.
Base URL
https://api.venipay.com.br/api/v1Todos os endpoints descritos nesta página são relativos à base URL acima. Por exemplo, POST /transactions corresponde a https://api.venipay.com.br/api/v1/transactions.
Autenticação
Todas as requisições autenticadas devem incluir sua API key no header Authorization com o esquema Bearer.
Authorization: Bearer sk_live_SuaChaveAqui
Suas chaves de API estão disponíveis em Painel → Integrações → Chaves de API. Cada chave é vinculada ao seu merchant e registra IP e data/hora do último uso.
Códigos de Erro
A API retorna erros com um objeto JSON contendo o campo error. Os status HTTP mais comuns:
| Status | Significado |
|---|---|
| 401 | API key ausente, inválida ou expirada. |
| 403 | Conta do merchant inativa. |
| 404 | Recurso não encontrado. |
| 422 | Erro de validação ou regra de negócio (ex.: saldo insuficiente, status inválido para a operação). |
| 500 | Erro interno do servidor. Tente novamente ou contate o suporte. |
{
"error": "API key required"
}
Transações
Cria uma nova cobrança. Se idempotency_key for fornecida e já existir uma transação com a mesma chave, retorna a transação existente com status 200 em vez de criar uma nova.
Parâmetros (body)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| amount | number | sim | Valor em reais. Mínimo: 0.01 |
| payment_method | string | sim | pix, credit, debit ou boleto |
| description | string | não | Descrição da cobrança. Máx: 255 |
| installments | integer | não | Parcelas (1–12). Aplicável a credit |
| payer_name | string | não | Nome do pagador. Máx: 255 |
| payer_document | string | não | CPF ou CNPJ do pagador. Máx: 18 |
| payer_email | string | não | E-mail do pagador |
| payer_phone | string | não | Telefone do pagador. Máx: 20 |
| external_id | string | não | Identificador do seu sistema. Máx: 255 |
| metadata | object | não | Dados adicionais livres (JSON) |
| idempotency_key | string | não | Chave de idempotência. Máx: 255 |
curl -X POST https://api.venipay.com.br/api/v1/transactions \
-H "Authorization: Bearer sk_live_SuaChaveAqui" \
-H "Content-Type: application/json" \
-d '{
"amount": 150.00,
"payment_method": "pix",
"payer_name": "João Silva",
"payer_document": "123.456.789-00",
"description": "Pedido #1042",
"external_id": "pedido-1042"
}'
Retorna 201 Created com o objeto da transação.
Retorna uma lista paginada das transações do seu merchant.
Query Parameters
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| status | string | não | Filtrar por status (ex.: approved, pending) |
| payment_method | string | não | Filtrar por método: pix, credit, debit, boleto |
| date_from | string | não | Data inicial (formato: YYYY-MM-DD) |
| date_to | string | não | Data final (formato: YYYY-MM-DD) |
| per_page | integer | não | Itens por página. Padrão: 20 |
curl https://api.venipay.com.br/api/v1/transactions?status=approved&per_page=10 \
-H "Authorization: Bearer sk_live_SuaChaveAqui"
Retorna 200 OK com paginação Laravel padrão (data, current_page, last_page, total, etc.).
Retorna os detalhes de uma transação específica.
curl https://api.venipay.com.br/api/v1/transactions/abc123 \
-H "Authorization: Bearer sk_live_SuaChaveAqui"
Captura uma transação previamente autorizada. Somente transações com status authorized podem ser capturadas.
curl -X POST https://api.venipay.com.br/api/v1/transactions/abc123/capture \
-H "Authorization: Bearer sk_live_SuaChaveAqui"
Retorna 200 OK com a transação atualizada (status captured).
Cancela uma transação com status pending ou authorized.
curl -X POST https://api.venipay.com.br/api/v1/transactions/abc123/void \
-H "Authorization: Bearer sk_live_SuaChaveAqui"
Retorna 200 OK com a transação atualizada (status cancelled).
Solicita reembolso total ou parcial de uma transação com status approved ou captured. Se amount não for informado, será reembolsado o valor total.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| amount | number | não | Valor do reembolso. Mínimo: 0.01. Não pode exceder o saldo reembolsável. |
| reason | string | não | Motivo do reembolso. Máx: 500 |
curl -X POST https://api.venipay.com.br/api/v1/transactions/abc123/refund \
-H "Authorization: Bearer sk_live_SuaChaveAqui" \
-H "Content-Type: application/json" \
-d '{ "amount": 50.00, "reason": "Produto devolvido" }'
Retorna 201 Created com o objeto de reembolso.
PIX
Gera uma cobrança PIX com QR Code. É um atalho para criar uma transação com payment_method: pix e retorna diretamente os dados do QR Code.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| amount | number | sim | Valor em reais. Mínimo: 0.01 |
| description | string | não | Descrição. Máx: 255 |
| payer_name | string | não | Nome do pagador. Máx: 255 |
| payer_document | string | não | CPF/CNPJ do pagador. Máx: 18 |
| expiration_minutes | integer | não | Minutos até expiração (5–1440). Padrão definido pelo gateway. |
| external_id | string | não | Identificador do seu sistema. Máx: 255 |
curl -X POST https://api.venipay.com.br/api/v1/pix/qrcode \
-H "Authorization: Bearer sk_live_SuaChaveAqui" \
-H "Content-Type: application/json" \
-d '{ "amount": 89.90, "description": "Assinatura mensal" }'
{
"transaction_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"txid": "VNP1042abc",
"qrcode": "00020126580014br.gov.bcb.pix...",
"qrcode_url": "https://app.venipay.com.br/pix/qr/VNP1042abc",
"expiration": "2026-03-25T15:30:00-03:00",
"amount": 89.90,
"status": "pending"
}
Consulta o status de uma cobrança PIX pelo txid.
{
"transaction_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"txid": "VNP1042abc",
"amount": 89.90,
"status": "approved",
"paid_at": "2026-03-25T14:22:10-03:00"
}
Financeiro / Cash-out
Retorna o saldo atual do merchant em reais.
{
"available": 12450.00,
"pending": 3200.50,
"blocked": 0.00,
"total": 15650.50,
"currency": "BRL"
}
| Campo | Descrição |
|---|---|
| available | Disponível para saque imediato. |
| pending | Valores em liquidação (aguardando D+N). |
| blocked | Bloqueado por saques em processamento, disputas ou medidas de segurança. |
| total | Soma: available + pending + blocked. |
Solicita transferência do saldo disponível via Pix. O valor é movido de available para blocked até a conclusão.
pix_key + pix_key_type) ou escolhido entre os destinos cadastrados no painel (Saldo → Destinos Pix), via bank_account_id ou destino principal.
1) Chave no JSON (recomendado para integrações estilo carteira): envie pix_key e pix_key_type junto com amount. Opcionalmente holder_name e holder_document para o adquirente (ex.: MisticPay). Se pix_key for enviada, ela tem prioridade sobre bank_account_id.
2) Destino no painel: omita pix_key e use bank_account_id (ou deixe em branco para o destino principal). É necessário ter um destino com chave Pix válida.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| amount | number | sim | Valor em reais. Limites: mínimo 5, máximo 15000 (configuráveis na plataforma). |
| method | string | não | Apenas pix (padrão). Saques são sempre por Pix. |
| pix_key | string | condicional | Chave Pix de recebimento. Se informada, exige pix_key_type e dispensa destino cadastrado no painel. |
| pix_key_type | string | condicional | cpf, cnpj, email, phone ou random (chave aleatória). Obrigatório quando pix_key é enviada. |
| holder_name | string | não | Nome do favorecido (opcional, para gateways que exigem). |
| holder_document | string | não | CPF/CNPJ do favorecido, só dígitos (opcional). |
| bank_account_id | integer | não | ID do destino Pix no painel. Usado apenas quando pix_key não é enviada. Se omitido, usa o destino principal. |
curl -X POST https://api.venipay.com.br/api/v1/payouts \
-H "Authorization: Bearer sk_live_SuaChaveAqui" \
-H "Content-Type: application/json" \
-d '{ "amount": 100.00, "pix_key": "email@exemplo.com", "pix_key_type": "email" }'
curl -X POST https://api.venipay.com.br/api/v1/payouts \
-H "Authorization: Bearer sk_live_SuaChaveAqui" \
-H "Content-Type: application/json" \
-d '{ "amount": 5000.00, "method": "pix" }'
Retorna 201 Created com o objeto do saque. A chave Pix informada no body não é devolvida por completo: use payout_pix_key_masked (últimos dígitos). A taxa aplicável (se houver) é calculada automaticamente conforme seu plano de taxas.
{
"id": 42,
"merchant_id": 1,
"bank_account_id": null,
"payout_pix_key_masked": "************.com",
"amount": "100.00",
"fee_amount": "4.00",
"net_amount": "96.00",
"method": "pix",
"status": "processing",
"processed_at": "2026-03-25T14:22:10.000000Z",
"completed_at": null,
"created_at": "2026-03-25T14:22:10.000000Z",
"updated_at": "2026-03-25T14:22:10.000000Z"
}
Erros específicos do Cash-out
As respostas de erro incluem os campos code (identificador estável), error (mensagem curta em inglês), message (explicação em português) e, quando aplicável, hints (lista de orientações).
| Status | code | Causa |
|---|---|---|
| 403 | CASHOUT_API_DISABLED | API Cash-out não habilitada no painel admin para este merchant. |
| 422 | NO_PAYOUT_DESTINATION | Sem pix_key no body e sem destino no painel (ou bank_account_id inválido). |
| 422 | DESTINATION_NO_PIX_KEY | O destino selecionado não possui chave Pix. |
| 422 | INSUFFICIENT_BALANCE | Saldo disponível insuficiente para o valor solicitado. |
Retorna os detalhes de um saque específico.
curl https://api.venipay.com.br/api/v1/payouts/42 \
-H "Authorization: Bearer sk_live_SuaChaveAqui"
Webhooks
Webhooks permitem que seu servidor receba notificações automáticas quando eventos ocorrem (ex.: pagamento aprovado). Configure URLs de callback e selecione quais eventos deseja receber.
Retorna todos os webhooks ativos do seu merchant.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| url | string | sim | URL HTTPS que receberá os eventos. Máx: 500 |
| events | array | sim | Lista de eventos (ao menos 1). Veja eventos disponíveis. |
curl -X POST https://api.venipay.com.br/api/v1/webhooks \
-H "Authorization: Bearer sk_live_SuaChaveAqui" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seu-servidor.com/webhooks/venipay",
"events": ["transaction.approved", "transaction.refunded"]
}'
Retorna 201 Created com o webhook criado, incluindo o campo secret (prefixo whsec_). Guarde o secret com segurança — ele será usado para verificar assinaturas.
Remove um webhook. Retorna 204 No Content.
Eventos Disponíveis
transaction.created transaction.approved transaction.declined transaction.refunded transaction.chargeback settlement.completed settlement.failed
Formato do payload
Cada notificação é enviada como POST para a URL cadastrada com os seguintes headers e corpo:
| Header | Descrição |
|---|---|
| Content-Type | application/json |
| X-VeniPay-Event | Tipo do evento (ex.: transaction.approved) |
| X-VeniPay-Signature | HMAC-SHA256 do corpo para verificação de autenticidade |
{
"event": "transaction.approved",
"data": {
"transaction_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"external_id": "pedido-1042",
"type": "cash_in",
"payment_method": "pix",
"status": "approved",
"amount": 150.00,
"fee_amount": 2.25,
"net_amount": 147.75,
"currency": "BRL",
"paid_at": "2026-03-25T14:22:10-03:00",
"created_at": "2026-03-25T14:20:00-03:00"
},
"timestamp": "2026-03-25T14:22:11-03:00"
}
Retentativas
Se seu servidor retornar um status HTTP diferente de 2xx, a VeniPay reenvia a notificação com backoff progressivo:
- 30 segundos
- 2 minutos
- 10 minutos
- 1 hora
- 24 horas
Após 10 falhas consecutivas, o webhook é automaticamente desativado. Reative-o pelo painel ou crie um novo via API.
Verificação de Assinatura
Para garantir que a notificação veio da VeniPay e não foi adulterada, valide o header X-VeniPay-Signature comparando-o com o HMAC-SHA256 do corpo bruto da requisição usando o secret do seu webhook.
A assinatura é calculada sobre o JSON serializado do corpo (json_encode do objeto { event, data, timestamp }). Use o corpo bruto da requisição (raw body) para a comparação, sem reparseá-lo.
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_VENIPAY_SIGNATURE'] ?? '';
$secret = 'whsec_SeuSecretAqui';
$expected = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Assinatura inválida');
}
$data = json_decode($payload, true);
// Processar evento...
const crypto = require('crypto');
app.post('/webhooks/venipay', (req, res) => {
const payload = JSON.stringify(req.body);
const signature = req.headers['x-venipay-signature'];
const secret = 'whsec_SeuSecretAqui';
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (expected !== signature) {
return res.status(401).send('Assinatura inválida');
}
// Processar evento...
res.sendStatus(200);
});
import hmac, hashlib, json
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks/venipay', methods=['POST'])
def webhook():
payload = request.get_data(as_text=True)
signature = request.headers.get('X-VeniPay-Signature', '')
secret = 'whsec_SeuSecretAqui'
expected = hmac.new(
secret.encode(), payload.encode(), hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
return 'Assinatura inválida', 401
data = json.loads(payload)
# Processar evento...
return '', 200
hash_equals em PHP, hmac.compare_digest em Python, crypto.timingSafeEqual em Node.js). Comparação direta com === pode ser vulnerável.
Precisa de ajuda com a integração?