VolgaPay / Docs
API v1 PIX • Cartão • Cripto Webhooks assinados

VolgaPay — Guia de integração para merchants

API de pagamentos da VolgaPay: PIX, cartão, cripto, links de pagamento, saldo, saques e webhooks.

A VolgaPay não possui sandbox separado. Testes são feitos em produção com valor baixo e dados reais do pagador.


1. Primeiros passos

  1. Crie a conta de merchant no painel VolgaPay.
  2. Ative o 2FA do titular. A criação de API keys exige 2FA.
  3. Crie uma API key em Configurações → Chaves de API.
  4. Guarde o token vp_...: ele aparece uma única vez.
  5. Cadastre os IPs permitidos da sua aplicação (opcional, mas recomendado).
  6. Cadastre um endpoint de webhook para receber payment.succeeded, payment.failed, etc.
  7. Consulte GET /v1/methods para ver métodos, moedas e taxas da sua conta.

Escopos

EscopoPara quê
payments:readConsultar pagamentos e listar
payments:writeCriar, capturar, cancelar e reembolsar
payouts:readConsultar saques
payouts:writeSolicitar saques
balance:readConsultar saldo
kyc:read / kyc:writeEnviar e consultar KYC
webhooks:read / webhooks:writeGerenciar endpoints e entregas
adminOperações administrativas (não use no servidor do merchant)

Use o menor escopo possível. Uma chave de produção não deve ser usada no navegador nem em aplicativos móveis.


2. Autenticação

Authorization: Bearer vp_<key_id>_<secret>
Content-Type: application/json
Accept: application/json

Exemplo:

curl https://volgapay.com/v1/balance \
  -H "Authorization: Bearer vp_SEU_TOKEN"

IP allowlist

Cada API key pode ter uma lista de IPs/CIDRs. Se a lista estiver preenchida, requisições de outros IPs recebem 401.

Rotação

Revogue a chave antiga e crie outra. A revogação é imediata.


3. Idempotência

Envie Idempotency-Key em toda operação que cria dinheiro:

Idempotency-Key: pedido-1001

Regras:


4. Criar pagamento PIX

POST /v1/payments

Corpo

CampoTipoObrigatórioDescrição
amountinteirosimValor em centavos
currencystringsimBRL para PIX
methodstringsimpix
countrystringnãoBR (inferido para PIX)
descriptionstringnãoAparece no seu extrato/painel
customerobjetosim no PIXPagador
metadataobjetonãoDados seus, devolvidos na consulta
capturebooleanonãoSó cartão; padrão true

Pagador (customer) no PIX

A VolgaPay exige o pagador completo na produção:

CampoObrigatórioRegra
namesimNome completo, mínimo 2 caracteres
documentsimCPF ou CNPJ válido (com ou sem pontuação)
phonesimTelefone com DDD. Ex.: +5511999990000
emailrecomendadoE-mail válido
external_idnãoSeu identificador do cliente

Sem nome, documento e telefone válidos, a cobrança é recusada com 422 e código cobranca_recusada_pelo_provedor.

Exemplo

curl -X POST https://volgapay.com/v1/payments \
  -H "Authorization: Bearer vp_SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1001" \
  -d '{
    "amount": 1000,
    "currency": "BRL",
    "method": "pix",
    "country": "BR",
    "description": "Pedido 1001",
    "customer": {
      "name": "Cliente Exemplo",
      "email": "[email protected]",
      "phone": "+5511999990000",
      "document": "529.982.247-25"
    },
    "metadata": { "order_id": "1001" }
  }'

Resposta 201

{
  "id": "01M760P713WDTJ7RF0W6DDZP9D",
  "object": "payment",
  "amount": 1000,
  "fee": 30,
  "net": 970,
  "currency": "BRL",
  "method": "pix",
  "status": "requires_action",
  "provider_reference": "13",
  "description": "Pedido 1001",
  "pix": {
    "qr_code": "0002010102122664...6304D12B",
    "copia_e_cola": "0002010102122664...6304D12B",
    "expires_at": "2026-11-12T19:17:23Z"
  },
  "created_at": "2026-11-11T19:17:23Z"
}

