VyvaPay
Entrar

API VyvaPay

Referência REST v1 para cobranças PIX, saques e consulta de transações. Todas as rotas usam JSON e autenticação por API Key.

Base: https://server.vyvapay.com

Visão geral

A API segue convenções REST: recursos em caminhos versionados (/api/v1), corpo e respostas em application/json, e códigos HTTP semânticos. Utilize HTTPS em produção.

Gere e revogue chaves no painel. Nunca exponha sk_live_... em aplicativos móveis ou repositórios públicos.

Pacote para integrar em outro sistema (README + instruções para IA)

Arquivos Markdown estáticos: /docs/README.md, /docs/AI_INTEGRATION.md. No repositório Git ficam em docs/ na raiz do projeto vyvapay.com (copie a pasta inteira).

Autenticação

Inclua o cabeçalho Authorization com o valor Bearer SUA_CHAVE. Requisições sem chave válida recebem 401.

Authorization: Bearer sk_live_...

Criar pagamento PIX

POST/api/v1/payments

Cria um pedido e retorna dados PIX (copia e cola e QR Code em Base64) para o pagador concluir a transação.

Corpo (JSON)

CampoTipoObrigatórioDescrição
amountnumberSimValor em reais (positivo).
customer_emailstringSimE-mail do pagador.
customer_namestringNãoNome exibido na cobrança.
customer_cpfstringNãoCPF do pagador (apenas dígitos ou formatado).
descriptionstringNãoDescrição da cobrança.
payment_method"PIX"NãoPadrão PIX.
ip_addressstringNãoIP público do pagador final. Recomendado para análise antifraude e auditoria.
ip_countrystringNãoISO-3166 alpha-2 (ex: BR). Em apps na Vercel, use o header x-vercel-ip-country.
ip_regionstringNãoEstado/região (ex: SP). Header Vercel: x-vercel-ip-country-region.
ip_citystringNãoCidade do pagador. Header Vercel: x-vercel-ip-city (decodifique via decodeURIComponent).
ip_postal_codestringNãoCEP / postal code. Header Vercel: x-vercel-ip-postal-code.
ip_latitudestringNãoLatitude aproximada. Header Vercel: x-vercel-ip-latitude.
ip_longitudestringNãoLongitude aproximada. Header Vercel: x-vercel-ip-longitude.
ip_timezonestringNãoFuso horário IANA. Header Vercel: x-vercel-ip-timezone.

Respostas

CódigoDescrição
201Cobrança criada.
400Validação (corpo inválido).
401API Key inválida.
500Erro interno.

Criar saque PIX

POST/api/v1/withdrawals

Inicia uma transferência PIX da sua conta para a chave informada. Campos opcionais na API, mas envie em produção com dados reais do usuário final: document, customer_name, customer_email (se key_type não for EMAIL) e ip_address.

Corpo (JSON)

CampoTipoObrigatórioDescrição
amountnumberSimValor do saque.
pix_keystringSimChave PIX de destino (telefone, e-mail, CPF, CNPJ ou EVP).
key_typeenumSimCPF, EMAIL, CNPJ, PHONE ou EVP.
descriptionstringNãoReferência interna no VyvaPay (ex.: solicitacao_abc). Não é enviado ao gateway.
documentstringNãoCPF/CNPJ do usuário que solicitou o saque (só dígitos). Recomendado. Se omitido: CPF/CNPJ da conta merchant ou 00000000000 no gateway.
external_idstringNãoIdentificador idempotente. Repetições com o mesmo external_id retornam 409.
customer_emailstringNãoE-mail do usuário que solicitou o saque. Recomendado quando key_type não for EMAIL. Se omitido: e-mail da conta merchant ou noreply@vyvapay.com no gateway.
customer_namestringNãoNome completo do usuário que solicitou o saque (campo name no gateway). Recomendado. Se omitido: razão social / nome fantasia da conta.
ip_addressstringNãoIP público do usuário no clique em Sacar (não do seu servidor). Recomendado. Se omitido: IP da requisição HTTP à API.
ip_countrystringNãoISO-3166 alpha-2. Em Next.js/Vercel, leia x-vercel-ip-country no Route Handler.
ip_regionstringNãoEstado/região do solicitante. Header Vercel: x-vercel-ip-country-region.
ip_citystringNãoCidade do solicitante. Header Vercel: x-vercel-ip-city (use decodeURIComponent).
ip_postal_codestringNãoCEP / postal code. Header Vercel: x-vercel-ip-postal-code.
ip_latitudestringNãoLatitude aproximada. Header Vercel: x-vercel-ip-latitude.
ip_longitudestringNãoLongitude aproximada. Header Vercel: x-vercel-ip-longitude.
ip_timezonestringNãoFuso horário IANA do solicitante. Header Vercel: x-vercel-ip-timezone.

Respostas

CódigoDescrição
201Saque registrado.
402Saldo insuficiente (INSUFFICIENT_BALANCE).
409external_id duplicado.
400Validação.
401API Key inválida.
502Gateway recusou o saque.
500Erro interno.

Gateway e webhooks

pix_key e key_type definem o destino do PIX. document, customer_name, customer_email e ip_address são repassados como dados do pagador na liquidação.

