POST/v1/charges

Criar Cobrança

Cria uma nova cobrança Pix via PSP configurado. Retorna o Pix copia-e-cola e o QR code em base64.

Headers

HeaderObrigatórioDescrição
AuthorizationSimBearer hpx_...
Content-TypeSimapplication/json
Idempotency-KeyNãoUUID para garantir idempotência. Mesma key + mesmo body retorna a mesma cobrança.

Body

CampoTipoObrigatórioDescrição
amountintegerSimValor em centavos. Ex: 5000 = R$ 50,00
providerstringSim"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.
descriptionstringNãoDescrição da cobrança (max 500 chars)
expires_in_secondsintegerNãoExpiração em segundos. Default: 86400 (24h)
payer.namestringNãoNome do pagador
payer.documentstringNãoCPF (11 dígitos) ou CNPJ (14 dígitos), só números
payer.emailstringNãoEmail do pagador
metadataobjectNãoDados livres. Ex: {"order_id": "123"}

Exemplos

bash
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

json
{
  "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:

json
{
  "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:

json
{
  "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

StatustypeQuando
400invalid_requestBody malformado ou campo inválido
401unauthorizedAPI key ausente, inválida ou revogada
402psp_not_configuredNenhum PSP ativo para o ambiente/provider
403forbiddenQuota do plano excedida ou conta suspensa
409idempotency_conflictMesma Idempotency-Key com body diferente
502psp_errorPSP retornou erro (detalhes em message)