referência da api

Provento API

API REST do gateway de pagamentos Provento. Pix, cartão e boleto sob um contrato único, com checkout hospedado, idempotência e webhooks assinados.

basehttps://pay.provento.tech
openapi.json ↓v1.0.0

Início rápido

Da chave gerada à primeira cobrança paga.

  1. 1
    Gere uma chave

    No painel, em Desenvolvedores, crie uma chave de API.

  2. 2
    Crie a cobrança

    Um POST /v1/charges devolve a checkout_url já pronta.

  3. 3
    Redirecione o cliente

    Ele paga na página hospedada — você não toca em dado de cartão.

  4. 4
    Receba o webhook

    Confirmou, avisamos sua aplicação com a assinatura HMAC.

primeira cobrança
curl -X POST https://pay.provento.tech/v1/charges \
  -H "Authorization: Bearer sk_live_9f2a4821" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"amount": 42390, "methods": ["pix"]}'

# → 201
# {
#   "id": "3f1c9a2e-...",
#   "status": "criada",
#   "checkout_url": "https://pay.provento.tech/checkout/3f1c9a2e-..."
# }

Autenticação

Toda chamada server-to-server usa sua chave secreta no header Authorization. A chave identifica o lojista — não é preciso enviar id de conta em lugar nenhum.

Nunca exponha uma chave sk_live no front-end. Os endpoints de /checkout são públicos justamente para o navegador não precisar de chave: o id da cobrança já é a credencial daquele pagamento.
Authorization: Bearer sk_live_9f2a4821...

Idempotência

Envie Idempotency-Key em toda criação de cobrança. Se a resposta se perder na rede e você repetir a chamada com a mesma chave, devolvemos a cobrança original em vez de criar outra.

É o que separa um gateway de um formulário: sem isso, um timeout vira cobrança duplicada no cartão do seu cliente.
Idempotency-Key: b1f4c0de-2a77-4f31-9d0c-7c1a3e5b8a90

# mesma chave + mesmo corpo → 201 com a MESMA cobrança

Valores

Dinheiro trafega sempre em centavos, como inteiro. R$ 423,90 é 42390. Nunca envie decimal — ponto flutuante e dinheiro não se misturam.

No razão, o sinal vai embutido no valor: cobranca é positivo e as taxas são negativas. Sua margem é a soma de taxa_provento menos taxa_provedor.
R$ 423,90   →  42390     ✅
R$ 423,90   →  423.90    ❌

"ledger": [
  { "type": "cobranca",      "amount":  42390 },
  { "type": "taxa_provedor", "amount":   -335 },
  { "type": "taxa_provento", "amount":   -420 }
]

Cobranças

O ciclo de vida de um pagamento. Você cria uma cobrança, redireciona o cliente para a `checkout_url` (ou confirma via API) e acompanha o status.

post/v1/charges

Criar cobrança

Cria uma cobrança e devolve a `checkout_url`. Envie o header `Idempotency-Key` com um valor único por pedido: repetir a mesma chave devolve a cobrança original em vez de criar outra — é a sua proteção contra cobrança em duplicidade quando a rede falha.

authBearer sk_…
Parâmetros
Idempotency-Keystring(header)

Chave única por operação (recomendado um UUID). Reenvios com a mesma chave retornam a cobrança já criada.

Corpo da requisição
amountintegerobrigatório

Valor total em centavos. R$ 423,90 → `42390`.

currencystring

Padrão `BRL`.

BRL
methodsarray

Métodos aceitos. Padrão `["pix"]`.

pixcartao_creditocartao_debitoboleto
order_refstring

Sua referência de pedido — aparece no painel e na conciliação.

customer_idstring

Id do cliente final, se você já o cadastrou.

Respostas
201Cobrança criada.
401Chave de API ausente ou inválida.
422Corpo inválido.
POST /v1/charges
curl -X POST https://pay.provento.tech/v1/charges \
  -H "Authorization: Bearer sk_live_9f2a4821" \
  -H "Idempotency-Key: b1f4c0de-2a77-4f31-9d0c-7c1a3e5b8a90" \
  -H "Content-Type: application/json" \
  -d '{
       "amount": 42390,
       "currency": "BRL",
       "methods": [
         "pix",
         "cartao_credito"
       ],
       "order_ref": "Pedido #1234"
     }'
{
  "id": "3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04",
  "status": "criada",
  "amount": 42390,
  "paid_amount": 0,
  "currency": "BRL",
  "methods": [
    "pix"
  ],
  "order_ref": "Pedido #1234",
  "checkout_url": "https://pay.provento.tech/checkout/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04",
  "created_at": "2026-08-11T12:00:00.000Z"
}
get/v1/charges/{id}

