1 Visão geral
Uma única API cobre os dois sentidos do fluxo e a custódia entre eles. Todos os valores em reais trafegam em centavos (amount_cents); quantidades de cripto são strings decimais.
📥 Cash-in
O cliente paga por PIX e você entrega USDT/USDC on-chain — ou mantém o valor como saldo em reais na custódia para decidir a saída depois.
📤 Cash-out
Recebe cripto de uma carteira externa e liquida em PIX, com cotação de validade explícita e endereço de depósito por operação.
🏦 Custódia BRL
Receba PIX e guarde como saldo real, organizado por subconta (cliente). Escolha a saída — PIX ou cripto — quando quiser.
⚡ Payouts
Envie PIX direto a partir do saldo, via API, sem passar por cripto. Ideal para repasses e saques dos seus clientes.
/catalog, /cashin/limits e /keys/me em vez de assumir valores fixos. Cotações são devolvidas antes de cada operação, já com a taxa aplicada.2 Autenticação
Toda requisição autenticada envia a sua chave no header X-API-Key. Requisições com corpo usam Content-Type: application/json.
curl --fail-with-body https://api.luniumpay.com/keys/me \
-H "X-API-Key: $LUNIUM_API_KEY"
.env commitado. Na WantsPay ela fica em variável de ambiente e o navegador nunca fala direto com a API — passa sempre pelos route handlers do servidor.Verificar a chave e o saldo
/keys/melimites, taxas e config/saldosaldo da conta3 Ambientes & chaves
Existe um ambiente de sandbox (determinístico, sem dinheiro real) e o de produção. Distinga-os pelo prefixo da chave e mantenha-os totalmente separados.
| Ambiente | Como obter a chave | Prefixo |
|---|---|---|
| Sandbox | POST /keys/sandbox — sem e-mail obrigatório | lun_test_… |
| Produção | POST /keys — com e-mail de operação | lun_live_… |
Criar chave de sandbox
curl --fail-with-body https://api.luniumpay.com/keys/sandbox \
-H 'Content-Type: application/json' \
-d '{"name":"Minha integração de teste"}'
Criar chave de produção
curl --fail-with-body https://api.luniumpay.com/keys \
-H 'Content-Type: application/json' \
-d '{"name":"Integração de produção","email":"operacao@wantspay.pro"}'
A resposta traz api_key, limits e uma monitor_url (painel privado de acompanhamento operacional). Guarde a api_key como LUNIUM_API_KEY no ambiente do servidor.
4 Comece agora
Do zero à primeira cobrança em quatro passos.
Gere a chave de sandbox
Uma chamada a POST /keys/sandbox devolve uma chave lun_test_…. Exporte como LUNIUM_API_KEY.
Confira chave e saldo
GET /keys/me e GET /saldo validam a autenticação e mostram limites e taxas vigentes.
Crie uma cobrança PIX de teste
POST /cashin/charge gera o QR (copia-e-cola + imagem). Em sandbox você simula o pagamento.
Acompanhe até liquidar
GET /cashin/{id}/status — ou receba o webhook. Crédito confirmado quando status=paid e settlement_status=sent.
curl --fail-with-body https://api.luniumpay.com/cashin/charge \
-H "X-API-Key: $LUNIUM_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"amount_cents": 5000,
"payer_tax_number": "00000000191",
"destino": "saldo",
"customer_ref": "cliente-42",
"external_id": "deposito-cliente42-001"
}'
POST /sandbox/cashin/{id}/pay para simular o pagamento do PIX e ver o ciclo completo sem transferir dinheiro real.5 Cash-in · PIX → cripto / custódia
Uma única cobrança (POST /cashin/charge) atende dois destinos, controlados pelo campo destino:
💰 destino: "saldo"
O PIX vira saldo em reais na custódia (opcionalmente numa subconta via customer_ref). A saída fica para depois.
🪙 destino: "cripto"
Entrega imediata de USDT/USDC no endereço informado. Requer asset, chain e payout_address.
/cashin/chargecria a cobrança PIX{
"amount_cents": 10000,
"payer_tax_number": "00000000191",
"destino": "cripto",
"asset": "usdt",
"chain": "polygon",
"payout_address": "0x1111111111111111111111111111111111111111",
"external_id": "compra-cripto-001",
"allow_hold": false
}
A resposta traz cashin_id, qr_copypaste, qr_image_url e expires_at. Gerar o QR confirma a criação — não o recebimento.
Acompanhar o status
/cashin/{cashin_id}/statusestado da cobrança| Campo | Valores |
|---|---|
status | pending delayed under_review paid expired refunded failed |
settlement_status | pending sending entregando sent incerto failed |
status = paid E settlement_status = sent. Um paid com liquidação sending/incerto ainda não está entregue — não mostre "entregue" ao cliente nem reenvie a operação.Antes de cobrar, você pode estimar com POST /cashin/preview e checar o teto do pagador com GET /cashin/limits?payer_tax=CPF. Redes e ativos disponíveis para entrega vêm de GET /cashin/catalog (campo entregavel: true).
6 Cash-out · cripto → PIX
Quando alguém envia cripto de uma carteira externa e você precisa pagar em PIX, o fluxo tem três passos: cotar, aceitar (recebe o endereço de depósito) e acompanhar.
Cotar — POST /cash-outs
Informe asset, network, a chave PIX de destino e um entre amount (cripto) ou brl_amount. Recebe cashout_id, deposit_address e a validade.
Aceitar — POST /cash-outs/{id}/accept
Confirma os termos e devolve o endereço/estado atualizados para o depósito.
Acompanhar — GET /cash-outs/{id}
Ao concluir, a resposta traz pix_e2e, pix_paid_at e receipt_url.
{
"asset": "USDT",
"network": "polygon",
"amount": "10.00",
"pix_key": "recebedor@example.com",
"pix_key_type": "email",
"external_id": "cashout-001"
}
Ciclo de estados
Estados terminais: COMPLETED, MANUAL_REVIEW, REFUNDING_CRYPTO, REFUNDED, EXPIRED, FAILED. Estimativa sem criar ordem: POST /cash-outs/preview.
7 Custódia & saldo
O saldo em reais fica organizado por subconta (customer_ref) sobre a "casa". Consulte, extraia, transfira entre subcontas e saque como cripto.
/saldocasa ou ?customer_ref=/saldo/consolidadocasa + subcontas/saldo/extratolançamentos/saldo/transferirentre subcontas/saldo/sacar-criptosaque em USDT/USDC/saldo/clientessaldos por clientetotal_cents, disponivel_cents (sacável, após retenções) e bloqueado_cents/held. Respeite carencia_horas/carencia_ate — mostre ao cliente a data prevista de liberação em vez de tratar como erro.Sacar saldo como cripto
{
"amount_cents": 10000,
"asset": "usdt",
"chain": "polygon",
"payout_address": "0x1111111111111111111111111111111111111111",
"tax_number": "00000000191",
"customer_ref": "cliente-42",
"external_id": "saque-cripto-cliente42-001"
}
amount_cents é o valor em reais a debitar, não a quantidade de cripto. Para redes que exigem memo, envie payout_tag. Use max_debited_cents para limitar o débito total (com taxas). Acompanhe por GET /cashin/{id}/status.
8 Payouts · PIX via API
Envie PIX direto a partir do saldo em custódia — sem intermediar cripto. Requer payout.enabled na chave e saldo suficiente (valor + taxas).
/payoutsenvia o PIX/payouts/{payout_id}acompanha{
"amount_cents": 5000,
"pix_key": "recebedor@example.com",
"pix_key_type": "email",
"tax_number": "00000000191",
"customer_ref": "cliente-42",
"external_id": "saque-pix-cliente42-001"
}
Estados: processing → sent / failed / refunded. Quando disponível, o comprovante traz e2e, paid_at, receiver_name e verify_url. As taxas estimadas saem de GET /saldo (saque_taxa_estimada_cents).
9 Catálogo, limites & cotações
Nunca fixe redes, mínimos ou taxas no código — leia-os por API antes de cada operação.
| Endpoint | Para quê |
|---|---|
GET /cashin/catalog | Ativos/redes entregáveis no cash-in (entregavel, instant, min_brl_cents, memoRequired). |
GET /catalog | Ativos e redes para receber cripto, com mínimos/máximos e taxas. Tokens DEX em /catalog/dex. |
GET /cashin/limits | Limite do pagador: faixa_instantanea_cents, utilizacao_cents, min_brl_cents. |
POST /cashin/preview | Estimativa não-vinculante: fee_cents, usdt_amount, eta. |
POST /cash-outs/preview | Cotação de cripto → PIX por amount ou brl_amount. |
10 Comissão (partner fee)
Você pode embutir uma comissão própria sobre cada operação, definida em basis points (partner_fee_bps; 200 = 2%). Ela é calculada sobre a base após a taxa fixa e creditada num saldo de comissão separado.
{ "partner_fee_bps": 200 } // 2%
/comissao/comissao/extrato/comissao/sacarA comissão é apurada após status=paid e settlement_status=sent. Consulte disponivel_cents, min_saque_cents e pode_sacar_agora antes de sacar. Fórmula: floor(base_cents × (10000 − lunium_bps − partner_bps) / 10000).
11 Webhooks
Configure a URL de recepção em PATCH /keys/me. A resposta devolve o webhook_secret uma única vez — guarde com segurança.
{ "webhook_url": "https://wantspay.pro/api/webhook" }
Assinatura (HMAC-SHA256)
Cada entrega traz o header X-Lunium-Signature: t=1700000000,v1=<hmac_hex>. Valide o HMAC-SHA256 de timestamp.raw_body — capture o corpo bruto antes de fazer o parse do JSON.
const crypto = require('crypto');
function verify(header, rawBody, secret) {
const [, sigPart] = header.split(','); // "v1=..."
const t = header.split(',')[0].split('=')[1];
const v1 = sigPart.split('=')[1];
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(v1), Buffer.from(expected) // comparação em tempo constante
);
}
Outros headers: X-Lunium-Event-Id (dedupe por ele), X-Lunium-Delivery-Id e X-Lunium-Attempt (até 12 tentativas em ~7h).
Formato do evento
{
"event": "cashin.settled",
"event_id": "evt_exemplo",
"created_at": "2026-09-17T20:00:00.000Z",
"data": {
"cashin_id": "ci_exemplo",
"destino": "saldo",
"status": "paid",
"settlement_status": "sent"
}
}
| Grupo | Eventos |
|---|---|
cashin | paid · settled · settlement_failed · expired · refunded · failed · delayed · held |
cashout | awaiting_deposit · deposit_detected · processing · confirming · under_review · refunding · completed · refunded · expired · failed |
payout | sent · failed · refunded |
saldo | liberado · congelado · transferido |
webhook | test |
event_id com restrição de unicidade (dedupe); responda 2xx em até 10s e faça o trabalho pesado de forma assíncrona; releia o estado canônico com um GET no recurso antes de atualizar a UI. Recupere entregas falhas em GET /webhooks/deliveries e reenvie com POST /webhooks/deliveries/{event_id}/retry. Dispare um teste com POST /webhooks/test.12 Idempotência & erros
Envie external_id em toda operação financeira (cash-in, cash-out, payout, transferência). Em retry, reutilize o mesmo external_id com o corpo idêntico.
external_id no endpoint de listagem (/cashin/charges, /cash-outs, /payouts). Se existir, acompanhe; se não, repita com o mesmo corpo/ID respeitando backoff.Códigos de erro
| HTTP | Campo | Significado | Ação |
|---|---|---|---|
401/403 | — | Autenticação / permissão da chave | Verifique a chave, limites e política |
402 | saldo_insuficiente | Saldo insuficiente | Cheque disponível, subconta e taxas |
409 | external_id_divergente | ID já usado com parâmetros diferentes | Não repita com o mesmo ID |
423 | carencia_primeiro_deposito | Trava de carência | Mostre o liberar_em retornado |
429 | — | Rate limit | Respeite o header Retry-After |
5xx | — | Erro de servidor / timeout | Consulte a operação antes de repetir |
O corpo de erro inclui erro, acao, detail, request_id e agent_guidance. Ao pedir suporte, informe ambiente, id da operação, external_id, horário com fuso e request_id — nunca a chave, o segredo do webhook ou o CPF/CNPJ completo.
13 Referência de endpoints
Resumo das rotas mais usadas. Base: https://api.luniumpay.com.
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /cashin/charge | Cria cobrança PIX (custódia ou cripto) |
| GET | /cashin/{id}/status | Estado da cobrança |
| POST | /cashin/preview | Estimativa de cash-in |
| GET | /cashin/catalog | Ativos/redes entregáveis |
| GET | /cashin/limits | Limites do pagador |
| POST | /cash-outs | Cota cripto → PIX (passo 1) |
| POST | /cash-outs/{id}/accept | Aceita e recebe endereço (passo 2) |
| GET | /cash-outs/{id} | Acompanha (passo 3) |
| POST | /cash-outs/preview | Cotação sem criar ordem |
| POST | /payouts | Envia PIX do saldo |
| GET | /payouts/{id} | Acompanha o payout |
| GET | /saldo | Saldo (casa ou subconta) |
| GET | /saldo/extrato | Lançamentos |
| POST | /saldo/transferir | Transferência interna |
| POST | /saldo/sacar-cripto | Saque do saldo em cripto |
| GET | /keys/me | Config, limites e taxas da chave |
| PATCH | /keys/me | Webhook, comissão etc. |
| GET | /comissao | Saldo de comissão |
| POST | /comissao/sacar | Saca a comissão em cripto |
| POST | /webhooks/test | Dispara webhook de teste |
| GET | /webhooks/deliveries | Log de entregas |
| GET | /ping | Health check |
14 Suporte
🟢 Status
luniumpay.com/status — disponibilidade da infraestrutura.
✉️ WantsPay
suporte@wantspay.pro — integração e dúvidas comerciais.
📘 Especificação
OpenAPI 3.1 em /openapi.json.
external_id; UI lendo catálogo/limites atuais e distinguindo PIX pago de cripto entregue; conciliação tratando carência, rota, taxa e erros de saldo sem duplicar operações.