/v1/chargesCriar Cobrança
Cria uma nova cobrança Pix via PSP configurado. Retorna o Pix copia-e-cola e o QR code em base64.
Headers
| Header | Obrigatório | Descrição |
|---|---|---|
Authorization | Sim | Bearer hpx_... |
Content-Type | Sim | application/json |
Idempotency-Key | Não | UUID para garantir idempotência. Mesma key + mesmo body retorna a mesma cobrança. |
Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amount | integer | Sim | Valor em centavos. Ex: 5000 = R$ 50,00 |
provider | string | Sim | "asaas", "mercadopago", "efi", "pagarme", "starkbank", "stripe", "iugu", "pagseguro", "inter", "sicredi", "sicoob", "openpix", "bradesco" ou "random" (distribuição automática round-robin entre todos os PSPs conectados) |
Para usar o Efí, é necessário cadastrar o certificado PEM no dashboard em PSPs → Conectar novo PSP. Para o Pagar.me, informe a Secret Key (sk_test_... ou sk_...) nas configurações do PSP. Para o Stark Bank, informe Project ID + chave privada ECDSA (PEM). Para o Stripe, informe a Secret Key (sk_test_... ou sk_live_...). Para o Iugu, informe o API Token; payer.email é recomendado (o adapter usa email padrão se omitido). Para o PagSeguro/PagBank, informe o Token (Bearer); payer.name, payer.email e payer.document são obrigatórios. Para o Banco Inter, informe Client ID + Secret + Chave Pix + Certificado (.crt) + Chave Privada (.key); funciona apenas para contas PJ. Para o Sicredi, informe Client ID + Secret + Chave Pix + Certificado + Chave Privada gerados no Portal do Desenvolvedor Sicredi; disponível apenas para associados PJ. Para o Sicoob, informe Client ID + Chave Pix + Certificado ICP-Brasil A1 (.pem) + Chave Privada (.key); não usa Client Secret (auth via mTLS) e disponível apenas para cooperados. Para o OpenPix/Woovi, informe apenas o AppID — sem OAuth, sem certificado; é o PSP mais simples e nenhum campo de payer é obrigatório. Para o Bradesco, informe Client ID + Client Secret + Chave Pix + Certificado + Chave Privada (.pem/.key); credenciais obtidas via email suporte.api@bradesco.com.br após assinatura de contrato; disponível apenas para conta PJ. O modo "random" exige pelo menos 2 PSPs ativos no mesmo ambiente. | |||
description | string | Não | Descrição da cobrança (max 500 chars) |
expires_in_seconds | integer | Não | Expiração em segundos. Default: 86400 (24h) |
payer.name | string | Não | Nome do pagador |
payer.document | string | Não | CPF (11 dígitos) ou CNPJ (14 dígitos), só números |
payer.email | string | Não | Email do pagador |
metadata | object | Não | Dados livres. Ex: {"order_id": "123"} |
Exemplos
curl https://api.hubpay.dev/v1/charges \
-X POST \
-H "Authorization: Bearer hpx_test_sua_chave" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"amount": 5000,
"provider": "asaas",
"description": "Pedido #1234",
"payer": {
"name": "Maria Souza",
"document": "12345678901",
"email": "maria@exemplo.com"
},
"metadata": {
"order_id": "1234"
}
}'Resposta 201
{
"id": "chg_a1b2c3d4e5f6...",
"object": "charge",
"status": "pending",
"amount": 5000,
"currency": "BRL",
"description": "Pedido #1234",
"provider": "asaas",
"environment": "test",
"pix": {
"copy_paste": "00020126580014br.gov.bcb.pix...",
"qr_code_base64": "iVBORw0KGgoAAAANSUhEUgAA..."
},
"payer": {
"name": "Maria Souza",
"document": "12345678901",
"email": "maria@exemplo.com"
},
"metadata": { "order_id": "1234" },
"expires_at": "2026-04-16T14:00:00.000Z",
"paid_at": null,
"created_at": "2026-04-15T14:00:00.000Z",
"updated_at": "2026-04-15T14:00:00.000Z"
}Provider “random” — distribuição automática
Ao enviar "provider": "random", o Hubpay distribui automaticamente as cobranças entre todos os PSPs que você tem conectados, usando round-robin (rodízio sequencial por usuário).
Como funciona: com Asaas, Efí e Mercado Pago conectados, as requisições são roteadas em ordem alfabética: Asaas → Efí → Mercado Pago → Asaas → ...
Fallback automático: se o PSP selecionado retornar erro, o Hubpay tenta automaticamente o próximo da lista. Se todos falharem, retorna 502 psp_error.
Requisitos: pelo menos 2 PSPs ativos conectados no mesmo ambiente (test ou live). Com apenas 1 PSP, use o nome do provider diretamente — retorna 400 invalid_request caso contrário.
Quando "random" é usado, a resposta inclui o campo extra routing:
{
"id": "chg_a1b2c3d4e5f6...",
"status": "pending",
"provider": "mercadopago",
"routing": {
"mode": "round_robin",
"selected_provider": "mercadopago",
"attempted_providers": ["asaas", "mercadopago"]
},
"pix": { "copy_paste": "00020126..." },
...
}attempted_providers lista os PSPs tentados na ordem. Se tem um item, o primeiro funcionou. Se tem dois ou mais, houve fallback. O campo routing não aparece quando um provider específico é usado.
Limites de volume por PSP
Configure quanto cada PSP processa antes de passar pro próximo. O sistema preenche o PSP até o limite, zera o acumulado e avança automaticamente. O ciclo é contínuo.
Exemplo: PSP1 com limite R$ 10.000 e PSP3 com limite R$ 15.000. PSP1 recebe cobranças até atingir R$ 10.000, então o acumulado zera e o PSP3 assume. O PSP3 recebe até R$ 15.000, então zera e o ciclo volta pro PSP1.
Se nenhum PSP tem limite, o roteamento é round-robin simples (1 cobrança pra cada, alternando). Configure em Dashboard → PSPs → ações → Configurar roteamento.
Quando o PSP selecionado tem limite, o routing inclui o estado atual do ciclo:
{
"routing": {
"mode": "round_robin",
"selected_provider": "asaas",
"attempted_providers": ["asaas"],
"volume": {
"limit_cents": 1000000,
"accumulated_cents": 450000,
"remaining_cents": 550000
}
}
}Você também pode desativar um PSP do roteamento (routeEnabled: false) sem desativá-lo por completo: cobranças com provider: "random" ignoram esse PSP, mas cobranças com provider: "<nome>" diretamente continuam funcionando.
Erros possíveis
| Status | type | Quando |
|---|---|---|
400 | invalid_request | Body malformado ou campo inválido |
401 | unauthorized | API key ausente, inválida ou revogada |
402 | psp_not_configured | Nenhum PSP ativo para o ambiente/provider |
403 | forbidden | Quota do plano excedida ou conta suspensa |
409 | idempotency_conflict | Mesma Idempotency-Key com body diferente |
502 | psp_error | PSP retornou erro (detalhes em message) |