Aruba Aruba Documentação da API api.arubabr.com

Começar

API de pagamentos da Aruba

Crie cobranças PIX a partir do seu sistema e receba a confirmação por webhook. REST, JSON e autenticação por API Key.

Arquivos para IA

Vai integrar com um assistente de código (Claude, ChatGPT, Cursor, Copilot…)? Passe para ele docs.arubabr.com/llms-full.txt: é esta documentação inteira em Markdown, com as regras que o código precisa seguir. O índice no padrão llms.txt está em docs.arubabr.com/llms.txt. Veja Para IA.

Como funciona

01Seu servidor cria a cobrançaPOST /api/v1/direct-payments com valor, método e comprador, autenticado pela API Key.
02O comprador pagaVocê mostra o que veio em payment_data: o código PIX copia-e-cola e o QR Code.
03A Aruba avisaWebhook no seu servidor. A venda está paga quando o status é AUTHORIZED.

A criação devolve a cobrança com status PENDING. A confirmação chega depois, quando o banco do comprador conclui o pagamento: por webhook ou pela consulta de status.

Recursos da API

Endereço da API

https://api.arubabr.com

Requisições e respostas usam JSON. Envie Content-Type: application/json nas requisições com corpo.

Endpoints

MétodoCaminhoAutenticaçãoUso
POST/api/v1/direct-paymentsHeader X-API-KeyCriar uma cobrança
GET/api/v1/payments/{transaction_id}/statusNenhumaConsultar o status de uma transação

Formato das respostas

Toda resposta tem o campo hasError. Com sucesso, os dados vêm em data; com erro, a mensagem vem em error (veja Erros).

{
  "hasError": false,
  "data": { "transaction_id": "7KQ2M9XA4T1B", "status": "PENDING" }
}
{
  "hasError": true,
  "error": "API key não fornecida. Envie a chave no header X-API-Key",
  "errorFields": [],
  "statusCode": 401,
  "timestamp": "2026-10-23T15:19:01.612Z",
  "path": "/api/v1/direct-payments"
}

Conceitos

  • Transação. Cada cobrança criada gera uma transação, identificada por transaction_id. Guarde esse valor junto com o seu pedido: é ele que liga a criação, a consulta de status e o webhook.
  • Valores. Na criação, amount é um inteiro em centavos de real. Nas respostas, os valores vêm em unidades decimais (99.9 = R$ 99,90). Detalhes em Valores e limites.
  • Produção. As chaves de API são de produção (pk_live_…) e não existe modo de teste separado: toda cobrança criada é real. Para testar a integração, crie um PIX de valor baixo e pague você mesmo.

Começar

Início rápido

Sua primeira cobrança PIX em quatro passos. Esse é o fluxo inteiro de uma integração.

  1. Gere uma API Key

    No painel da Aruba, abra Integração → API Keys e clique em Nova API Key. Copie a chave (pk_live_…) na hora: ela aparece uma única vez. Guarde-a numa variável de ambiente do seu servidor, por exemplo ARUBA_API_KEY.

  2. Crie a cobrança

    Chame o endpoint de cobrança a partir do seu servidor. amount vai em centavos: 9990 = R$ 99,90.

    curl -X POST https://api.arubabr.com/api/v1/direct-payments \
      -H "Content-Type: application/json" \
      -H "X-API-Key: $ARUBA_API_KEY" \
      -d '{
        "amount": 9990,
        "description": "Pedido 1234",
        "paymentMethod": "pix",
        "customer": {
          "name": "João da Silva",
          "email": "joao@exemplo.com",
          "document": "12345678909"
        }
      }'
    const res = await fetch("https://api.arubabr.com/api/v1/direct-payments", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-API-Key": process.env.ARUBA_API_KEY,
      },
      body: JSON.stringify({
        amount: 9990, // R$ 99,90 em centavos
        description: "Pedido 1234",
        paymentMethod: "pix",
        customer: {
          name: "João da Silva",
          email: "joao@exemplo.com",
          document: "12345678909",
        },
      }),
    });
    const body = await res.json();
    if (!res.ok) throw new Error(body.error);
    
    const { transaction_id, payment_data } = body.data;
    // Salve transaction_id no seu pedido antes de seguir.
    $payload = [
      "amount" => 9990, // R$ 99,90 em centavos
      "description" => "Pedido 1234",
      "paymentMethod" => "pix",
      "customer" => [
        "name" => "João da Silva",
        "email" => "joao@exemplo.com",
        "document" => "12345678909",
      ],
    ];
    
    $ch = curl_init("https://api.arubabr.com/api/v1/direct-payments");
    curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: " . getenv("ARUBA_API_KEY"),
      ],
      CURLOPT_POSTFIELDS => json_encode($payload),
    ]);
    $body = json_decode(curl_exec($ch), true);
    $http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($http >= 400) throw new Exception($body["error"]);
    $transactionId = $body["data"]["transaction_id"]; // salve no seu pedido
    {
      "hasError": false,
      "data": {
        "transaction_id": "7KQ2M9XA4T1B",
        "total_value": 99.9,
        "status": "PENDING",
        "email": "joao@exemplo.com",
        "payment_method": "pix",
        "payment_data": {
          "expiration_date": null,
          "payment_id": "c1a7e0b2-5d3f-4e8a-9b61-0f2d7c4e9a13",
          "pix_key": "00020126580014br.gov.bcb.pix0136…6304A1B2",
          "status": "PENDING",
          "status_detail": "WAITING_PAYMENT",
          "total_transaction_value": 99.9
        }
      }
    }
  3. Mostre o PIX ao comprador

    payment_data.pix_key é o código copia-e-cola. Mostre-o com um botão de copiar e gere o QR Code a partir dele com a biblioteca de QR Code que preferir. Envie ao navegador só o que ele precisa exibir, nunca a API Key.

  4. Confirme o pagamento

    Cadastre a URL do seu servidor em Integração → Webhooks. Quando o PIX for pago, a Aruba envia um POST com "status": "AUTHORIZED". Confirme na consulta de status e libere o pedido.

    curl https://api.arubabr.com/api/v1/payments/7KQ2M9XA4T1B/status
