BRL ↔ USDT · produção
BRL ↔ USDT por API
Os dois sentidos, na mesma chave, com preço consultável antes de qualquer compromisso. A cotação é uma chamada que não cria ordem, não consome limite e responde a mesma conta que vai valer.
Para quem é
- Fintech ou empresa que precisa de BRL → USDT e USDT → BRL rodando em produção, não em piloto.
- Tesouraria que converte todo dia e quer o preço na tela antes de decidir.
- Quem hoje usa corretora manual e quer o mesmo resultado com contrato, estado e comprovante.
O problema
Converter BRL e USDT com previsibilidade tem dois inimigos: preço que muda entre a decisão e a execução, e processo que depende de alguém logar em algum lugar. O primeiro vira prejuízo silencioso; o segundo vira dependência de horário comercial.
A resposta é separar cotar de executar. A prévia responde a mesma conta da ordem real — mesmo trilho, mesmos mínimos, mesmas recusas — mas não persiste nada. Você mostra o número, o usuário decide, e só então a ordem nasce com o valor travado.
O fluxo, ponta a ponta
- Cotar:
POST /cashin/preview(reais → cripto) ouPOST /cash-outs/preview(cripto → reais). Nada é criado. - A prévia devolve o trilho (
path), a quantidade e, na compra, o mínimo em reais daquela rota. - Comprar:
POST /cashin/chargegera o PIX; pago, a cripto sai para a carteira indicada. - Vender:
POST /cash-outs+/acceptdevolve o endereço; depositado, o PIX sai. - Toda operação tem
external_id, webhook assinado e comprovante — a conciliação é automática.
Endpoints usados
| Endpoint | Para quê |
|---|---|
POST /cashin/preview | Preço de compra e o mínimo em reais da rota. Não cria nada. |
POST /cash-outs/preview | Preço de venda nos dois sentidos, sem ordem e sem consumir limite. |
POST /cashin/charge | Compra: gera o PIX identificado e entrega a cripto. |
POST /cash-outs + /accept | Venda: trava a cotação e devolve o endereço de depósito. |
GET /keys/me | Limites por operação e tier vigente da sua chave. |
Exemplo que roda
# preço antes de qualquer ordem — os dois sentidos
curl -X POST https://api.luniumpay.com/cashin/preview -H "X-API-Key: $LUNIUM_KEY" \
-H "Content-Type: application/json" \
-d '{"amount_cents":100000,"asset":"usdt","chain":"polygon"}'
curl -X POST https://api.luniumpay.com/cash-outs/preview -H "X-API-Key: $LUNIUM_KEY" \
-H "Content-Type: application/json" \
-d '{"asset":"USDT","network":"polygon","amount":"1000"}'const h = { "X-API-Key": process.env.LUNIUM_KEY, "Content-Type": "application/json" };
// BRL -> USDT: quanto de cripto sai por R$ X (com o mínimo da rota)
export async function comprar(cents) {
const p = await (await fetch(`${API}/cashin/preview`, { method: "POST", headers: h,
body: JSON.stringify({ amount_cents: cents, asset: "usdt", chain: "polygon" }) })).json();
return { usdt: p.usdt_amount ?? p.amount, minimoBrlCents: p.min_brl_cents };
}
// USDT -> BRL: quanto de PIX sai por N USDT, sem criar ordem
export async function vender(qtd) {
const p = await (await fetch(`${API}/cash-outs/preview`, { method: "POST", headers: h,
body: JSON.stringify({ asset: "USDT", network: "polygon", amount: String(qtd) }) })).json();
return { brl: p.brl_amount, trilho: p.path };
}import os, requests
API, H = "https://api.luniumpay.com", {"X-API-Key": os.environ["LUNIUM_KEY"]}
def comprar(cents):
p = requests.post(f"{API}/cashin/preview", headers=H, timeout=30, json={
"amount_cents": cents, "asset": "usdt", "chain": "polygon"}).json()
return p.get("usdt_amount") or p.get("amount"), p.get("min_brl_cents")
def vender(qtd):
p = requests.post(f"{API}/cash-outs/preview", headers=H, timeout=30, json={
"asset": "USDT", "network": "polygon", "amount": str(qtd)}).json()
return p["brl_amount"], p["path"]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
Abaixo do mínimo: a recusa cita o número — na compra, min_brl_cents vem na própria prévia,
então a tela mostra o mínimo antes de o usuário digitar.
Acima do máximo: valor_acima_do_maximo com o teto vigente. Leia de GET /keys/me em vez de
fixar o número no código: tetos mudam por contrato.
Cotação expirada: a ordem tem expires_at. Depois dele, o depósito chega órfão — cote de novo em vez de
depositar atrasado.
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
A primeira integração útil é só a prévia: uma chamada, sem efeito colateral, que já dá para colocar numa tela. A execução vem depois, com o mesmo contrato que você já testou.
Perguntas que os integradores fazem
A prévia consome limite ou cria ordem?
Nenhum dos dois. Ela roda a mesma conta da cotação real e devolve o mesmo trilho e os mesmos erros, sem persistir nada — foi feita para tela que cota a cada tecla.
O preço fica travado?
Na venda, sim: o aceite trava a cotação e o expires_at diz até quando vale. Na compra, o valor do PIX é o que você definiu, e a cripto entregue segue a cotação da operação.
Quais pares funcionam?
USDT e USDC na Polygon liquidam no trilho próprio, em segundos. Além deles, 1478 ativos em 241 redes na venda e 1795 rotas na compra, pela corretora.
Consigo operar fora do horário bancário?
Sim. PIX liquida 24 horas por dia, todos os dias, e a API não tem janela — o que varia é o tempo de confirmação da rede escolhida.
Contrato OpenAPI 1.25.0 · fatos desta página em product-truth.json · status