Status

StatusSignificado
requires_actionAguardando o pagador pagar o PIX
processingEm processamento
succeededPago e creditado no saldo líquido
failedRecusado/falhou
canceledCancelado
expiredExpirou sem pagamento
refundedDevolvido
partially_refundedDevolvido parcialmente
chargebackContestação

Libere o pedido somente com status = succeeded (e idealmente confirmando via GET /v1/payments/{id}).


5. Consultar pagamento

GET /v1/payments/{id}

curl https://volgapay.com/v1/payments/01M760P713WDTJ7RF0W6DDZP9D \
  -H "Authorization: Bearer vp_SEU_TOKEN"

Retorna o pagamento completo, incluindo pix, fee, net, paid_at, failure e metadata.

Listar

GET /v1/payments?limit=20&before=<id>

Capturar cartão

POST /v1/payments/{id}/capture com {"amount": 1000} (opcional).

Cancelar

POST /v1/payments/{id}/cancel

No PIX, o cancelamento e a devolução podem não estar disponíveis pela API. Use o painel da VolgaPay para MED/devolução. O endpoint de cancelamento pode retornar erro para PIX.

Reembolsar

POST /v1/payments/{id}/refund

{ "amount": 1000, "reason": "Pedido cancelado" }

Sujeito ao método e ao provedor.


6. Webhooks

Cadastrar endpoint

POST /v1/webhook-endpoints

curl -X POST https://volgapay.com/v1/webhook-endpoints \
  -H "Authorization: Bearer vp_SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-sistema.com/webhooks/volgapay",
    "events": ["payment.succeeded", "payment.failed", "payment.canceled", "payment.expired"]
  }'

Resposta:

{
  "id": "01...",
  "object": "webhook_endpoint",
  "url": "https://seu-sistema.com/webhooks/volgapay",
  "events": ["payment.succeeded", "..."],
  "secret": "whsec_...",
  "_notice": "Guarde o secret agora; ele não será exibido novamente."
}

Eventos

Payload

{
  "id": "01M...",
  "type": "payment.succeeded",
  "created_at": "2026-11-11T19:25:14+00:00",
  "data": {
    "payment_id": "01M760P713WDTJ7RF0W6DDZP9D",
    "amount": 1000,
    "currency": "BRL",
    "method": "pix",
    "status": "succeeded"
  }
}

O payload do webhook é enxuto. Consulte GET /v1/payments/{payment_id} para obter pix, fee, net, metadata e paid_at.

Assinatura

Headers:

X-VolgaPay-Event-Id: 01M...
X-VolgaPay-Signature: t=1791824530,v1=5d2f...64 hex...

A assinatura é:

HMAC-SHA256(secret, "<t>.<corpo cru>")

PHP

$raw = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_VOLGAPAY_SIGNATURE'] ?? '';
preg_match('/t=(\d+),v1=([0-9a-f]{64})/', $header, $m);
$expected = hash_hmac('sha256', $m[1] . '.' . $raw, getenv('VOLGAPAY_WEBHOOK_SECRET'));
if (! hash_equals($expected, $m[2])) {
    http_response_code(401);
    exit;
}
$event = json_decode($raw, true);
if ($event['type'] === 'payment.succeeded') {
    // consulte GET /v1/payments/{$event['data']['payment_id']} antes de liberar
}
http_response_code(200);

Node.js

const crypto = require('crypto');
const raw = req.rawBody; // Buffer, corpo cru
const secret = process.env.VOLGAPAY_WEBHOOK_SECRET;
const [t, v1] = String(req.get('X-VolgaPay-Signature')).match(/t=(\d+),v1=([0-9a-f]{64})/).slice(1);
const expected = crypto.createHmac('sha256', secret).update(`${t}.`).update(raw).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) return res.status(401).end();
const event = JSON.parse(raw.toString('utf8'));
if (event.type === 'payment.succeeded') { /* confirmar na API */ }
res.status(200).end();

