JogaLudo
sandbox ativo Autenticação
Documentação para parceiros · Cash-in PIX

Cobranças PIX para a carteira JogaLudo

Integração direta com a API da ARBOR: crie cobranças PIX dinâmicas, receba a confirmação e credite o saldo do jogador em tempo real. API REST simples, sem SDK obrigatório.

Guia de integração

Como funciona

Esta API cria cobranças PIX dinâmicas (QR code + copia-e-cola), confirma o pagamento e devolve o status em tempo real, para você creditar a carteira do jogador. Valores monetários são sempre números inteiros em centavos — R$ 10,00 é 1000.

Disponível agora: cobrança PIX (cash-in), consulta de saldo e extrato, e webhook de confirmação assinado. Em desenvolvimento: PIX out (saque) — veja Cash-out para o status atual.

URL baseAmbienteUso
https://api.ludopayments.com.br/v1SandboxTestes, sem dinheiro real. Use uma chave ak_test_.
https://api.ludopayments.com.br/v1ProduçãoDinheiro real. Use uma chave ak_live_.

Nota: sandbox e produção compartilham a mesma URL — o ambiente é determinado pelo prefixo da sua chave de API (ak_test_ ou ak_live_), não por um host diferente.

Primeiros passos

Autenticação

Toda requisição carrega sua chave de API no cabeçalho Authorization, como bearer token. Não existe OAuth, sessão ou SDK obrigatório — qualquer cliente HTTP funciona.

cURL
curl https://api.ludopayments.com.br/v1/business/pix-charges \
  -H "Authorization: Bearer ak_test_xxxxxxxxxxxx" \
  -H "Content-Type: application/json"

Guarde a chave com cuidado: ela é exibida uma única vez no momento da criação. A ARBOR armazena apenas o hash — se perdê-la, é preciso gerar uma nova.

Primeiros passos

Sandbox vs. produção

Chaves de sandbox e produção são independentes e não compartilham dados. No sandbox, toda cobrança pode ser confirmada manualmente pela rota de simulação — não é preciso pagar um PIX de verdade para testar sua integração ponta a ponta.

Cobranças PIX

Criar cobrança

POST/v1/business/pix-charges

Cria uma cobrança PIX dinâmica e devolve o código copia-e-cola. Gere o QR a partir do campo qr_code (payload EMV padrão do Banco Central) em qualquer biblioteca de QR do seu lado — a ARBOR não devolve uma imagem pronta.

Corpo da requisição

CampoTipoDescrição
amount_centsintegerobrigatórioValor em centavos, maior que zero.
descriptionstringopcionalAté 300 caracteres. Aparece no seu painel, não no app do pagador.
external_refstringopcionalSeu identificador para esta cobrança (até 120 caracteres). Devolvido inalterado nas consultas e no webhook.
customer_emailstringopcionalE-mail do jogador, se você já o conhece.
expires_in_secondsintegeropcionalEntre 60 e 86400. Padrão: 3600 (1 hora).

Reenvio seguro: use o cabeçalho Idempotency-Key nesta chamada — veja Idempotência. O campo external_ref é só um rótulo seu: reenviar a criação sem repetir a chave de idempotência gera uma nova cobrança, mesmo com o mesmo external_ref.

Requisição
curl -X POST https://api.ludopayments.com.br/v1/business/pix-charges \
  -H "Authorization: Bearer ak_test_xxxx" \
  -H "Idempotency-Key: joga_dep_9f21c3" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_cents": 5000,
    "description": "Depósito JogaLudo",
    "external_ref": "dep_9f21c3",
    "customer_email": "jogador@exemplo.com",
    "expires_in_seconds": 900
  }'
Resposta 200
{
  "id": "pix_6k2wq1n0",
  "status": "pending",
  "amount_cents": 5000,
  "description": "Depósito JogaLudo",
  "external_ref": "dep_9f21c3",
  "customer_email": "jogador@exemplo.com",
  "qr_code": "00020126580014BR.GOV.BCB.PIX...",
  "e2e_id": "or_Nq3f...charge_8a2",
  "provider": "pagarme",
  "expires_at": "2026-08-07T15:32:10Z",
  "created_at": "2026-08-07T15:17:10Z"
}

Consultar cobrança

