POST /v1/charges
Create a charge — card, Pix, or boleto.
Cria uma cobrança. Aceita os métodos card, pix e boleto. Requer os cabeçalhos
Authorization com sua chave secreta (Basic, com a chave como usuário e senha
vazia, ou Bearer <chave>) e Idempotency-Key com uma chave única por intenção
(até 255 caracteres, apenas A-Z a-z 0-9 _ - : .).
Exemplo (curl)
curl -X POST https://api.kirvex.com.br/v1/charges -u "$KIRVEX_SECRET_KEY:" -H "Content-Type: application/json" -H "Idempotency-Key: pedido-1234-pix-1" -d '{
"amount": { "amount": "9990", "currency": "BRL" },
"method": "pix",
"description": "Pedido #1234",
"customer": { "email": "ada@lovelace.com", "name": "Ada Lovelace", "document": "12345678909" },
"pix": { "expiresInSeconds": 3600 },
"metadata": { "product_id": "prod_...", "offer_id": "poff_..." }
}'
O painel mostra este mesmo exemplo já preenchido com os IDs do seu produto em Produtos → (produto) → Integrações.
Modo de teste: sk_test_ e sk_live_
Existe uma só API, em https://api.kirvex.com.br. É a chave que decide o
modo, não a URL:
sk_live_cobra de verdade.sk_test_nunca move dinheiro real. A cobrança vai para o ambiente de teste (sandbox) do adquirente — Stripe para cartão, Woovi ou Pagar.me para Pix, Pagar.me para boleto, conforme o que estiver configurado na Kirvex.
Uma cobrança de teste volta com "livemode": false. Ela não entra no seu
saldo, não vira saque e não aparece nas vendas, relatórios e exportações do
painel. Os webhooks dela chegam com "livemode": false.
Se o método pedido não tem sandbox configurado, a cobrança é recusada com
422 e o código test_mode_unavailable. Ela nunca é enviada para produção no
lugar. A aba Produtos → (produto) → Integrações do painel mostra, por
método, se o teste está disponível agora.
Cada chave só enxerga os objetos do seu modo: GET, estorno, captura e
cancelamento de uma cobrança real com uma chave sk_test_ respondem 404, e o
mesmo vale ao contrário. As chaves de idempotência também são separadas por
modo.
Operações que só existem com dinheiro real recusam a chave sk_test_ com
test_mode_unavailable: saque (/v1/payouts), antecipação, faturas e saques
em cripto, recebedores, assinaturas e links de pagamento.
O que a cobrança pela API não faz
A cobrança criada por esta rota não gera pedido. Ela não envia o e-mail de
entrega do produto, não libera área de membros e não gera comissão de afiliado
nem rateio de coprodução — isso só acontece em vendas pelo checkout ou pelo link
de pagamento. O valor cobrado é sempre o de amount: a API não lê preço de
produto ou oferta. Para amarrar a cobrança a um produto, mande os IDs em
metadata; a Kirvex guarda e devolve esse campo em GET /v1/charges/{id}. Os
eventos de webhook trazem o charge_id, não o metadata.
Request body
{
"amount": { "amount": "9990", "currency": "BRL" },
"method": "pix",
"description": "Pedido #1234",
"customer": {
"email": "ada@lovelace.com",
"name": "Ada Lovelace",
"document": "12345678909"
},
"pix": { "expiresInSeconds": 3600 },
"metadata": { "product_id": "prod_...", "offer_id": "poff_..." }
}
customeroucustomer_id(um dos dois é obrigatório).metadata: objeto de texto → texto, opcional. Guardado com a cobrança.pix.expiresInSeconds: de 60 a 86400.
Response 201
{
"id": "ch_018f1c4b00007abcdef1234567890abc",
"object": "charge",
"status": "pending",
"method": "pix",
"amount": { "amount": "9990", "currency": "BRL" },
"vendor": "woovi",
"vendor_ref": "ch_vnd_xxx",
"created_at": "2026-04-29T12:34:56Z",
"pix": { "qrCode": "00020126..." }
}
Errors
Toda resposta de erro segue o envelope:
{
"error": {
"type": "...",
"code": "...",
"message": "...",
"request_id": "...",
"retryable": false
}
}
Códigos previstos:
validation_erroridempotency_conflictunauthorizedvendor_unavailablecard_declinedkyc_requiredinternal_error
Refund, capture, void
Endpoints relacionados (todos requerem Idempotency-Key):
POST /v1/charges/{id}/refund— full ou partial refund. Aceitaamountopcional no body. Faz reverse-sweep proporcional no ledger.POST /v1/charges/{id}/capture— captura explícita para cards em modomanualcapture.POST /v1/charges/{id}/void— cancela uma cobrança autorizada (não capturada).
OpenAPI
A spec completa está em /openapi.json.