Consultar cobrança

Devolve a cobrança com todas as tentativas e os lançamentos que ela gerou no razão. É o endpoint de polling se você ainda não configurou webhooks.

authBearer sk_…
Parâmetros
idstring · uuid(path)obrigatório

Id da cobrança.

Respostas
200A cobrança.
404Cobrança não encontrada para esta chave.
GET /v1/charges/{id}
curl -X GET https://pay.provento.tech/v1/charges/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04 \
  -H "Authorization: Bearer sk_live_9f2a4821"
{
  "id": "3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04",
  "status": "paga",
  "amount": 42390,
  "paid_amount": 42390,
  "currency": "BRL",
  "methods": [
    "pix"
  ],
  "order_ref": "Pedido #1234",
  "checkout_url": "https://pay.provento.tech/checkout/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04",
  "created_at": "2026-08-11T12:00:00.000Z",
  "attempts": [
    {
      "id": "9c2f7b10-4e51-4a03-8f6d-1b2c3d4e5f60",
      "status": "capturada",
      "method": "pix",
      "provider_external_id": "psp_8f21ac",
      "card_brand": null,
      "card_last4": null,
      "pix_qr_code": "00020126580014BR.GOV.BCB.PIX...",
      "boleto_line": null,
      "error_code": null,
      "created_at": "2026-08-11T12:00:04.000Z"
    }
  ],
  "ledger": [
    {
      "type": "cobranca",
      "amount": 42390,
      "competency_date": "2026-08-11"
    },
    {
      "type": "taxa_provedor",
      "amount": -335,
      "competency_date": "2026-08-11"
    },
    {
      "type": "taxa_provento",
      "amount": -420,
      "competency_date": "2026-08-11"
    }
  ]
}
post/v1/charges/{id}/confirm

Confirmar pagamento

Dispara uma tentativa de pagamento — o caminho server-to-server, para quem tem checkout próprio em vez de usar a `checkout_url`. Para cartão, envie o `card_token`: **o número do cartão nunca trafega pela sua aplicação**.

authBearer sk_…
Parâmetros
idstring · uuid(path)obrigatório

Id da cobrança.

Corpo da requisição
methodstringobrigatório

Método escolhido.

pixcartao_creditocartao_debitoboleto
card_tokenstring

Token do cartão, obrigatório nos métodos de cartão.

installmentsinteger

Número de parcelas. Padrão `1`.

Respostas
200Cobrança após a tentativa.
422Método inválido ou token ausente.
POST /v1/charges/{id}/confirm
curl -X POST https://pay.provento.tech/v1/charges/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04/confirm \
  -H "Authorization: Bearer sk_live_9f2a4821" \
  -H "Content-Type: application/json" \
  -d '{
       "method": "cartao_credito",
       "card_token": "tok_1a2b3c",
       "installments": 3
     }'

Checkout

Endpoints internos do checkout hospedado, servidos sob `/api/`. Não exigem chave — são escopados pelo id da cobrança, que funciona como capability. Para integrar do seu servidor, use `/v1/charges/{id}/confirm`.

get/api/checkout/{id}

Dados do checkout

Público — não exige chave. O id da cobrança já é o segredo que autoriza o acesso. É o que a página de checkout hospedada consome.

authpúblico — sem chave
Parâmetros
idstring · uuid(path)obrigatório

Id da cobrança.

Respostas
200A cobrança.
404Cobrança inexistente.
GET /api/checkout/{id}
curl -X GET https://pay.provento.tech/api/checkout/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04
post/api/checkout/{id}/confirm

Pagar (cliente final)

Chamado pela página de checkout quando o cliente conclui o pagamento. Ao confirmar, o webhook de saída é despachado em seguida.

authpúblico — sem chave
Parâmetros
idstring · uuid(path)obrigatório

Id da cobrança.

Corpo da requisição
methodstringobrigatório
pixcartao_creditocartao_debitoboleto
card_tokenstring

Token do cartão.

installmentsinteger

Padrão `1`.

Respostas
200Cobrança após o pagamento.
POST /api/checkout/{id}/confirm
curl -X POST https://pay.provento.tech/api/checkout/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04/confirm \
  -H "Content-Type: application/json" \
  -d '{
       "method": "pix"
     }'
post/api/checkout/{id}/simulate

Simular confirmação

Simula a confirmação assíncrona de Pix e boleto sem esperar o banco — para você testar o fluxo completo em desenvolvimento.

authpúblico — sem chave
Parâmetros
idstring · uuid(path)obrigatório