GET/v1/business/pix-charges/:id

Devolve o estado atual da cobrança. Enquanto o webhook do seu ambiente estiver sendo finalizado (veja Recebendo o webhook), esta é a forma confiável de confirmar um pagamento — consulte logo após o jogador informar que pagou, ou em intervalos curtos até sair de pending.

Requisição
curl https://api.ludopayments.com.br/v1/business/pix-charges/pix_6k2wq1n0 \
  -H "Authorization: Bearer ak_test_xxxx"

Listar cobranças

GET/v1/business/pix-charges?status=paid

Lista as cobranças da sua conta, mais recentes primeiro (até 200 registros). O parâmetro status é opcional e filtra por um dos estados abaixo.

Requisição
curl "https://api.ludopayments.com.br/v1/business/pix-charges?status=paid" \
  -H "Authorization: Bearer ak_test_xxxx"

Cancelar cobrança

POST/v1/business/pix-charges/:id/cancel

Cancela uma cobrança que ainda não foi paga. Só funciona a partir do estado pending — cobranças já pagas, expiradas ou canceladas devolvem 409.

Requisição
curl -X POST https://api.ludopayments.com.br/v1/business/pix-charges/pix_6k2wq1n0/cancel \
  -H "Authorization: Bearer ak_test_xxxx"
Cobranças PIX

Estados de uma cobrança

Uma cobrança nasce em pending e se move para exatamente um destes destinos — transições são atômicas: duas confirmações concorrentes para a mesma cobrança nunca capturam o valor duas vezes.

pending paid · expired · canceled
EstadoSignificado
pendingCobrança criada, aguardando pagamento.
paidPagamento confirmado — estado terminal.
expiredPassou de expires_at sem pagamento. Detectado na primeira consulta ou tentativa de confirmação após o vencimento — se você depende de expiração para liberar um QR reutilizado, consulte a cobrança periodicamente em vez de assumir a mudança automática.
canceledCancelada por você antes do pagamento.
Cash-out

PIX out Em breve

Endpoint ainda não disponível — em desenvolvimento.

O saque PIX (pagar a chave PIX de um jogador a partir de uma solicitação aprovada no seu painel) está no roadmap da integração e ainda não tem uma rota pública. Quando estiver disponível, vai seguir os mesmos padrões já usados na cobrança: autenticação por API key, Idempotency-Key obrigatório, e webhook de status assinado (concluído / falhou) no mesmo formato descrito em Recebendo o webhook.

Assim que o endpoint for liberado, esta seção é atualizada com o contrato completo — campos, estados e exemplos. Se o cronograma do PIX out for um bloqueador pro seu piloto, fale com seu contato na ARBOR.

Sandbox

Simular pagamento

POST/v1/business/pix-charges/:id/pay

Disponível somente em sandbox — confirma a cobrança como se o PIX tivesse sido pago, disparando exatamente o mesmo fluxo (captura + webhook) que um pagamento real. Em produção esta rota devolve 403.

Requisição
curl -X POST https://api.ludopayments.com.br/v1/business/pix-charges/pix_6k2wq1n0/pay \
  -H "Authorization: Bearer ak_test_xxxx"
Conta

Saldo e extrato

GET/v1/business/finance

Devolve o saldo atual da sua conta e as últimas 50 movimentações do ledger, para conciliação com o seu extrato interno. Use available_cents como o saldo confiável — é o mesmo valor usado internamente para liberar operações.

CampoDescrição
available_centsSaldo disponível, em centavos.
reserve_centsValor retido em reserva de risco (se aplicável à sua conta).
currencySempre "BRL".
transactions[]Últimos lançamentos do ledger — cada um com event_type (ex.: payment.captured, settlement, refund.reversal), description, created_at e os entries (débito/crédito) que compõem o lançamento.
Requisição
curl https://api.ludopayments.com.br/v1/business/finance \
  -H "Authorization: Bearer ak_test_xxxx"
Resposta 200
{
  "merchant_id": "mch_8x2p...",
  "currency": "BRL",
  "available_cents": 184250,
  "reserve_cents": 0,
  "transactions": [
    {
      "id": "txn_a1c9...",
      "event_type": "payment.captured",
      "description": "Pix Depósito JogaLudo",
      "created_at": "2026-08-07T15:19:42Z",
      "entries": [
        { "account_code": "psp:pagarme:receivable", "direction": "debit", "amount_cents": 5000 },
        { "account_code": "merchant:mch_8x2p...:payable", "direction": "credit", "amount_cents": 4750 }
      ]
    }
  ]
}
Confirmações

