Confirmaciones
Cuándo cuenta un pago, qué ven el comprador y el merchant mientras se confirma, y por qué es "confirmado", no "final".
Última actualización 27 oct 2026
Los umbrales
Una invoice se acredita solo después de que la transferencia alcanzó el umbral de confirmaciones de su red. El conteo es una sola fórmula en todos lados (confirmationsAt): head − block + 1, así que el bloque que contiene la transferencia es la confirmación 1.
| Red | Umbral | Bloque típico | ≈ Espera |
|---|---|---|---|
| Polygon PoS / Amoy | 64 | 2 s | ~2 min |
| BNB Chain / BSC Testnet | 15 | 3 s | ~45 s |
| Base / Base Sepolia | 30 | 2 s | ~1 min |
Los umbrales de testnet se pueden bajar para desarrollo con CRYPTO_CONFIRMATIONS_<NETWORK> (p. ej. CRYPTO_CONFIRMATIONS_POLYGON_AMOY=5). En producción, los overrides de mainnet se rechazan al arrancar. Cada invoice guarda el umbral con el que se creó (required_confirmations), así que cambiar el env nunca mueve una invoice que ya se está confirmando.
Cómo se sigue una transferencia
El job scan del worker corre cada 2 s por red:
- Lee los logs de cada contrato de token canónico de la red enviados a las direcciones de depósito activas (
eth_getLogs, en rangos de como máximoCRYPTO_LOGS_MAX_RANGE_<NETWORK>bloques, 200 por defecto, y como máximo 20 direcciones por query; un rango que el provider rechaza se parte a la mitad hasta que pasa). - Re-escanea los últimos 12 bloques en cada tick y vuelve a chequear los hashes de bloque: una transferencia cuyo bloque fue reemplazado por un reorg se marca
ORPHANED, y una invoice que solo tenía transferencias huérfanas vuelve deDETECTEDaPENDING. - Actualiza las confirmaciones y corre la máquina de estados de la invoice. El estado, el posting del ledger, los refunds y los eventos del outbox de una evaluación se escriben en una sola transacción de base de datos.
El primer avistaje mueve la invoice a DETECTED (al comprador se le avisa que el pago está en camino y puede cerrar la página). Alcanzar el umbral la mueve a PAID, OVERPAID o UNDERPAID y registra la liquidación en el ledger. Una invoice DETECTED nunca vence: el comprador pagó a tiempo.
Qué ve cada lado:
- Checkout: una barra de confirmaciones
n / requiredcon un ETA, enviada por Server-Sent Events (GET /api/v1/public/pay/:id/stream, con polling cada 4 s como respaldo). - Dashboard: la línea de la invoice dice "Confirming n/required"; la barra de split se dibuja hueca hasta que la invoice se liquida.
- Webhooks:
invoice.detecteden el primer avistaje,invoice.paid(einvoice.overpaid) al alcanzar el umbral.
"Confirmado", no "final"
Los umbrales son una política de riesgo elegida por red: lo bastante profundos como para que un reorg que llegue más atrás no sea una preocupación práctica, lo bastante cortos para el checkout. No son la finality de protocolo de la cadena, que el gateway no sigue. Por eso el producto dice "Confirmed at 64/64 confirmations" y nunca "final", "irreversible" o "settled forever", ni en el checkout, ni en el dashboard, ni en los emails, ni en estos docs. Respetá esa regla cuando escribas copy.
Los mismos umbrales controlan el dinero que sale: un sweep, un payout o un refund queda COMPLETED solo cuando su propia transacción alcanza el umbral de la red, y un refund se envía solo después de que el sweep del depósito está confirmado.