Inscreva TRANSFER_FAILED no webhook do merchant para receber falhas (ex.: failure_reason INSUFFICIENT_BALANCE).

Consultar saldo

GET/api/v1/balance

Retorna o saldo VyvaPay da conta da API Key. Use available_balance antes de sacar. Não é o saldo global do adquirente (Citrex).

Corpo da resposta

CampoTipoObrigatórioDescrição
account_idstringSimID da conta merchant.
currencystringSimMoeda (BRL).
ledger_balancenumberSimSaldo contábil: entradas − saques concluídos e taxas.
reserved_balancenumberSimReservado em saques PENDING/PROCESSING (valor + taxa).
available_balancenumberSimDisponível para novo saque (ledger − reservado, mín. 0).

Respostas

CódigoDescrição
200Saldo retornado.
401API Key inválida.
500Erro interno.

Consultar transação

GET/api/v1/transactions/:id

Retorna uma transação do razão vinculada à sua conta, incluindo status do pagamento e dados do cliente quando disponíveis.

Parâmetros de rota

CampoTipoObrigatórioDescrição
idstringSimIdentificador da transação (ledger).

Respostas

CódigoDescrição
200Encontrada.
401API Key inválida.
404Não encontrada.
500Erro interno.

Geolocalização do cliente

Para análise antifraude e auditoria, você pode (e deve) enviar o IP e a localização do usuário final que solicitou o pagamento ou saque dentro do seu app — não o IP do servidor que chama nossa API. Os campos abaixo são opcionais em /api/v1/payments e /api/v1/withdrawals e ficam visíveis no detalhe da transação no painel.

Apps na Vercel (Next.js)

A Vercel injeta automaticamente headers x-vercel-ip-* em todas as requisições recebidas pelo seu Edge / Functions. Em uma Server Action ou Route Handler, leia esses headers e repasse no body para a VyvaPay:

import { headers } from "next/headers";

export async function POST(request: Request) {
  const h = await headers();
  const xff = h.get("x-forwarded-for");
  const ip = xff?.split(",")[0]?.trim() ?? h.get("x-real-ip") ?? null;

  const res = await fetch("https://server.vyvapay.com/api/v1/payments", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.VYVAPAY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount: 50,
      customer_email: "cliente@email.com",
      ip_address: ip,
      ip_country: h.get("x-vercel-ip-country"),
      ip_region: h.get("x-vercel-ip-country-region"),
      ip_city: h.get("x-vercel-ip-city")
        ? decodeURIComponent(h.get("x-vercel-ip-city")!)
        : null,
      ip_postal_code: h.get("x-vercel-ip-postal-code"),
      ip_latitude: h.get("x-vercel-ip-latitude"),
      ip_longitude: h.get("x-vercel-ip-longitude"),
      ip_timezone: h.get("x-vercel-ip-timezone"),
    }),
  });

  return Response.json(await res.json());
}

Apps em Cloudflare / Fly / outros

Cloudflare expõe CF-Connecting-IP e CF-IPCountry, e o objeto request.cf traz city, region, latitude, longitude, timezone e postalCode. Em outros provedores, use x-forwarded-for e qualquer serviço de geo-IP da sua escolha.

Se você não enviar nenhum desses campos, a VyvaPay registra apenas o IP do remetente HTTP (que normalmente é o seu servidor). Se a VyvaPay receber a chamada diretamente via Vercel/Cloudflare (ex: dashboard interno), os headers do edge são lidos automaticamente como fallback.

Webhooks de eventos (painel)

No dashboard, em Modo Dev → Webhooks, você cadastra endpoints HTTPS que recebem notificações quando eventos ocorrem na conta (pagamentos, pedidos, saques, etc.).

Requisitos do endpoint

  • HTTPS obrigatório.
  • Responda com 200 ou 201 para confirmar entrega. Qualquer outro código ou erro de rede conta como falha.
  • Entregas com falha são repetidas automaticamente até 4 tentativas, com espera de 30s, depois 1 min, depois 5 min entre uma tentativa e a seguinte. Após esgotar as tentativas, o painel marca a entrega como falha; você pode reenfileirar manualmente na aba Entregas.

Corpo e cabeçalhos

Cada notificação é um POST com corpo JSON contendo id, type, created_at e data.

CampoTipoObrigatórioDescrição
Content-TypeheaderSimapplication/json
X-VyvaPay-TimestampheaderSimUnix timestamp em segundos (string) usado na assinatura.
X-VyvaPay-SignatureheaderSimHMAC SHA-256 em hexadecimal: assina a mensagem timestamp + "." + corpo bruto (UTF-8), usando o segredo do endpoint (whsec_…).
X-VyvaPay-Event-IdheaderSimId do evento (coincide com o campo id no JSON).
X-VyvaPay-Endpoint-IdheaderSimIdentificador do endpoint configurado no painel.

Para validar: calcule o HMAC-SHA-256 em hexadecimal do segredo do endpoint sobre a mensagem formada por timestamp + "." + corpo_bruto (UTF-8, bytes exatamente como recebidos) e compare com X-VyvaPay-Signature. Use o mesmo timestamp do cabeçalho X-VyvaPay-Timestamp.

Webhooks do gateway de liquidação (internos) seguem outro fluxo; esta seção refere-se apenas aos webhooks de eventos que você configura no painel VyvaPay.