Só AUTHORIZED é pagamento confirmado

A resposta da criação traz a cobrança ainda pendente. Libere o pedido apenas quando o seu servidor receber ou consultar o status AUTHORIZED.

Próximos passos

Começar

Autenticação

A criação de cobranças é autenticada por API Key, enviada no header X-API-Key. Cada chave pertence a uma conta: as cobranças criadas com ela entram nessa conta.

Criar uma API Key

  1. No painel da Aruba, abra Integração → API Keys.
  2. Clique em Nova API Key, dê um nome (3 a 100 caracteres) e, se quiser, uma descrição (até 255).
  3. Copie a chave exibida. Ela aparece uma única vez. Se perder, crie outra.

A chave tem o formato pk_live_ seguido de 48 caracteres hexadecimais em minúsculas.

Enviar a chave

POST /api/v1/direct-payments HTTP/1.1
Host: api.arubabr.com
Content-Type: application/json
X-API-Key: pk_live_…

A consulta de status não usa API Key.

Gerenciar chaves

  • Limite: até 10 chaves ativas por conta.
  • Pausar: em Editar (ou no menu da chave), mude o status para pausada. A API passa a recusar a chave até você reativá-la.
  • Deletar: remove a chave de vez. Chamadas com ela passam a receber 401.

Boas práticas

  • Use a chave só no servidor. Nunca a coloque em front-end, app mobile ou repositório de código.
  • Guarde-a em variável de ambiente ou num cofre de segredos.
  • Crie uma chave por integração: dá para trocar ou pausar uma sem afetar as outras.
  • Se suspeitar de vazamento, delete a chave e crie outra.

Erros de autenticação

Problemas de autenticação respondem HTTP 401, com a mensagem em error:

MensagemCausa
API key não fornecida. Envie a chave no header X-API-KeyO header não foi enviado.
Formato de API key inválidoA chave não tem o formato pk_live_ + 48 hexadecimais. Confira se foi copiada inteira, sem espaços ou quebras de linha.
API key inválidaNão existe chave com esse valor (por exemplo, ela foi deletada).
API key está inativa ou revogadaA chave está pausada. Reative em Integração → API Keys.
Seller está bloqueado para receber pagamentosA conta está bloqueada. Fale com o suporte.

Cobranças

Criar cobrança

POST/api/v1/direct-paymentsHeader X-API-Key

Cria uma cobrança PIX para um comprador, sem produto cadastrado na Aruba. A resposta traz o código copia-e-cola em payment_data.

Corpo da requisição

CampoTipoObrigatórioDescrição
amountinteiroobrigatórioValor em centavos de real, a partir de 1. Ex.: 9990 = R$ 99,90. Não envie valores decimais em reais.
descriptionstringobrigatórioDescrição da cobrança, de 3 a 255 caracteres.
paymentMethodstringobrigatóriopix.
customerobjetoobrigatórioDados do comprador (abaixo).
Campos desconhecidos são recusados

A API responde 400 se o corpo tiver um campo que ela não conhece (por exemplo currency). Envie só os campos desta página.

Objeto customer

