Pagos (Aliquot)
Pagos en stablecoins para plataformas — invoices, checkout hosteado, splits, refunds y payouts en Polygon, BNB Chain y Base.
Última actualización 27 oct 2026
Aliquot es el bounded context crypto-payments (apps/server/src/modules/crypto-payments/). Una plataforma (la organization) vende en nombre de sus sellers, cobra a los compradores en stablecoins, divide cada pago al centavo y les paga on chain a sellers y partners.
Qué hace
- Invoices en USD, pagadas en USDT o USDC sobre Polygon, BNB Chain (BSC) o Base. Cada invoice tiene su propia dirección de depósito, derivada de una clave HD (
m/44'/60'/0'/0/i; las invoices empiezan en el índice 1000). - Checkout hosteado en
/pay/:id: el comprador elige un par red × token (si la invoice no lo fijó), ve un código QR EIP-681 o paga en un clic con una wallet del navegador. La página sigue la invoice en vivo (SSE, con polling de respaldo) hasta el recibo y la invoice imprimible. - Payment links (
/l/:slug): una página de producto con precio fijo; cada "Pay" arranca una invoice nueva. - Splits: un fee de procesamiento de 0.50 % (50 bps,
CRYPTO_PLATFORM_FEE_BPS), un markup opcional de la plataforma y partes para partners, calculados en unidades base enteras y registrados en un ledger de partida doble. - Refunds para cada caso en que llegó dinero que no se le debe al seller (sobrepago, pago parcial vencido, pago tardío, token equivocado). Los refunds los retira (pull) el comprador a través de un link de reclamo privado — ver Refunds.
- Payouts de saldos liquidados a una wallet externa, protegidos por un step-up TOTP — ver Payouts.
- Webhooks (
invoice.*,payout.*,refund.*) a través del módulo de webhooks salientes del boilerplate, firmados con HMAC.
Redes y tokens
Existen cuatro pares por modo. El modo test usa solo testnets; el modo live usa solo mainnets. El modo sale de la red (o de mode en una invoice donde elige el comprador).
| Par | Live (chainId) | Test (chainId) | Confirmaciones |
|---|---|---|---|
| Polygon · USDT | Polygon PoS (137) | Polygon Amoy (80002) | 64 |
| Polygon · USDC | Polygon PoS (137) | Polygon Amoy (80002) | 64 |
| BNB Chain · USDT (18 decimales) | BSC (56) | BSC Testnet (97) | 15 |
| Base · USDC | Base (8453) | Base Sepolia (84532) | 30 |
Los contratos de token son los canónicos (p. ej. USDT de Polygon 0xc2132D05…8e8F, USDC de Base 0x833589fC…2913). Amoy no tiene un USDT canónico; existe solo en las cadenas locales, así que se ofrece únicamente cuando todas las URLs de CRYPTO_RPC_POLYGON_AMOY son locales (loopback). Una red sin URL CRYPTO_RPC_<NETWORK> aparece en GET /api/v1/crypto/networks con enabled: false y no se puede seleccionar.
Piezas en movimiento
| Proceso | Rol |
|---|---|
| Servidor de la API | API de merchant (/api/v1/crypto/*, sesión o API key), API del checkout hosteado (/api/v1/public/*, sin auth). Deriva las direcciones de depósito solo desde la xpub. |
Worker (bun run worker) | La queue crypto de BullMQ: scan (cada 2 s por red), expire (10 s), sweep (15 s), payouts (3 s), refunds (5 s). El único proceso que firma. |
| Postgres | Invoices, transfers, el ledger (append-only, balanceado por transacción, balance >= 0), el journal de transacciones salientes. |
| Redis | Schedules de jobs, locks por job/por red, mutex de nonces, contadores de intentos de step-up. |
Sin CRYPTO_MASTER_MNEMONIC el servidor arranca y todos los endpoints cripto responden 503 CRYPTO_NOT_CONFIGURED. La lista completa de variables está en Entorno; los detalles internos del módulo, en Bounded contexts.
Ciclo de vida de la 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──▶ CANCELLEDElegir un par reinicia la ventana de pago (30 minutos por defecto, expires_in_minutes 1–1440), porque la dirección se muestra recién a partir de ese momento.
Siguiente
- Inicio rápido: API key → invoice → pago → webhook.
- Confirmaciones: cuándo una invoice cuenta como pagada, y por qué decimos "confirmado", no "final".
- Desarrollo local: cadenas locales, datos de demo y las suites de aceptación.