Id da cobrança.

Respostas
200Cobrança confirmada.
POST /api/checkout/{id}/simulate
curl -X POST https://pay.provento.tech/api/checkout/3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04/simulate

Webhooks

Notificações de mudança de status, assinadas com HMAC-SHA256. Inclui os endpoints que simulam a confirmação assíncrona de Pix e boleto.

post/v1/webhooks/simulate

Simular webhook de entrada

Simula o adquirente confirmando um Pix ou boleto. Use para exercitar seu handler de webhook sem depender de um pagamento real.

authBearer sk_…
Corpo da requisição
charge_idstring · uuidobrigatório

Id da cobrança.

Respostas
200Cobrança após a confirmação.
POST /v1/webhooks/simulate
curl -X POST https://pay.provento.tech/v1/webhooks/simulate \
  -H "Authorization: Bearer sk_live_9f2a4821" \
  -H "Content-Type: application/json" \
  -d '{
       "charge_id": "3f1c9a2e-8b4d-4f77-9a10-2c5e6d8b1f04"
     }'
post/v1/webhooks/receive-test

Conferir assinatura

Receptor de verificação: recomputa o HMAC do corpo cru e responde se a assinatura confere. Serve para você validar sua própria implementação de verificação antes de apontar o webhook para produção.

authpúblico — sem chave
Parâmetros
X-Provento-Signaturestring(header)obrigatório

Assinatura no formato `t=<unix>,v1=<hmac_sha256_hex>`.

Respostas
200Assinatura válida.
400Assinatura inválida ou fora da tolerância de 5 minutos.
POST /v1/webhooks/receive-test
curl -X POST https://pay.provento.tech/v1/webhooks/receive-test \
  -H "X-Provento-Signature: t=1786452000,v1=5d48f102..."
{
  "received": true
}
post/v1/webhooks/dispatch

Despachar fila (interno)

Worker que drena a fila de saída com backoff. Acionado por Vercel Cron e protegido por `PROVENTO_CRON_SECRET` — não faz parte da API pública.

authinterno — segredo do worker
Respostas
200Resumo do despacho.
401Segredo ausente ou incorreto.
POST /v1/webhooks/dispatch
curl -X POST https://pay.provento.tech/v1/webhooks/dispatch \
  -H "Authorization: Bearer $PROVENTO_CRON_SECRET"
{
  "dispatched": 3,
  "failed": 0
}

Verificar a assinatura

Todo webhook de saída vai assinado. Verifique antes de confiar no corpo — sem isso, qualquer um que descubra sua URL pode forjar um pagamento aprovado.

O header X-Provento-Signature traz t=<unix>,v1=<hmac>. O HMAC-SHA256 cobre a string ${t}.${corpoCru} — o corpo cru, antes de qualquer parse.

1
Leia o corpo cru
Sem JSON.parse antes.
2
Recompute o HMAC
Com seu whsec.
3
Compare em tempo constante
Nunca com ==.

Rejeitamos assinaturas com mais de 5 minutos — é a proteção contra replay. Faça o mesmo do seu lado.

verificação
import { createHmac, timingSafeEqual } from "node:crypto";

export function verificar(segredo, corpoCru, header) {
  const partes = Object.fromEntries(
    header.split(",").map((kv) => kv.split("=", 2)),
  );
  const t = Number(partes.t);
  if (!Number.isFinite(t) || !partes.v1) return false;

  // rejeita replay: tolerância de 5 minutos
  const agora = Math.floor(Date.now() / 1000);
  if (Math.abs(agora - t) > 300) return false;

  const esperado = createHmac("sha256", segredo)
    .update(`${t}.${corpoCru}`)
    .digest("hex");

  const a = Buffer.from(esperado, "hex");
  const b = Buffer.from(partes.v1, "hex");
  return a.length === b.length && timingSafeEqual(a, b);
}

Catálogo de erros

Todo erro sai no mesmo formato. Trate pelo campo code, nunca pela mensagem — a mensagem pode mudar, o código não.

422
validation_error

Corpo ou parâmetro inválido. Veja error.fields para saber qual.

401
unauthorized

Chave ausente, inválida ou revogada.

404
not_found

O recurso não existe — ou não pertence a esta chave.

409
conflict

Conflito de estado, como confirmar uma cobrança já paga.

500
internal_error

Falha nossa. Pode repetir com a mesma Idempotency-Key.

formato do erro
{
  "error": {
    "code": "validation_error",
    "message": "Valor deve ser maior que zero.",
    "fields": {
      "amount": "deve ser um inteiro positivo em centavos"
    }
  }
}