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 base | Ambiente | Uso |
|---|---|---|
https://api.ludopayments.com.br/v1 | Sandbox | Testes, sem dinheiro real. Use uma chave ak_test_. |
https://api.ludopayments.com.br/v1 | Produção | Dinheiro 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.
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 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.
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.
Criar cobrança
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
| Campo | Tipo | Descrição | |
|---|---|---|---|
amount_cents | integer | obrigatório | Valor em centavos, maior que zero. |
description | string | opcional | Até 300 caracteres. Aparece no seu painel, não no app do pagador. |
external_ref | string | opcional | Seu identificador para esta cobrança (até 120 caracteres). Devolvido inalterado nas consultas e no webhook. |
customer_email | string | opcional | E-mail do jogador, se você já o conhece. |
expires_in_seconds | integer | opcional | Entre 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.
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
}'
{
"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
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.
curl https://api.ludopayments.com.br/v1/business/pix-charges/pix_6k2wq1n0 \
-H "Authorization: Bearer ak_test_xxxx"
Listar cobranças
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.
curl "https://api.ludopayments.com.br/v1/business/pix-charges?status=paid" \
-H "Authorization: Bearer ak_test_xxxx"
Cancelar cobrança
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.
curl -X POST https://api.ludopayments.com.br/v1/business/pix-charges/pix_6k2wq1n0/cancel \
-H "Authorization: Bearer ak_test_xxxx"
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.
| Estado | Significado |
|---|---|
pending | Cobrança criada, aguardando pagamento. |
paid | Pagamento confirmado — estado terminal. |
expired | Passou 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. |
canceled | Cancelada por você antes do pagamento. |
PIX out Em breve
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.
Simular pagamento
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.
curl -X POST https://api.ludopayments.com.br/v1/business/pix-charges/pix_6k2wq1n0/pay \
-H "Authorization: Bearer ak_test_xxxx"
Saldo e extrato
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.
| Campo | Descrição |
|---|---|
available_cents | Saldo disponível, em centavos. |
reserve_cents | Valor retido em reserva de risco (se aplicável à sua conta). |
currency | Sempre "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. |
curl https://api.ludopayments.com.br/v1/business/finance \
-H "Authorization: Bearer ak_test_xxxx"
{
"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 }
]
}
]
}
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.
| Evento | Quando dispara |
|---|---|
business.pix.created | Cobrança criada. |
business.pix.paid | Pagamento confirmado — é este que credita a carteira do jogador. |
business.pix.canceled | Cobrança cancelada antes do pagamento. |
{
"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.
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);
}
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ção | Comportamento |
|---|---|
| Mesma chave, mesmo corpo | Devolve a resposta original, sem repetir o efeito. |
| Mesma chave, corpo diferente | 409 — provável reaproveitamento indevido da chave. |
| Sem cabeçalho | Cada 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" }
| Status | Significado |
|---|---|
401 | Chave de API ausente, inválida ou revogada. |
403 | Rota indisponível neste ambiente (ex.: simular pagamento em produção). |
404 | Recurso não encontrado ou pertence a outra conta. |
409 | Conflito de estado (ex.: cancelar cobrança já paga) ou Idempotency-Key reaproveitada com corpo diferente. |
422 | Corpo da requisição inválido — detail aponta o campo. |
Referência rápida
| Método | Rota | Descrição |
|---|---|---|
| POST | /v1/business/pix-charges | Criar cobrança |
| GET | /v1/business/pix-charges/:id | Consultar cobrança |
| GET | /v1/business/pix-charges | Listar cobranças |
| POST | /v1/business/pix-charges/:id/cancel | Cancelar cobrança |
| POST | /v1/business/pix-charges/:id/pay | Simular pagamento (sandbox) |
| GET | /v1/business/finance | Saldo e extrato |
| em breve | /v1/business/payouts | PIX out — ainda não disponível |