CampoTipoObrigatórioDescrição
namestringobrigatórioNome completo, de 3 a 128 caracteres.
emailstringobrigatórioE-mail válido do comprador.
documentstringobrigatórioCPF (11 dígitos) ou CNPJ (14 dígitos) válido, só números.
phonestringopcionalFormato E.164, com + e código do país, ex.: +5511999999999. Precisa ser um número válido.
birthDatestringopcionalData de nascimento no formato DD/MM/AAAA, ex.: 15/01/1990. O formato AAAA-MM-DD é recusado.
addressobjetoopcionalEndereço do comprador (abaixo).
utmobjetoopcionalParâmetros de rastreamento da venda (abaixo).

Objeto customer.address

Se enviar o endereço, os campos marcados como obrigatórios passam a ser exigidos.

CampoTipoObrigatórioDescrição
zipCodestringobrigatórioCEP com 8 dígitos, sem hífen.
streetstringobrigatórioLogradouro, de 3 a 128 caracteres.
districtstringobrigatórioBairro, de 3 a 128 caracteres.
citystringobrigatórioCidade, de 3 a 128 caracteres.
statestringobrigatórioUF, ex.: SP.
numberstringopcionalNúmero, de 1 a 6 caracteres.
complementstringopcionalComplemento, de 1 a 48 caracteres.

Objeto customer.utm

CampoTipoDescrição
sourcestringutm_source, até 128 caracteres.
mediumstringutm_medium, até 128 caracteres.
campaignstringutm_campaign, até 128 caracteres.
termstringutm_term, até 128 caracteres.
contentstringutm_content, até 128 caracteres.
srcstringParâmetro src usado na integração com a Utmify, até 2048 caracteres.
sckstringParâmetro sck usado na integração com a Utmify, até 256 caracteres.

Exemplo completo

curl -X POST https://api.arubabr.com/api/v1/direct-payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $ARUBA_API_KEY" \
  -d '{
    "amount": 15000,
    "description": "Assinatura anual",
    "paymentMethod": "pix",
    "customer": {
      "name": "Maria Souza",
      "email": "maria@exemplo.com",
      "document": "12345678909",
      "phone": "+5511999999999",
      "birthDate": "15/01/1990",
      "address": {
        "zipCode": "01310100",
        "street": "Avenida Paulista",
        "number": "1000",
        "complement": "Sala 101",
        "district": "Bela Vista",
        "city": "São Paulo",
        "state": "SP"
      },
      "utm": { "source": "google", "medium": "cpc", "campaign": "lancamento" }
    }
  }'