Retentativas e duplicatas

Consultar entregas

GET /v1/webhook-deliveries

Mostra status, tentativas, código HTTP e erro das últimas entregas.


7. Saldo

GET /v1/balance?currency=BRL

{
  "object": "balance",
  "currency": "BRL",
  "available": 970,
  "payout_hold": 0
}

available é o saldo disponível para saque, em centavos.


8. Saques (PIX-out)

Pré-requisitos:

POST /v1/payouts

{
  "amount": 1000,
  "currency": "BRL",
  "payout_method": "pix",
  "pix_key_type": "cpf",
  "pix_key": "529.982.247-25",
  "reason": "Saque do merchant"
}

Resposta 201:

{
  "id": "01...",
  "object": "payout",
  "amount": 1000,
  "fee": 0,
  "currency": "BRL",
  "status": "pending_approval",
  "payout_method": "pix",
  "pix_key_type": "cpf",
  "pix_key_last4": "7-25",
  "requested_at": "2026-11-11T20:00:00Z"
}

Status:

Consulte GET /v1/payouts/{id}. O webhook payout.paid também é enviado.

Saques podem exigir aprovação manual. O saldo fica retido enquanto o saque está pendente.


9. Clientes

POST /v1/customers

{
  "external_id": "cliente-123",
  "name": "Cliente Exemplo",
  "email": "[email protected]",
  "phone": "+5511999990000",
  "document": "529.982.247-25",
  "country": "BR",
  "metadata": { "plan": "pro" }
}

Depois use customer_id em POST /v1/payments.

GET /v1/customers/{id} consulta.


POST /v1/payment-links

{
  "amount": 10000,
  "currency": "BRL",
  "description": "Plano anual",
  "methods": ["pix", "card", "volgapay"],
  "max_installments": 12
}

A resposta inclui url e token. Compartilhe a url com o cliente.


11. Métodos e taxas

GET /v1/methods

Retorna os métodos ativos, moedas, países, campos e taxas da sua conta. Use catalog e fees para montar seu checkout.


12. Erros

Formato:

{
  "error": {
    "type": "unprocessable_entity",
    "code": "unprocessable_entity",
    "message": "Mensagem legível",
    "details": {}
  }
}
HTTPSignificado
400Requisição inválida
401API key ausente/inválida ou IP não permitido
403Sem escopo ou acesso negado
404Recurso não encontrado
409Conflito/idempotência
422Regra de negócio (pagador inválido, saldo insuficiente, etc.)
429Rate limit
502Provedor recusou/falhou
503Provedor indisponível

Erros do provedor PIX podem vir com code:


13. Boas práticas de segurança


14. Exemplo completo de PIX

  1. Seu servidor cria o pagamento:
POST /v1/payments
Idempotency-Key: pedido-1001
  1. A resposta traz id, pix.copia_e_cola e expires_at.
  1. Seu checkout mostra o QR/copia-e-cola.
  1. O cliente paga.
  1. A VolgaPay envia payment.succeeded para o seu webhook.
  1. Seu servidor verifica a assinatura, consulta GET /v1/payments/{id} e confirma status = succeeded e o valor.
  1. Seu servidor credita o pedido uma única vez.
  1. Se o webhook não chegar, o polling em GET /v1/payments/{id} reconcilia.

15. Extensibilidade — novas adquirentes

A API é agnóstica de adquirente. Quando a VolgaPay adiciona um novo PSP ou uma nova rota interna:

A VolgaPay roteia internamente por método, moeda, país e grupo de risco. Você não precisa criar uma nova integração nem emitir novos tokens para cada adquirente.

16. Suporte

Ao abrir suporte, informe:

VolgaPay — documentação para merchants. Valores sempre em centavos. Guarde suas chaves com segurança.