On-ramp e off-ramp · Brasil
On-ramp e off-ramp no Brasil, em uma API
PIX é o meio de pagamento do país: instantâneo, 24 horas por dia, e todo mundo tem. O que falta a quem vem de fora não é demanda — é o encanamento. É isso que esta API é.
Para quem é
- Empresa estrangeira que quer vender, pagar ou receber no Brasil sem montar operação local do zero.
- Exchange, corretora ou broker que precisa de par BRL sem operar banco brasileiro.
- Produto global que já tem PIX na roadmap e não quer três fornecedores para uma coisa só.
O problema
Quem chega ao Brasil descobre a mesma sequência: PIX exige instituição autorizada, a conta exige empresa local, a empresa exige sócios e tempo, e a conversão para stablecoin exige uma corretora com o próprio KYC. São meses antes da primeira transação — e cada peça é um contrato, um limite e uma conciliação diferentes.
A alternativa é tratar o Brasil como um trilho e não como uma filial: você fala com uma API, o dinheiro entra e sai em reais, e o seu saldo continua em stablecoin. Quem já opera assim integrou lendo a documentação, sem reunião.
O fluxo, ponta a ponta
- Entrada:
POST /cashin/chargecria um QR PIX identificado pelo CPF/CNPJ de quem vai pagar. Pago o PIX, a stablecoin sai para a sua carteira. - Saída:
POST /cash-outscota,/accepttrava e devolve o endereço; você deposita e uma chave PIX recebe reais. - Custódia (opcional): com
destino: "saldo"o PIX vira saldo em reais por subconta, e você paga comPOST /payoutsquando quiser. - Os dois sentidos usam a mesma chave, o mesmo formato de erro (
erro+acao) e o mesmoexternal_id. - Todo evento chega assinado por webhook; nada exige polling.
Endpoints usados
| Endpoint | Para quê |
|---|---|
POST /cashin/charge | Entrada: cria o QR PIX e entrega stablecoin. |
POST /cash-outs + /accept | Saída: cota, trava e recebe o endereço de depósito. |
POST /payouts | PIX direto em reais a partir do saldo custodial, sem perna cripto. |
GET /keys/me | Seus limites vigentes, tier e o que está liberado. Leia daqui, não do código. |
GET /v1/verificar/{e2e} | Verificação pública de um PIX liquidado. Sem chave. |
Exemplo que roda
# entrada: PIX vira stablecoin na sua carteira
curl -X POST https://api.luniumpay.com/cashin/charge -H "X-API-Key: $LUNIUM_KEY" \
-H "Content-Type: application/json" \
-d '{"amount_cents":100000,"asset":"usdc","chain":"polygon",
"payout_address":"0xTesouraria","payer_tax_number":"12345678909",
"external_id":"in-9001"}'
# saída: stablecoin vira PIX na conta de alguém
curl -X POST https://api.luniumpay.com/cash-outs -H "X-API-Key: $LUNIUM_KEY" \
-H "Content-Type: application/json" \
-d '{"asset":"USDC","network":"polygon","brl_amount":"1000.00",
"pix_key":"11122233344","pix_key_type":"cpf","external_id":"out-9001"}'const h = { "X-API-Key": process.env.LUNIUM_KEY, "Content-Type": "application/json" };
export const entrada = (cents, carteira, docPagador, id) =>
fetch(`${API}/cashin/charge`, { method: "POST", headers: h, body: JSON.stringify({
amount_cents: cents, asset: "usdc", chain: "polygon",
payout_address: carteira, payer_tax_number: docPagador, external_id: id,
})}).then((r) => r.json());
export const saida = (brl, chave, tipo, id) =>
fetch(`${API}/cash-outs`, { method: "POST", headers: h, body: JSON.stringify({
asset: "USDC", network: "polygon", brl_amount: brl,
pix_key: chave, pix_key_type: tipo, external_id: id,
})}).then((r) => r.json());import os, requests
API, H = "https://api.luniumpay.com", {"X-API-Key": os.environ["LUNIUM_KEY"]}
def entrada(cents, carteira, doc_pagador, ident):
return requests.post(f"{API}/cashin/charge", headers=H, timeout=30, json={
"amount_cents": cents, "asset": "usdc", "chain": "polygon",
"payout_address": carteira, "payer_tax_number": doc_pagador,
"external_id": ident}).json()
def saida(brl, chave, tipo, ident):
return requests.post(f"{API}/cash-outs", headers=H, timeout=30, json={
"asset": "USDC", "network": "polygon", "brl_amount": brl,
"pix_key": chave, "pix_key_type": tipo, "external_id": ident}).json()Sandbox: teste antes de gastar
Uma chamada, sem cadastro, sem cartão. A chave lun_test_ exercita a superfície inteira
sem mover dinheiro nenhum.
curl -X POST https://api.luniumpay.com/keys/sandbox \
-H "Content-Type: application/json" \
-d '{"name":"meu-teste"}'
O que o sandbox não prova: liquidação real. Nenhuma cripto se move e nenhum PIX é pago — ele serve para acertar o contrato, não para medir o trilho.
Ativos e redes
Instantâneo (trilho próprio): USDT na Polygon e USDC na Polygon — liquidação em segundos, sem corretora no caminho.
Via corretora: 1.478 ativos em 241 redes na venda (1.668 pares ativo×rede) e 1.795 rotas na compra. O prazo é o número de confirmações que a rede exige, não uma escolha nossa.
Redes de endereço compartilhado (ALGO, ATOM, EOS, HBAR, KAVA, LUNA, TON, XLM, XRP): o depósito precisa levar o memo. Na venda ele vem
em deposit_tag no aceite; na compra você manda payout_tag junto do endereço.
O catálogo muda sozinho conforme redes entram e saem. Leia de GET /catalog e GET /cashin/catalog em vez de manter lista no código.
Limites e retenções
| O quê | Valor |
|---|---|
| Compra (cash-in) e saque PIX, por operação | R$ 1,00 a R$ 6.000,00 |
| Venda (cash-out), por operação | a partir de R$ 6,00 |
| Validade do QR | 15 minutos |
| Escada por pagador (CPF/CNPJ de quem paga) | R$ 60,00 na estreia → R$ 200,00 nas primeiras 24 h → R$ 6.000,00/dia |
| Acima da escada | o QR ainda é aceito e o provedor retém 24 h (D+1), até R$ 6.000,00/dia por pagador |
A escada é por documento de quem paga, não por conta que recebe: dez pagadores são dez limites
independentes. É isso que faz o produto servir a e-commerce e marketplace. Consulte o disponível de um
pagador antes de cobrar em GET /cashin/limits?payer_tax=, e leia os limites da sua chave em
GET /keys/me — tetos acima do tier são contratados.
Medições, não promessas
Medido em produção, janela de 90 dias, em 07/09/2026:
| Trecho | Mediana | p90 | Amostra |
|---|---|---|---|
| PIX recebido → stablecoin entregue (Polygon) | 6 s | 70 s | 112 operações |
| Aceite da cotação → PIX pago (Polygon) | 81 s | 580 s | 27 operações |
Fora da Polygon o relógio é o da rede: o prazo é o número de confirmações que a corretora
exige, e está em eta no catálogo. Não prometemos “instantâneo” fora do trilho próprio.
Idempotência
Mande external_id em toda operação que move dinheiro. Repetir a mesma chamada devolve a
mesma operação, nunca uma segunda; os mesmos parâmetros com id diferente criam duas, e o mesmo id
com parâmetros diferentes responde 409 external_id_divergente em vez de adivinhar.
Timeout não é recusa. Se a chamada não respondeu, consulte pelo external_id
antes de repetir — a operação pode existir.
Webhooks e reconciliação
Cada transição dispara um evento assinado em HMAC SHA-256 com timestamp (header
X-Lunium-Signature, formato t=…,v1=…) — o timestamp é o que impede replay de uma
entrega capturada. Confira a assinatura antes de confiar no corpo.
Webhook é o sinal principal; polling é opcional. Quando precisar pesquisar, o status traz a
timeline carimbada pelo servidor — desenhe a etapa a partir dela, porque o cronômetro do
seu polling mede a sua rede, não a operação.
Não respondeu 2xx? A entrega é retentada com backoff. Você reenvia à mão em
POST /webhooks/deliveries/{event_id}/retry e testa a sua URL em POST /webhooks/test.
Quando dá errado
Cada erro traz erro (o que houve) e acao (o que fazer): corrigir,
repetir, esperar ou parar. É o campo que um agente ou um retry automático
consegue seguir sem heurística.
parar é o mais importante: em provedor_sem_resposta num saque, o PIX pode ter saído.
Consulte a operação, não repita.
Segurança
- webhook assinado — Todo webhook vai assinado em HMAC SHA-256 com timestamp (header X-Lunium-Signature, formato t=…,v1=…), o que impede replay de uma entrega capturada.
- idempotencia — external_id em cash-in, cash-out e payout: repetir a mesma chamada devolve a MESMA operação, nunca uma segunda. Parâmetros diferentes no mesmo external_id respondem 409.
- egress validado — A URL de webhook é resolvida e validada antes de cada entrega: endereço interno, metadata de nuvem e redirect para rede privada são recusados, e a conexão é fixada no IP validado.
- retencao fail closed — A retenção é verificada na liquidação e repetida na reivindicação SQL: nenhum caminho (worker, consulta de status, fila) consegue liquidar antes da hora.
- payout duravel — O saque grava a operação e debita o saldo na MESMA transação, antes de qualquer chamada ao provedor: não existe débito sem ordem para reconciliar.
- verificacao aberta — GET /v1/verificar/{e2e} confere um PIX liquidado sem chave nenhuma — a contraparte não precisa confiar na nossa palavra.
A verificação aberta é a que mais importa numa negociação: a sua contraparte confere o PIX sozinha, sem chave e sem depender da nossa palavra.
Tempo até a primeira integração
Sandbox em uma chamada, sem cadastro. O contrato do sandbox é idêntico ao de produção — os mesmos campos, os mesmos estados e os mesmos erros — então o código que você escreveu testando é o que vai para o ar.
Perguntas que os integradores fazem
Preciso de empresa no Brasil?
Não para integrar nem para testar. O que existe é análise proporcional ao volume, como em qualquer trilho de pagamento.
Como funciona o limite para quem está começando?
A escada é por CPF/CNPJ de quem paga: R$ 60,00 na estreia, R$ 200,00 nas primeiras 24 h e R$ 6.000,00/dia depois. Acima disso o QR ainda é aceito, com retenção de 24 h. Como o limite é do pagador, muitos pagadores somam sem teto único.
Vocês seguram o meu dinheiro?
Só se você pedir. No fluxo padrão a stablecoin vai direto para a sua carteira e o PIX direto para a chave de destino. A custódia em reais é um produto à parte, com destino: "saldo".
Dá para usar por um agente de IA?
Sim: além do REST há MCP, um Agent Card e llms.txt. Todo erro traz orientação legível por máquina, e o verificador de PIX é aberto.
Contrato OpenAPI 1.25.0 · fatos desta página em product-truth.json · status