const res = await fetch("https://api.arubabr.com/api/v1/direct-payments", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": process.env.ARUBA_API_KEY,
  },
  body: JSON.stringify({
    amount: 15000,
    description: "Assinatura anual",
    paymentMethod: "pix",
    customer: {
      name: "Maria Souza",
      email: "maria@exemplo.com",
      document: "12345678909",
      phone: "+5511999999999",
      birthDate: "15/01/1990",
      address: {
        zipCode: "01310100",
        street: "Avenida Paulista",
        number: "1000",
        complement: "Sala 101",
        district: "Bela Vista",
        city: "São Paulo",
        state: "SP",
      },
      utm: { source: "google", medium: "cpc", campaign: "lancamento" },
    },
  }),
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error} ${body.errorFields.join("; ")}`);
$payload = [
  "amount" => 15000,
  "description" => "Assinatura anual",
  "paymentMethod" => "pix",
  "customer" => [
    "name" => "Maria Souza",
    "email" => "maria@exemplo.com",
    "document" => "12345678909",
    "phone" => "+5511999999999",
    "birthDate" => "15/01/1990",
    "address" => [
      "zipCode" => "01310100",
      "street" => "Avenida Paulista",
      "number" => "1000",
      "complement" => "Sala 101",
      "district" => "Bela Vista",
      "city" => "São Paulo",
      "state" => "SP",
    ],
    "utm" => ["source" => "google", "medium" => "cpc", "campaign" => "lancamento"],
  ],
];

$ch = curl_init("https://api.arubabr.com/api/v1/direct-payments");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Content-Type: application/json", "X-API-Key: " . getenv("ARUBA_API_KEY")],
  CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);

Resposta

Com sucesso, a API responde 201 Created:

CampoTipoDescrição
transaction_idstringIdentificador da transação na Aruba. Use na consulta de status e para reconhecer o webhook.
total_valuenúmeroValor cobrado em reais (não em centavos). Ex.: 99.9.
statusstringStatus inicial da cobrança, normalmente PENDING.
emailstringE-mail do comprador, em minúsculas.
payment_methodstringO método enviado, em minúsculas: pix.
payment_dataobjetoO que o comprador precisa para pagar. Veja PIX.
Cada chamada cria uma cobrança nova

A criação não tem chave de idempotência. Se a requisição falhar por timeout ou erro de rede, não repita automaticamente: confira em Vendas, no painel, se a cobrança foi criada antes de gerar outra.

Erros mais comuns

HTTPMensagemO que fazer
401API key não fornecida… e similaresVeja Autenticação.
400Erro na validação dos camposLeia errorFields: ele lista cada campo com problema.
400document é obrigatório para este método de pagamentoEnvie o CPF ou CNPJ do comprador.
400document deve ser um CPF ou CNPJ válido (somente números)Confira os dígitos do documento.
400Você ainda não possui documentos validados para gerar pagamentosConclua a validação de documentos da sua conta no painel.

A lista completa está em Erros.

Cobranças

PIX

Cobrança em reais paga com copia-e-cola ou QR Code no app do banco.

País BRMoeda BRLpaymentMethod "pix"

Requisição

CampoRegra no PIX
amountCentavos de real. 9990 = R$ 99,90.
customer.documentobrigatório CPF ou CNPJ válido, só números.
curl -X POST https://api.arubabr.com/api/v1/direct-payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $ARUBA_API_KEY" \
  -d '{
    "amount": 9990,
    "description": "Pedido 1234",
    "paymentMethod": "pix",
    "customer": { "name": "João da Silva", "email": "joao@exemplo.com", "document": "12345678909" }
  }'
const res = await fetch("https://api.arubabr.com/api/v1/direct-payments", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-API-Key": process.env.ARUBA_API_KEY },
  body: JSON.stringify({
    amount: 9990,
    description: "Pedido 1234",
    paymentMethod: "pix",
    customer: { name: "João da Silva", email: "joao@exemplo.com", document: "12345678909" },
  }),
});
const { data } = await res.json();
// Para o front: só o copia-e-cola e o valor
return { transactionId: data.transaction_id, pix: data.payment_data.pix_key, valor: data.total_value };
$ch = curl_init("https://api.arubabr.com/api/v1/direct-payments");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Content-Type: application/json", "X-API-Key: " . getenv("ARUBA_API_KEY")],
  CURLOPT_POSTFIELDS => json_encode([
    "amount" => 9990,
    "description" => "Pedido 1234",
    "paymentMethod" => "pix",
    "customer" => ["name" => "João da Silva", "email" => "joao@exemplo.com", "document" => "12345678909"],
  ]),
]);
$data = json_decode(curl_exec($ch), true)["data"];
curl_close($ch);
$copiaECola = $data["payment_data"]["pix_key"];

Resposta

Campos de payment_data no PIX:

CampoTipoDescrição
pix_keystringCódigo PIX copia-e-cola. Mostre com botão de copiar e gere o QR Code a partir dele.
expiration_datestring | nullValidade informada pelo processador, em ISO 8601. Pode vir null.
payment_idstringIdentificador da cobrança no processador. Para tudo na Aruba, use o transaction_id.
status, status_detailstringSituação no momento da criação (PENDING / WAITING_PAYMENT). Não muda depois: o status que vale é o da raiz, na consulta ou no webhook.
total_transaction_valuenúmeroValor em reais.

Dependendo do processador, payment_data pode trazer outros campos. Ignore os que você não usa.

Tela de pagamento

  • Mostre o valor, o código copia-e-cola com botão Copiar e o QR Code gerado a partir de pix_key.
  • Enquanto a tela estiver aberta, consulte o status a cada 5 a 15 segundos para trocar a mensagem quando o pagamento for confirmado. A consulta não exige API Key e pode ser feita pelo navegador.
  • Essa consulta no navegador serve só para a experiência do comprador. A liberação do pedido acontece no seu servidor (webhook + consulta).
async function aguardarPagamento(transactionId, { intervalo = 10000, limite = 30 * 60 * 1000 } = {}) {
  const url = `https://api.arubabr.com/api/v1/payments/${transactionId}/status`;
  const fim = Date.now() + limite;
  while (Date.now() < fim) {
    const res = await fetch(url);
    if (res.ok) {
      const { data } = await res.json();
      if (data.status === "AUTHORIZED") return "pago";
      if (["REJECTED", "CANCELED"].includes(data.status)) return "nao-pago";
    }
    await new Promise((r) => setTimeout(r, intervalo));
  }
  return "tempo-esgotado";
}

Vencimento

Não existe status de expiração

Um PIX vencido e não pago pode continuar PENDING ou mudar para REJECTED ou CANCELED, conforme o processador. Controle o prazo do pedido do seu lado e, se o comprador voltar depois, gere uma nova cobrança.

Depois do pagamento

Consultar status

GET/api/v1/payments/{transaction_id}/statusSem autenticação

Devolve o status atual da transação e os dados de pagamento gravados na criação. Não exige API Key: pode ser chamada pelo seu servidor, para confirmar um webhook, e pelo navegador, para atualizar a tela do comprador.

Parâmetro

