Pagamentos (Aliquot)
Pagamentos em stablecoins para plataformas — invoices, checkout hospedado, splits, refunds e payouts em Polygon, BNB Chain e Base.
Última atualização 27 de out. de 2026
Aliquot é o bounded context crypto-payments (apps/server/src/modules/crypto-payments/). Uma plataforma (a organização) vende em nome dos seus vendedores, recebe pagamentos em stablecoins dos compradores, divide cada pagamento até o centavo e paga vendedores e parceiros on chain.
O que faz
- Invoices em USD, pagas em USDT ou USDC na Polygon, BNB Chain (BSC) ou Base. Cada invoice recebe seu próprio endereço de depósito, derivado de uma chave HD (
m/44'/60'/0'/0/i, as invoices começam no índice 1000). - Checkout hospedado em
/pay/:id: o comprador escolhe um par rede × token (se a invoice não fixou um), vê um QR code EIP-681 ou paga com um clique usando uma wallet do navegador. A página acompanha a invoice ao vivo (SSE, com polling como fallback) até o recibo e a invoice imprimível. - Payment links (
/l/:slug): uma página de produto com preço fixo; cada "Pagar" inicia uma invoice nova. - Splits: uma taxa de processamento de 0,50 % (50 bps,
CRYPTO_PLATFORM_FEE_BPS), um markup opcional da plataforma e participações de parceiros, calculados em unidades base inteiras e lançados em um ledger de partidas dobradas. - Refunds para todo caso em que chegou dinheiro que não é devido ao vendedor (pagamento a mais, pagamento parcial expirado, pagamento atrasado, token errado). Os refunds são puxados pelo comprador por meio de um link de resgate privado — veja Refunds.
- Payouts de saldos liquidados para uma wallet externa, protegidos por um step-up TOTP — veja Payouts.
- Webhooks (
invoice.*,payout.*,refund.*) pelo módulo de webhooks de saída do boilerplate, assinados com HMAC.
Redes e tokens
Existem quatro pares por modo. O modo de teste usa apenas testnets; o modo live usa apenas mainnets. O modo vem da rede (ou de mode em uma invoice em que o comprador escolhe).
| Par | Live (chainId) | Teste (chainId) | Confirmações |
|---|---|---|---|
| Polygon · USDT | Polygon PoS (137) | Polygon Amoy (80002) | 64 |
| Polygon · USDC | Polygon PoS (137) | Polygon Amoy (80002) | 64 |
| BNB Chain · USDT (18 decimais) | BSC (56) | BSC Testnet (97) | 15 |
| Base · USDC | Base (8453) | Base Sepolia (84532) | 30 |
Os contratos de token são os canônicos (ex.: Polygon USDT 0xc2132D05…8e8F, Base USDC 0x833589fC…2913). A Amoy não tem USDT canônico; ele existe apenas nas chains locais, por isso só é oferecido quando todas as URLs de CRYPTO_RPC_POLYGON_AMOY são locais (loopback). Uma rede sem URL CRYPTO_RPC_<NETWORK> aparece em GET /api/v1/crypto/networks com enabled: false e não pode ser selecionada.
Peças em movimento
| Processo | Papel |
|---|---|
| Servidor da API | API de merchant (/api/v1/crypto/*, sessão ou API key), API do checkout hospedado (/api/v1/public/*, sem auth). Deriva os endereços de depósito apenas a partir da xpub. |
Worker (bun run worker) | A queue crypto do BullMQ: scan (a cada 2 s por rede), expire (10 s), sweep (15 s), payouts (3 s), refunds (5 s). O único processo que assina. |
| Postgres | Invoices, transfers, o ledger (append-only, balanceado por transação, balance >= 0), o journal de transações de saída. |
| Redis | Agendamentos de jobs, locks por job/por rede, mutexes de nonce, contadores de tentativas de step-up. |
Sem CRYPTO_MASTER_MNEMONIC o servidor sobe e todo endpoint cripto responde 503 CRYPTO_NOT_CONFIGURED. A lista completa de variáveis de ambiente está em Ambiente; os detalhes internos do módulo estão em Bounded contexts.
Ciclo de vida da invoice
AWAITING_SELECTION ──buyer picks a pair──▶ PENDING
PENDING ──first transfer──▶ DETECTED ──all confirmed──▶ PAID | OVERPAID | UNDERPAID
PENDING ──expiry──▶ EXPIRED (DETECTED never expires: the buyer paid in time)
UNDERPAID ──top-up──▶ DETECTED; UNDERPAID ──expiry──▶ EXPIRED_UNDERPAID (refund held)
EXPIRED_UNDERPAID ──refund paid──▶ REFUNDED; any open invoice ──void──▶ CANCELLEDEscolher um par reinicia a janela de pagamento (padrão de 30 minutos, expires_in_minutes 1–1440), porque o endereço só é exibido a partir desse momento.
Próximos passos
- Quickstart: API key → invoice → pagamento → webhook.
- Confirmações: quando uma invoice conta como paga, e por que dizemos "confirmado", não "final".
- Desenvolvimento local: chains locais, dados de demo e as suítes de aceitação.