Referência

A API da Oxyvon

Cartão, Pix e boleto sobre o mesmo recurso. Valores sempre em centavos, respostas sempre em JSON, erros sempre com code legível.

Começar

três passos
1

Autenticar

Chave secreta (sk_) no header Authorization: Bearer. A publicável (pk_) só tokeniza cartão no navegador.

2

Cobrar

Um POST /v1/charges com valor, método e o cartão ou o token. Pix e boleto voltam com o instrumento pronto.

3

Receber o evento

Cadastre um endpoint e escute charge.captured. Toda entrega é assinada e reenviada com backoff.

requisição
curl -s https://sua-instancia/v1/charges \
  -H "Authorization: Bearer sk_test_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1001" \
  -d '{
    "amount": 12990,
    "method": "card",
    "card": {
      "number": "4111111111111111",
      "holder_name": "MARIA SOUZA",
      "exp_month": 12, "exp_year": 2030, "cvv": "123"
    }
  }'
resposta · 201
{
  "id": "ch_06G8J0HKYYHNXT834S6J5A9GXM",
  "object": "charge",
  "status": "captured",
  "method": "card",
  "amount": 12990,          // R$ 129,90
  "currency": "BRL",
  "captured_amount": 12990,
  "refundable_amount": 12990,
  "fee_amount": 427,
  "net_amount": 12563,
  "risk": { "score": 0, "decision": "approve" },
  "acquirer": "sandbox",
  "card": { "authorization_code": "669341", "nsu": "418032774" },
  "created_at": "2026-09-10T01:49:12.084Z"
}

12990 são R$ 129,90 — a API nunca recebe decimal. Repetir a requisição com a mesma Idempotency-Key devolve exatamente esta resposta, sem cobrar de novo.

Endpoints

carregando…

Erros

sempre no mesmo formato
resposta · 402
{ "error": {
    "code": "card_declined",
    "message": "Transacao nao autorizada pelo emissor",
    "charge_id": "ch_…",
    "decline_code": "generic_decline"
} }
CódigoHTTPQuando acontece
invalid_request400corpo inválido ou campo faltando
unauthorized401chave ausente, revogada ou do tipo errado
forbidden403conta suspensa ou operação restrita
not_found404recurso inexistente ou de outro merchant
card_declined402emissor recusou — não tente outro adquirente
insufficient_funds402saldo insuficiente para saque ou estorno
risk_blocked402antifraude negou a transação
idempotency_conflict409mesma chave, corpo diferente
invalid_state422operação impossível no status atual
rate_limited429excedeu o limite — respeite retry-after
acquirer_error502todos os adquirentes falharam

Recebendo webhooks

assinatura e política de entrega
validar a assinatura
const [t, v1] = header.split(',').map(p => p.split('=')[1]);
const esperado = crypto.createHmac('sha256', segredo)
  .update(`${t}.${corpoCru}`).digest('hex');

// compare com timingSafeEqual
// e rejeite t fora de ±5min

Header x-oxyvon-signature, formato t=<epoch>,v1=<hmac>. O timestamp entra na mensagem assinada, então payload capturado não pode ser reenviado.

Entrega

Tentativas8
Backoff1 min → 6 h
Timeout10 s
Depois dissodead

Responda 2xx rápido e processe depois. O mesmo evento pode chegar duas vezes: trate por x-oxyvon-event-id.