ParâmetroEmDescrição
transaction_idcaminhoO transaction_id devolvido na criação da cobrança.

Requisição

curl https://api.arubabr.com/api/v1/payments/7KQ2M9XA4T1B/status
const res = await fetch(`https://api.arubabr.com/api/v1/payments/${transactionId}/status`);
const body = await res.json();
if (!res.ok) throw new Error(body.error); // ex.: "Pedido não encontrado!"

console.log(body.data.status); // "PENDING", "AUTHORIZED"…
$url = "https://api.arubabr.com/api/v1/payments/" . urlencode($transactionId) . "/status";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);

$status = $body["data"]["status"] ?? null; // "PENDING", "AUTHORIZED"…

Resposta

{
  "hasError": false,
  "data": {
    "transaction_id": "7KQ2M9XA4T1B",
    "total_value": 99.9,
    "fee": 4.49,
    "net_value": 95.41,
    "status": "AUTHORIZED",
    "product": null,
    "payment_method": "PIX",
    "producer": null,
    "payment_data": {
      "pix_key": "00020126580014br.gov.bcb.pix0136…6304A1B2",
      "expiration_date": null,
      "payment_id": "c1a7e0b2-5d3f-4e8a-9b61-0f2d7c4e9a13",
      "status": "PENDING",
      "status_detail": "WAITING_PAYMENT",
      "total_transaction_value": 99.9
    }
  }
}

Os valores do exemplo são ilustrativos: a taxa depende do plano da sua conta.

CampoTipoDescrição
transaction_idstringIdentificador da transação.
statusstringStatus atual. É o campo que vale; veja Status da transação.
total_valuenúmeroValor da transação em reais.
feenúmeroTaxa da Aruba, em reais.
net_valuenúmeroValor líquido para você, em reais.
payment_methodstringMétodo em maiúsculas: PIX.
product, producerobjeto | nullnull nas cobranças criadas pela API. Vêm preenchidos nas vendas de produto feitas pelo checkout da Aruba.
payment_dataobjetoDados gravados na criação, como o pix_key.
Use o status da raiz

No PIX, payment_data.status é a foto do momento da criação e continua PENDING mesmo depois do pagamento. O status atual é sempre data.status.

Erros

HTTPMensagemCausa
400Pedido não encontrado!Não existe transação com esse transaction_id.

Polling

  • Consulte a cada 5 a 15 segundos, com um limite de tempo, e pare quando o status deixar de ser PENDING.
  • Polling é apoio. Para liberar pedidos, use o webhook e confirme com esta consulta.

Depois do pagamento

Webhooks

A Aruba avisa o seu servidor com um POST em JSON quando uma transação sua é atualizada. Use o aviso como gatilho e confirme o status na consulta antes de liberar o pedido.

Cadastrar a URL

  1. No painel da Aruba, abra Integração → Webhooks e clique em Novo Webhook.
  2. Informe um nome e a URL de destino. Use HTTPS.
  3. Escolha os eventos que esse webhook deve receber (veja a tabela abaixo). É preciso marcar ao menos um.
  4. Se o seu endpoint exige autenticação, escolha o tipo de autenticação: Basic Auth (usuário e senha) ou Bearer Token. Sem autenticação, deixe em Nenhuma.
  5. Clique em Cadastrar. O webhook já nasce ativo.
  • Você pode cadastrar mais de uma URL (o painel aceita até 10). Cada URL ativa recebe os eventos que escolheu.
  • Em Editar, dá para trocar URL, eventos e autenticação. Com Pausar, o webhook deixa de receber disparos até ser ativado de novo.
  • Os avisos cobrem todas as transações da sua conta, não só as criadas pela API. Ignore os transaction_id que a sua integração não conhece.

Eventos

Cada aviso leva o nome do evento no campo event. O webhook só recebe os eventos que foram marcados nele.

EventoStatusDescrição
transaction.pendingPENDINGVenda criada, aguardando pagamento.
transaction.processingPROCESSINGVenda em processamento.
transaction.paidAUTHORIZEDPagamento aprovado.
transaction.refundedREFUNDEDVenda reembolsada.
transaction.canceledCANCELEDVenda cancelada.
transaction.rejectedREJECTEDPagamento recusado.
transaction.chargebackCHARGEBACKChargeback recebido.
transaction.disputeIN_DISPUTEVenda em disputa.
Marque ao menos transaction.paid

Para liberar pedidos, o webhook precisa receber transaction.paid. Para tratar devoluções, inclua também transaction.refunded, transaction.chargeback e transaction.dispute.

