Documentação da API
Guia completo para integrar com a API do Lexxen Hub: on-ramp (Pix → cripto), off-ramp (venda de cripto → Pix/BRL) e transferências entre carteiras. O cliente paga em BRL via Pix e a stablecoin (USDC ou USDT) cai direto em uma wallet_address informada.
Base URL
Todos os endpoints são relativos a esta base. O path usado na assinatura vai sem a barra inicial.
https://cashout.lexxen.com/api/v1
lxn_test_… ativa o sandbox (providers simulados, nenhum dinheiro real se move); lxn_… é produção. Use o seletor Sandbox / Produção no topo para alternar os exemplos.Fluxo recomendado
POST /wallets/validate antes de cobrar.POST /quotes → guarde o quote_id e mostre o resumo.POST /orders com o quote_id → gere o QR pelo pix_copy_paste.GET /orders/{id} e/ou o webhook transaction.completed.Autenticação
Toda requisição deve ser assinada com HMAC-SHA256. Inclua os headers abaixo em todas as chamadas.
Headers obrigatórios
api_key do tenant: lxn_… em produção ou lxn_test_… no sandbox (mesma URL, providers simulados).Gerando a assinatura
A assinatura é HMAC-SHA256 sobre timestamp + METHOD + path + body — o timestamp vem PRIMEIRO.
signature = HMAC-SHA256(payload, api_secret) // hex
Regras
METHODem MAIÚSCULAS (POST/GET).pathsem barra inicial e sem query string.body= corpo cru exatamente como enviado (string vazia em GET).- Timestamp válido por ±60s · assinatura de uso único (anti-replay ~120s).
api_secret no frontend. Assine sempre no servidor.$timestamp = (string) time(); $method = 'POST'; $path = 'api/v1/quotes'; // sem barra, sem query $body = json_encode($data); $payload = $timestamp . strtoupper($method) . $path . $body; $sig = hash_hmac('sha256', $payload, $apiSecret);
const crypto = require('crypto'); const timestamp = Math.floor(Date.now()/1000).toString(); const sig = crypto .createHmac('sha256', apiSecret) .update(timestamp + method + path + body) .digest('hex');
import hmac, hashlib
sig = hmac.new(
api_secret.encode(),
(timestamp + method + path + body).encode(),
hashlib.sha256
).hexdigest()
Tipos
awaiting_payment = on-ramp aguardando o Pix; awaiting_deposit = off-ramp aguardando o depósito on-chain.
https://cashout.lexxen.com/api/v1/quotes
Quote — trava a cotação
Crie uma cotação para travar o preço da stablecoin antes de gerar o Pix. A cotação vale por aproximadamente 5 minutos — guarde o quote_id e use-o em POST /orders.
Corpo da requisição
Envie os dados da compra em JSON. Informe amount_brl (valor em reais) ou crypto_receive (quanto de cripto deseja receber) — nunca os dois ao mesmo tempo.
amount_brl. Para entregar um valor exato em cripto, use crypto_receive.{ "amount_brl": 200, "asset": "USDT", "network": "polygon", "wallet_address": "0x8f3…a91" }
Parâmetros
Clique em cada campo para ver detalhes e valores aceitos.
crypto_receive, nunca ambos. ex: 200POST /wallets/validate.Exemplos de código
A requisição precisa ser assinada com HMAC-SHA256 na ordem timestamp + METHOD + path + body. O path vai sem barra inicial e sem query string.
api_secret no frontend. Assine sempre no servidor — a assinatura é de uso único (anti-replay ~120s) e o timestamp vale ±60s.curl -X POST https://cashout.lexxen.com/api/v1/quotes \ -H "X-API-Key: lxn_…" \ -H "X-Timestamp: 1718643000" \ -H "X-Signature: 9f86d0818…" \ -H "Content-Type: application/json" \ -d '{"amount_brl":200,"asset":"USDT","network":"polygon","wallet_address":"0x8f3…a91"}'
const crypto = require('crypto'); const ts = Math.floor(Date.now()/1000).toString(); const method = 'POST', path = 'api/v1/quotes'; const body = JSON.stringify({ amount_brl:200, asset:'USDT', network:'polygon', wallet_address:'0x8f3…a91' }); const sig = crypto.createHmac('sha256', apiSecret) .update(ts+method+path+body).digest('hex'); await fetch('https://cashout.lexxen.com/api/v1'+'/quotes', { method, headers: { 'X-API-Key': apiKey, 'X-Timestamp': ts, 'X-Signature': sig, 'Content-Type': 'application/json' }, body });
$ts = (string) time(); $method = 'POST'; $path = 'api/v1/quotes'; $body = json_encode([ 'amount_brl'=>200, 'asset'=>'USDT', 'network'=>'polygon', 'wallet_address'=>'0x8f3…a91' ]); $sig = hash_hmac('sha256', $ts.$method.$path.$body, $apiSecret); // envie via cURL com os headers X-API-Key / X-Timestamp / X-Signature
import time, hmac, hashlib, json, requests ts = str(int(time.time())) method, path = 'POST', 'api/v1/quotes' body = json.dumps({"amount_brl":200,"asset":"USDT","network":"polygon","wallet_address":"0x8f3…a91"}) sig = hmac.new(api_secret.encode(), (ts+method+path+body).encode(), hashlib.sha256).hexdigest() requests.post('https://cashout.lexxen.com/api/v1'+'/quotes', headers={'X-API-Key':api_key,'X-Timestamp':ts,'X-Signature':sig, 'Content-Type':'application/json'}, data=body)
Resposta 200 OK
POST /quotes é FLAT — sem o envelope data. Os demais endpoints usam { "data": … }.{ "quote_id": "q_8a72…e1", "asset": "USDT", "network": "polygon", "amount_brl": "200.00", "amount_crypto": "38.74000000", "wallet_address": "0x8f3…a91", "price": "5.14970000", "fees": { "percent": "3.0000", "fixed": "1.00000000", "network": "2.00000000" }, "expires_at": "2026-06-17T17:17:39+00:00" }
Campos da resposta
POST /orders para gerar o Pix.Erros
https://cashout.lexxen.com/api/v1/orders
Create Order — gera o Pix
Cria o pedido a partir de um quote_id e devolve o pix_copy_paste para gerar o QR.
Corpo da requisição
Envie o quote_id da cotação. O external_id é o seu identificador opcional para consultar depois.
external_id para reconciliar com o id do seu sistema — depois consulte por ele em GET /orders/{external_id}.{ "quote_id": "q_8a72…e1", "external_id": "pedido-loja-123" }
Parâmetros
Clique em cada campo para ver detalhes e valores aceitos.
quote_id retornado por POST /quotes. Precisa estar válido (não expirado e não usado).GET /orders/{external_id}.Exemplos de código
Assine com path = api/v1/orders e o body cru.
curl -X POST https://cashout.lexxen.com/api/v1/orders \ -H "X-API-Key: lxn_…" \ -H "X-Timestamp: 1718643000" \ -H "X-Signature: 9f86d0818…" \ -H "Content-Type: application/json" \ -d '{"quote_id":"q_8a72…e1","external_id":"pedido-loja-123"}'
const path = 'api/v1/orders'; const body = JSON.stringify({ quote_id, external_id }); const sig = crypto.createHmac('sha256', apiSecret) .update(ts + 'POST' + path + body).digest('hex'); await fetch('https://cashout.lexxen.com/api/v1'+'/orders', { method:'POST', headers, body });
Resposta 201
/quotes, esta resposta usa o envelope data.{ "data": { "uuid": "ord_3f1…77", "external_id": "pedido-loja-123", "display_status": "awaiting_payment", "asset": "USDT", "network": "polygon", "amount_brl": "200.00", "amount_crypto": "38.74000000", "wallet_address": "0x8f3…a91", "pix_copy_paste": "00020126…", "provider_transaction_id": "…", "receipt": null, "error_message": null, "finished_at": null, "created_at": "2026-06-17T17:12:00+00:00" } }
Campos da resposta
GET /orders/{uuid}.null enquanto pendente.Erros
https://cashout.lexxen.com/api/v1/orders/{id}/pay-from-balance
Pay from Balance — paga com saldo
Liquida o Pix de um pedido on-ramp debitando o seu saldo na Lexxen, em vez de pagar o copia-e-cola externamente. Sem corpo: o valor e o EMV saem do próprio pedido.
Pré-condições
422 BANKING_CORE_NOT_CONFIGURED.awaiting_payment.pix_copy_paste ou, quando null, no deposit_address de Pix das deposit_instructions.Parâmetros
uuid do pedido on-ramp a pagar.Exemplos de código
POST sem corpo. Assine com path = api/v1/orders/{uuid}/pay-from-balance e body vazio.
curl -X POST https://cashout.lexxen.com/api/v1/orders/ord_3f1…77/pay-from-balance \ -H "X-API-Key: lxn_…" \ -H "X-Timestamp: 1718643000" \ -H "X-Signature: 9f86d0818…"
const path = 'api/v1/orders/ord_3f1…77/pay-from-balance'; const sig = crypto.createHmac('sha256', apiSecret) .update(ts + 'POST' + path + '').digest('hex'); await fetch('https://cashout.lexxen.com/api/v1'+'/orders/ord_3f1…77/pay-from-balance', { method:'POST', headers });
Resposta 200
POST /orders (envelope data). O pedido segue em awaiting_payment até a confirmação do Pix pela Lexxen (webhook) → processing → completed — igual ao pagamento externo.{ "data": { "uuid": "ord_3f1…77", "display_status": "awaiting_payment", "asset": "USDT", "network": "polygon", "amount_brl": "500.00", "amount_crypto": "92.50000000", "wallet_address": "0xabc…123", "created_at": "2026-06-17T14:50:00+00:00" } }
Erros
https://cashout.lexxen.com/api/v1/orders/{idOrExternalId}
Get Status — status do pedido
Retorna o pedido (envelope data) com o display_status atualizado. Aceita o uuid OU o seu external_id.
Parâmetros
uuid do pedido ou o external_id enviado na criação.Exemplos de código
Em GET o body é string vazia na assinatura.
curl https://cashout.lexxen.com/api/v1/orders/ord_3f1…77 \ -H "X-API-Key: lxn_…" \ -H "X-Timestamp: 1718643000" \ -H "X-Signature: 9f86d0818…"
const path = 'api/v1/orders/ord_3f1…77'; const sig = crypto.createHmac('sha256', apiSecret) .update(ts + 'GET' + path + '').digest('hex');
Resposta 200
Mesmo objeto de POST /orders (envelope data), com o status atualizado.
{ "data": { "uuid": "ord_3f1…77", "display_status": "completed", "amount_crypto": "38.74000000", "receipt": "0xabc…", "finished_at": "2026-06-17T17:18:02+00:00" } }
Erros
https://cashout.lexxen.com/api/v1/orders
List Orders — lista com filtros
Lista paginada de pedidos, com filtro por status e intervalo de datas.
Query parameters
Resposta 200
api/v1/orders).{ "data": [ /* …orders… */ ], "meta": { "page": 1, "per_page": 20, "total": 42, "last_page": 3 } }
https://cashout.lexxen.com/api/v1/wallets/validate
Validate Wallet — valida endereço
Verifica se um endereço é válido para a rede e se está em blocklist. Útil antes de criar a cotação.
Corpo da requisição
Envie o address e a network de destino.
{ "address": "0x8f3…a91", "network": "polygon" }
Resposta 200
Envelope data com o resultado da validação.
{ "data": { "address": "0x8f3…a91", "blockchain": "polygon", "is_blocklisted": false } }
Campos da resposta
true indica endereço em lista de bloqueio — não prossiga com a operação.Erros
https://cashout.lexxen.com/api/v1/sell/quotes
Sell Quote — trava a cotação de venda
O cliente deposita stablecoin on-chain e recebe BRL via Pix. Informe amount_crypto (quanto vender) ou amount_brl (quanto receber).
Corpo da requisição
O holder indica de quem é a carteira de origem: self (padrão) ou other.
amount_brl líquido (já com taxas) — mostre-o como o valor que o cliente vai receber.{ "amount_crypto": 100, "asset": "USDT", "network": "polygon", "holder": "self" // opcional: self (padrão) ou other }
Parâmetros
amount_brl.self (padrão) ou other.Resposta 200 OK
/quotes, a resposta de venda é FLAT (sem envelope data).{ "quote_id": "q_3b91…d0", "direction": "off_ramp", "asset": "USDT", "network": "polygon", "amount_crypto": "100.00000000", "amount_brl": "535.00", "quotation": "5.40000000", "holder": "self", "fees": { "percent": "1.5000", "fixed": "0.50000000", "shipping_brl": "3.50" }, "expires_at": "2026-06-17T15:00:00+00:00" }
Campos da resposta
Erros
https://cashout.lexxen.com/api/v1/sell/orders
Create Sell Order — gera o payout
Cria a venda a partir de um quote_id, com o sender.address (origem on-chain) e a receiver.pix_key. Devolve o deposit_address.
Corpo da requisição
O sender.address é a origem on-chain da cripto; o receiver.pix_key é a chave Pix que vai receber os reais.
deposit_address e depois chame /sell/orders/{id}/confirm.{ "quote_id": "q_3b91…d0", "external_id": "venda-loja-123", "sender": { "address": "0x… (origem on-chain)" }, "receiver": { "pix_key": "[email protected]", "document": "12345678900" // opcional } }
Parâmetros
quote_id de uma cotação de venda (direção off_ramp) válida.Resposta 201
awaiting_deposit. Envie a cripto para o deposit_address.{ "data": { "uuid": "sell_9c2…aa", "external_id": "venda-loja-123", "direction": "off_ramp", "display_status": "awaiting_deposit", "asset": "USDT", "network": "polygon", "amount_crypto": "100.00000000", "amount_brl": "535.00", "sender_address": "0x…", "pix_key": "[email protected]", "deposit_address": "0x… (envie a cripto para cá)", "transaction_hash": null, "finished_at": null, "created_at": "2026-06-17T17:12:00+00:00" } }
Erros
https://cashout.lexxen.com/api/v1/sell/orders/{id}/confirm
Confirm — confirma o depósito on-chain
Depois de depositar a cripto no deposit_address, confirme informando o transaction_hash. Só funciona enquanto a venda está em awaiting_deposit.
Corpo da requisição
O amount é opcional — informe a quantidade efetivamente depositada se diferir da cotação.
{ "transaction_hash": "0x… (hash do depósito)", "amount": 100 // opcional }
Resposta 200
Recurso da venda atualizado, com display_status → processing.
Erros
https://cashout.lexxen.com/api/v1/sell/orders/{idOrExternalId}
Get Sell Status — status da venda
Retorna a venda (envelope data) com o status atualizado. Aceita o uuid OU o seu external_id — apenas vendas (off_ramp).
Parâmetros
uuid da venda ou o external_id enviado na criação.Resposta 200
Mesmo objeto de POST /sell/orders (envelope data), com o display_status atualizado.
https://cashout.lexxen.com/api/v1/sell/orders
List Sell Orders — lista de vendas
Lista paginada de vendas (off_ramp), com os mesmos filtros do on-ramp.
Query parameters
Resposta 200
api/v1/sell/orders). Resposta paginada com data + meta.https://cashout.lexxen.com/api/v1/wallets
List Wallets — carteiras + saldos
Lista as carteiras gerenciadas do cliente, com o saldo de cada uma. Use o wallet_id retornado como sender no POST /wallet-transfers.
Query parameters
meta.cursor da página anterior.Resposta 200
Lista cursor-paginada: o meta.cursor aponta para a próxima página.
{ "data": [{ "wallet_id": "wlt_2a…f1", "name": "Minha carteira", "network": "polygon", "address": "0x8f3…a91", "is_external": false, "balances": [ { "currency": "USDT", "balance": "150.00" } ] }], "meta": { "cursor": "…" } }
Erros
https://cashout.lexxen.com/api/v1/wallet-transfers
Create Transfer — wallet → wallet
Transfere stablecoin entre carteiras gerenciadas (ou para um endereço externo) na mesma rede — sem cotação. O destino pode ser outro wallet_id OU um address.
Corpo da requisição
O sender é o wallet_id da carteira de origem. O receiver é outra carteira (wallet_id) OU um endereço on-chain (address), sempre na mesma rede.
processing (fundos em custódia) e segue para completed ou failed.{ "amount": 50, "asset": "USDT", "network": "polygon", "sender": "wlt_2a…f1", "receiver": { "wallet_id": "wlt_7c…b3" // OU "address": "0x…" }, "external_id": "transf-123" // opcional (máx 36) }
Parâmetros
network.wallet_id da carteira de origem (de GET /wallets).wallet_id (carteira gerenciada) ou address (endereço on-chain).Resposta 201
Envelope data com a transferência criada (direction: wallet_transfer).
{ "data": { "uuid": "wtr_5d…c2", "external_id": "transf-123", "direction": "wallet_transfer", "display_status": "processing", "asset": "USDT", "network": "polygon", "amount": "50.00000000", "sender_wallet_id": "wlt_2a…f1", "receiver_wallet_id": "wlt_7c…b3", "receiver_address": "0x…", "transaction_hash": null, "finished_at": null, "created_at": "2026-06-17T17:12:00+00:00" } }
Erros
https://cashout.lexxen.com/api/v1/wallet-transfers/{idOrExternalId}
Get Transfer — status da transferência
Retorna a transferência (envelope data) com o display_status atualizado. Aceita o uuid OU o seu external_id.
Resposta 200
Mesmo objeto de POST /wallet-transfers (envelope data), com o status atualizado.
https://cashout.lexxen.com/api/v1/wallet-transfers
List Transfers — lista de transferências
Lista paginada de transferências, com filtro por status e intervalo de datas.
Query parameters
Resposta 200
api/v1/wallet-transfers). Resposta paginada com data + meta.https://cashout.lexxen.com/api/v1/balance
Balance — saldo unificado
Saldo consolidado do tenant em Pix (BRL) e cripto numa única chamada. Cada bloco é resolvido de forma independente: se um provedor falhar, aquele bloco vem null e o outro continua válido. Somente leitura — não movimenta dinheiro.
Exemplos de código
GET sem corpo. Assine com path = api/v1/balance e body vazio.
curl https://cashout.lexxen.com/api/v1/balance \ -H "X-API-Key: lxn_live_…" \ -H "X-Timestamp: 1718643000" \ -H "X-Signature: 9f86d0818…"
const path = 'api/v1/balance'; const sig = crypto.createHmac('sha256', apiSecret) .update(ts + 'GET' + path + '').digest('hex');
Resposta 200
available = saldo livre menos as taxas pendentes (max(0, …)).crypto, apenas ativos com free > 0 são listados (8 casas decimais).pix e/ou crypto podem vir null se o provedor correspondente estiver indisponível.{ "data": { "pix": { "balance": 1000.00, "pending_fees": 12.50, "available": 987.50 }, "crypto": { "balances": [ { "asset": "USDT", "free": "150.00000000", "pending_fees": "2.00000000", "available": "148.00000000" } ] } } }
https://cashout.lexxen.com/api/v1/balance/banking
Banking Balance — saldo no banking core
Consulta direto o saldo da conta do tenant no banking core (Lexxen), sem passar pelos provedores de Pix/cripto do GET /balance. É a mesma conta usada no POST /orders/{id}/pay-from-balance — útil para saber quanto há disponível antes de pagar um pedido por saldo. Somente leitura.
Pré-condições
422 BANKING_CORE_NOT_CONFIGURED.Exemplos de código
GET sem corpo. Assine com path = api/v1/balance/banking e body vazio.
curl https://cashout.lexxen.com/api/v1/balance/banking \ -H "X-API-Key: lxn_live_…" \ -H "X-Timestamp: 1718643000" \ -H "X-Signature: 9f86d0818…"
const path = 'api/v1/balance/banking'; const sig = crypto.createHmac('sha256', apiSecret) .update(ts + 'GET' + path + '').digest('hex');
Resposta 200
data sem transformação. Os saldos vêm por moeda em balances, com valores em centavos: available é o disponível e blocked é o bloqueado.{ "data": { "balances": { "BRL": { "available": 150000, "blocked": 2500 } } } }
Erros
Webhooks
Quando um pedido conclui (on-ramp ou off-ramp), a Lexxen dispara um webhook para a URL configurada pelo tenant. O payload inclui direction e, na venda, o transaction_hash.
Eventos
Payload
{ "event": "transaction.completed", "order_uuid": "ord_3f1…77", "external_id": "pedido-loja-123", "direction": "on_ramp", "status": "completed", "asset": "USDT", "network": "polygon", "amount_brl": "200.00", "amount_crypto": "38.74000000", "wallet_address": "0x8f3…a91", "transaction_hash": null, // preenchido na venda (off-ramp) "provider": "UNBLOCKPAY" }
Códigos de erro
Todas as respostas são JSON. Os corpos de erro trazem um código para você tratar no seu código.
ORDER_NOT_FOUND · QUOTE_NOT_FOUND · TRANSFER_NOT_FOUNDQUOTE_FAILED · QUOTE_NOT_USABLE · WALLET_VALIDATION_FAILED · INSUFFICIENT_BALANCE · PAYOUT_NOT_CONFIRMABLE · validaçãoexternal_id). A resposta de POST /quotes e POST /sell/quotes é FLAT; as demais usam envelope data.