Recebendo o webhook

Durante o piloto, a URL do seu endpoint é configurada diretamente com o nosso time de integração — fale com seu contato na ARBOR para registrá-la. Enquanto isso, use a consulta de cobrança para confirmar pagamentos.

Quando seu endpoint estiver ativo, cada mudança de estado gera um POST assinado para a sua URL, no formato abaixo. Responda 2xx rapidamente — o processamento pesado deve acontecer depois, de forma assíncrona do seu lado.

EventoQuando dispara
business.pix.createdCobrança criada.
business.pix.paidPagamento confirmado — é este que credita a carteira do jogador.
business.pix.canceledCobrança cancelada antes do pagamento.
Corpo do POST
{
  "id": "evt_a91fd8",
  "type": "business.pix.paid",
  "created_at": "2026-08-07T15:19:42Z",
  "data": {
    "amount_cents": 5000,
    "e2e_id": "or_Nq3f...charge_8a2",
    "external_ref": "dep_9f21c3"
  }
}

Reentrega: até 8 tentativas por evento, com backoff exponencial (dobra a cada tentativa, teto de 5 minutos) e timeout de 10s por chamada. Se todas as tentativas falharem, o evento fica retido para reenvio manual do nosso lado — fale com seu contato na ARBOR se perceber uma lacuna. Trate o mesmo id de evento chegando mais de uma vez como normal — credite a carteira do jogador de forma idempotente por external_ref ou e2e_id, nunca assumindo que cada entrega é única.

Verificando a assinatura

Todo POST chega com o cabeçalho X-Arbor-Signature, no formato t=<epoch>,v1=<hmac>. Recalcule o HMAC sobre {timestamp}.{corpo bruto} com o segredo do seu endpoint e compare em tempo constante — nunca com === direto.

Use o corpo bruto (raw): reserializar o JSON antes de assinar quase sempre muda a string de bytes e invalida a assinatura. Capture o corpo cru da requisição antes de fazer JSON.parse.

Node.js
const { createHmac, timingSafeEqual } = require("node:crypto");

function isValid(secret, rawBody, header, toleranceSec = 300) {
  const parts = new Map(
    header.split(",").map((p) => p.split("="))
  );
  const ts = Number(parts.get("t"));
  const v1 = parts.get("v1");
  if (Math.abs(Date.now() / 1000 - ts) > toleranceSec) return false;

  const expected = createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(v1 ?? "");
  return a.length === b.length && timingSafeEqual(a, b);
}
Referência

Idempotência

Envie um cabeçalho Idempotency-Key em requisições POST que possam ser reenviadas por retry de rede (recomendado sempre em criar cobrança). A regra:

SituaçãoComportamento
Mesma chave, mesmo corpoDevolve a resposta original, sem repetir o efeito.
Mesma chave, corpo diferente409 — provável reaproveitamento indevido da chave.
Sem cabeçalhoCada chamada cria um novo registro — use só quando a operação for naturalmente segura de repetir (ex.: GET).

Erros

Erros sempre respondem em JSON com um campo detail legível:

{ "detail": "cobrança não encontrada" }
StatusSignificado
401Chave de API ausente, inválida ou revogada.
403Rota indisponível neste ambiente (ex.: simular pagamento em produção).
404Recurso não encontrado ou pertence a outra conta.
409Conflito de estado (ex.: cancelar cobrança já paga) ou Idempotency-Key reaproveitada com corpo diferente.
422Corpo da requisição inválido — detail aponta o campo.

Referência rápida

MétodoRotaDescrição
POST/v1/business/pix-chargesCriar cobrança
GET/v1/business/pix-charges/:idConsultar cobrança
GET/v1/business/pix-chargesListar cobranças
POST/v1/business/pix-charges/:id/cancelCancelar cobrança
POST/v1/business/pix-charges/:id/paySimular pagamento (sandbox)
GET/v1/business/financeSaldo e extrato
em breve/v1/business/payoutsPIX out — ainda não disponível