Quando a Aruba envia

  • Quando o processador informa uma atualização da transação: pagamento aprovado, recusa, cancelamento, estorno, chargeback, disputa e atualizações de pendência.
  • Quando a equipe da Aruba aprova uma transação manualmente.
  • Não há aviso na criação da cobrança. Uma falha ao gerar a cobrança (FAILED) também não gera aviso: nesse caso a própria criação já respondeu erro.
  • O mesmo status pode chegar mais de uma vez, por exemplo duas atualizações seguidas com PENDING.

Requisição enviada

POST para a sua URL, com Content-Type: application/json e este corpo:

{
  "event": "transaction.paid",
  "transaction_id": "7KQ2M9XA4T1B",
  "total_value": 99.9,
  "fee": 4.49,
  "net_value": 95.41,
  "status": "AUTHORIZED",
  "product": null,
  "payment_method": "PIX",
  "producer": null,
  "payment_data": {
    "pix_key": "00020126580014br.gov.bcb.pix0136…6304A1B2",
    "expiration_date": null,
    "payment_id": "c1a7e0b2-5d3f-4e8a-9b61-0f2d7c4e9a13",
    "status": "PENDING",
    "status_detail": "WAITING_PAYMENT",
    "total_transaction_value": 99.9
  },
  "customer": {
    "name": "João da Silva",
    "email": "joao@exemplo.com",
    "document": "12345678909",
    "phone": "+5511999999999",
    "birth_date": "15/01/1990",
    "address": {}
  }
}
CampoDescrição
eventNome do evento que gerou o aviso (tabela acima).
transaction_idA transação atualizada. Localize o seu pedido por ele.
statusStatus da transação no momento do envio.
total_value, fee, net_valueValor, taxa e líquido em reais.
payment_methodEm maiúsculas: PIX.
product, producernull nas cobranças da API; preenchidos nas vendas de produto do checkout da Aruba.
payment_dataO mesmo objeto da consulta de status.
customerComprador: name, email, document, phone, birth_date e address (com as chaves cep, street, number, complement, neighborhood, city e state; vazio se não foi enviado).

Entrega e retentativas

  • Responda com HTTP 2xx. Qualquer outro status, ou erro de rede, conta como falha.
  • São até 3 tentativas no total, com 15 segundos entre elas. Depois da terceira falha, aquele aviso não é reenviado: recupere o estado pela consulta de status.
  • Responda rápido: grave o aviso, devolva 200 e processe em segundo plano.
  • A ordem de chegada não é garantida. Por isso, confirme o status atual na consulta antes de agir.

Segurança

A Aruba não assina o corpo do aviso. Proteja o seu endpoint com a autenticação do cadastro (Basic Auth ou Bearer Token), que é enviada no header Authorization a cada disparo, e confirme sempre o status na consulta.

Confirme sempre na consulta

Trate o corpo do webhook como um aviso, não como prova de pagamento. Antes de liberar o pedido, confirme com GET /api/v1/payments/{transaction_id}/status. Use HTTPS e confira o header Authorization ao receber.

Idempotência

  • O mesmo aviso pode chegar mais de uma vez (retentativas e atualizações repetidas). Liberar o pedido duas vezes precisa ser impossível.
  • Uma transação aprovada pode mudar depois para REFUNDED, CHARGEBACK ou IN_DISPUTE. Não descarte um aviso só porque já viu aquele transaction_id: deduplique por transaction_id + status.
  • Torne a liberação atômica: marque o pedido como pago numa atualização condicional (por exemplo, UPDATE … WHERE status <> 'pago') e entregue só se a atualização mudou uma linha.

Exemplo de receptor

No cadastro do webhook, escolha Bearer Token e informe o valor de ARUBA_WEBHOOK_TOKEN.

import express from "express";

const app = express();
app.use(express.json());

const API = "https://api.arubabr.com/api/v1";

app.post("/webhooks/aruba", async (req, res) => {
  if (req.get("authorization") !== `Bearer ${process.env.ARUBA_WEBHOOK_TOKEN}`) return res.sendStatus(401);
  res.sendStatus(200); // responda logo; processe em seguida

  const transactionId = req.body?.transaction_id;
  if (!transactionId) return;

  const pedido = await db.pedidos.porTransacao(transactionId);
  if (!pedido) return; // transação que não é desta integração

  // Confirma o status na fonte antes de agir
  const r = await fetch(`${API}/payments/${transactionId}/status`);
  if (!r.ok) return;
  const { data } = await r.json();

  if (data.status === "AUTHORIZED") {
    const mudou = await db.pedidos.marcarPagoSeAindaNao(pedido.id); // UPDATE condicional
    if (mudou) await liberarPedido(pedido);
  } else if (["REFUNDED", "CHARGEBACK"].includes(data.status)) {
    await revogarPedido(pedido);
  }
});

app.listen(3000);
<?php
// Bearer Token cadastrado no webhook = ARUBA_WEBHOOK_TOKEN
// Em alguns servidores o header precisa ser repassado ao PHP (ex.: Apache com CGI).
$auth = $_SERVER["HTTP_AUTHORIZATION"] ?? "";
if (!hash_equals("Bearer " . getenv("ARUBA_WEBHOOK_TOKEN"), $auth)) {
  http_response_code(401);
  exit;
}

$aviso = json_decode(file_get_contents("php://input"), true);
http_response_code(200);
$transactionId = $aviso["transaction_id"] ?? null;
if (!$transactionId) exit;

// Confirma o status na fonte antes de agir
$ch = curl_init("https://api.arubabr.com/api/v1/payments/" . urlencode($transactionId) . "/status");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$status = json_decode(curl_exec($ch), true)["data"]["status"] ?? null;
curl_close($ch);

if ($status === "AUTHORIZED") {
  // UPDATE pedidos SET status = 'pago' WHERE transaction_id = ? AND status <> 'pago'
  // Se mudou 1 linha, libere o pedido.
}

Depois do pagamento

Status da transação

O campo status da consulta e do webhook diz em que ponto a transação está. A venda está paga só com AUTHORIZED.

Ciclo de vida

PENDING→AUTHORIZED→REFUNDED·CHARGEBACK·IN_DISPUTE PENDING→REJECTED·CANCELED

Tabela de status

StatusSignificadoO que fazerWebhook
PENDINGCobrança criada, aguardando o pagamento.Mostrar os dados de pagamento e aguardar.sim
AUTHORIZEDPago.Liberar o pedido, uma única vez.sim
REJECTEDRecusado.Oferecer uma nova tentativa (nova cobrança).sim
CANCELEDCancelado.Encerrar o pedido ou gerar nova cobrança.sim
REFUNDEDValor devolvido ao comprador.Revogar acesso ou entrega.sim
CHARGEBACKPagamento contestado pelo comprador.Revogar acesso ou entrega.sim
IN_DISPUTEDisputa aberta, em análise.Suspender a entrega e acompanhar.sim
FAILEDO processador não gerou a cobrança.A criação já respondeu erro; corrija e tente de novo.não
DISPUTE_ACCEPTEDDisputa encerrada com devolução ao comprador.Revogar acesso ou entrega.não
DISPUTE_REJECTEDDisputa encerrada a favor da venda.A venda segue válida.não

Os status sem webhook só aparecem na consulta de status e no painel.

Não existe status de expiração

Uma cobrança vencida e não paga pode continuar PENDING ou passar para REJECTED ou CANCELED, conforme o processador. Controle o prazo do pedido do seu lado.

AUTHORIZED pode mudar

Depois de pago, um pedido ainda pode virar REFUNDED, CHARGEBACK ou IN_DISPUTE. Mantenha o webhook tratando esses status mesmo para pedidos já entregues.

Referência

Erros

Erros respondem com hasError: true, o código HTTP em statusCode e a mensagem em error. Erros de validação listam cada problema em errorFields.

Formato

{
  "hasError": true,
  "error": "Erro na validação dos campos",
  "errorFields": [
    "amount must not be less than 1",
    "customer.email must be an email"
  ],
  "statusCode": 400,
  "timestamp": "2026-10-23T15:19:00.782Z",
  "path": "/api/v1/direct-payments"
}
CampoDescrição
hasErrorSempre true em erro.
errorMensagem principal. Nos erros de validação, é Erro na validação dos campos.
errorFieldsLista de problemas de validação, cada um citando o campo (ex.: customer.email). Vazia nos demais erros. As mensagens padrão de validação vêm em inglês.
statusCodeO mesmo código HTTP da resposta.
timestamp, pathMomento (ISO 8601, UTC) e caminho da requisição. Úteis ao falar com o suporte.

Códigos HTTP

HTTPQuando
200Consulta de status com sucesso.
201Cobrança criada.
400Dados inválidos ou regra de negócio: validação, documento, recusa do processador. Também quando a transação consultada não existe.
401API Key ausente, inválida ou pausada, ou conta bloqueada.
404Rota inexistente. Confira o método HTTP e o caminho.
429Muitas requisições em pouco tempo. Espere alguns segundos e tente de novo.
500Erro inesperado. Tente de novo; se persistir, fale com o suporte informando timestamp e path.

Mensagens comuns

Autenticação · 401

Header X-API-Key ausente, chave inválida ou inativa, ou conta bloqueada. As mensagens estão em Autenticação.

Validação · 400, em errorFields

MensagemCausa
property currency should not existCampo desconhecido no corpo (aqui, currency).
amount must not be less than 1amount abaixo do mínimo.
customer.email must be an emailE-mail em formato inválido.
document deve ser um CPF/CNPJ válido (somente números)…O documento do comprador não é um CPF ou CNPJ válido.
A data de nascimento deve ser válida e estar no formato DD/MM/YYYYbirthDate fora do formato.

Regras de negócio · 400, em error

MensagemCausa
document é obrigatório para este método de pagamentoPIX sem CPF/CNPJ.
document deve ser um CPF ou CNPJ válido (somente números)PIX com documento inválido.
Você ainda não possui documentos validados para gerar pagamentosValidação de documentos da conta pendente.
Mensagem variávelO processador não gerou a cobrança PIX. A transação fica FAILED.
Pedido não encontrado!Consulta de status com transaction_id inexistente.

Como tratar

  • 400 de validação ou regra: corrija a requisição. Repetir igual dá o mesmo erro.
  • Recusa do processador: pode tentar de novo, manualmente. Cada tentativa cria uma nova transação.
  • 429, 500 e timeouts: espere e tente de novo com intervalo crescente. Antes de recriar uma cobrança, confira no painel se a anterior não foi criada.

Referência

Valores e limites

Unidades de valor, mínimo, formatos de dados e limites da conta.

Unidades de valor

OndeUnidadeExemplo
amount na criaçãoInteiro, em centavos de real9990 = R$ 99,90
total_value na resposta da criaçãoDecimal, em reais99.9
total_value, fee, net_value na consulta e no webhookDecimal, em reais99.9

Valor mínimo

MétodoMínimo de amountEquivale a
pix1R$ 0,01 (limite da validação da API)

Tamanho dos campos

CampoLimite
description3 a 255 caracteres
customer.name3 a 128 caracteres
customer.utm.*até 128 caracteres; src até 2048 e sck até 256
customer.address.*veja Criar cobrança

Formatos

DadoFormatoExemplo
CPF / CNPJSó números, 11 ou 14 dígitos, dígitos verificadores válidos12345678909
TelefoneE.164+5511999999999
Data de nascimentoDD/MM/AAAA15/01/1990
CEP8 dígitos, sem hífen01310100
Datas nas respostasISO 8601, UTC2026-10-23T15:19:00.782Z

Limites da conta

  • API Keys: até 10 ativas por conta.
  • Webhooks: o painel aceita até 10 URLs.
  • Requisições: até 100 chamadas a cada 10 segundos por endereço IP. Acima disso a API responde 429. Faça polling a cada 5 a 15 segundos, nunca em laço contínuo.

Referência

Checklist de produção

Confira estes pontos antes de colocar a integração no ar.

Geral

  • A API Key fica só no servidor, em variável de ambiente ou cofre de segredos. Nunca no front nem no repositório.
  • amount é inteiro, em centavos de real.
  • O transaction_id é salvo no pedido logo após a criação.
  • A criação não é repetida automaticamente em erro ou timeout.
  • O webhook está cadastrado com HTTPS, com os eventos de pagamento e de devolução marcados, e responde 2xx rápido.
  • Antes de liberar o pedido, o servidor confirma AUTHORIZED na consulta de status, e a liberação é idempotente.
  • REFUNDED, CHARGEBACK e IN_DISPUTE são tratados também em pedidos já entregues.

PIX

  • Copia-e-cola com botão de copiar e QR Code gerado de pix_key.
  • O prazo do pedido é controlado do seu lado; depois dele, uma nova cobrança é gerada.
  • O polling no navegador (se houver) respeita o intervalo de 5 a 15 segundos e tem limite de tempo.

Referência

Para IA (llms.txt)

Esta documentação também existe em Markdown, para assistentes de código (Claude, ChatGPT, Cursor, Copilot…) implementarem a integração com as mesmas regras que você leu aqui.

Arquivos

ArquivoConteúdoQuando usar
/llms-full.txtA documentação inteira num arquivo só, em Markdown, com as regras para assistentes no início.Para colar no chat ou passar a URL ao assistente. É o recomendado.
/llms.txtÍndice no padrão llmstxt.org, com um link por página.Para ferramentas que leem llms.txt e buscam só as páginas necessárias.
/llms/<página>.mdCada página desta documentação em Markdown (ex.: /llms/webhooks.md).Para dar ao assistente só o trecho de um assunto.

Prompt sugerido

Leia https://docs.arubabr.com/llms-full.txt inteiro antes de escrever código.
Implemente a integração de pagamentos da Aruba no meu projeto seguindo essa documentação:
- criação da cobrança PIX no servidor com a API Key em variável de ambiente;
- tela de pagamento com o copia-e-cola e o QR Code gerado a partir de pix_key;
- webhook + consulta de status para liberar o pedido só com AUTHORIZED, de forma idempotente.
Respeite todas as regras da seção "Regras para assistentes de código".
Mesmo conteúdo do site

Os arquivos são gerados a partir desta página. Se algo mudar aqui, eles mudam junto.