Aliquot

Payouts

Pagar saldos liquidados a una wallet — el step-up 2FA para sesiones del dashboard, API keys con step-up, el fee de red fijo y el ciclo de vida del payout.

Última actualización 27 oct 2026

Un payout envía parte o todo el saldo disponible de una cuenta (GET /api/v1/crypto/balances?mode=) en una red y un token a una dirección externa, desde la hot wallet.

curl -X POST "$API/api/v1/crypto/payouts" \
  -H "authorization: Bearer $KEY" -H 'content-type: application/json' -H 'idempotency-key: po-2026-10-27-halden' \
  -d '{ "account": "halden_type", "network": "POLYGON_AMOY", "token": "USDT",
        "amount": "50.00", "destination_address": "0x…" }'

Quién puede hacer payouts

Los payouts requieren crypto-payouts:create y se rechazan mientras un platform admin está impersonando al usuario. Además, cada payout pasa por un step-up:

  • Dashboard (sesión con cookie): cada payout lleva un código TOTP fresco (totp_code). El usuario tiene que tener la autenticación de dos factores activada (Settings → Security); si no, el diálogo New payout linkea ahí. Los códigos son de un solo uso, y 5 códigos fallidos en 15 minutos bloquean los step-ups (429 STEP_UP_LOCKED). Un código incorrecto o reutilizado es 403.
  • Las API keys se saltean el código por payout, así que el step-up se mueve al momento en que la key se crea: crear una key con crypto-payouts:create (o crypto-payouts:manage, o *:*) requiere una sesión de navegador no impersonada con 2FA y un totp_code válido. Solo esas keys llevan payoutStepUpAt; cualquier otra key responde 403 STEP_UP_REQUIRED. Las keys creadas antes de esta regla perdieron la capacidad de hacer payouts. El CLI de operador (mint:api-key) también lo setea.

Monto y fee

Un fee de red fijo por payout sale del monto (net_amount = amount − fee) y se registra como REVENUE:PAYOUT_NETWORK_FEE: CRYPTO_PAYOUT_FEE_POLYGON (por defecto 0.10), CRYPTO_PAYOUT_FEE_BSC (0.15), CRYPTO_PAYOUT_FEE_BASE (0.10). El monto tiene que superar el fee. El destino tiene que ser una dirección válida que no sea una de las propias del gateway (los contratos se permiten, a diferencia de los refunds).

Ciclo de vida

EstadoSignificado
QUEUEDCreado: el monto queda bloqueado en el ledger (MERCHANT_LOCKED) en la misma transacción, así que un payout por encima del saldo es 409 INSUFFICIENT_BALANCE y no crea nada.
BROADCASTFirmado y enviado por el worker una vez que la hot wallet puede cubrir net_amount y el gas (si no, espera a los sweeps). La transacción se registra en el journal antes de transmitirse, así que un crash reenvía los mismos bytes; después de 180 s sin receipt se reemplaza con el mismo nonce y fees +20 %.
COMPLETEDLa transacción alcanzó el umbral de confirmaciones de la red; el lock se libera hacia el payout (payout.completed).
FAILEDRevertida o descartada: el lock vuelve al saldo disponible y el gas se registra como gasto (payout.failed).

La página Payouts del dashboard muestra los saldos arriba, el historial abajo (contador de confirmaciones en vivo mientras está BROADCAST) y New payout (saldo de origen, monto, destino precargado con la dirección de liquidación de la cuenta, TOTP).

[!WARNING] Cuando una invoice no tiene merchant, el seller es la cuenta PLATFORM de la organization: su neto se acredita en PARTNER_PAYABLE junto con el markup, el único saldo del que toman los payouts de PLATFORM. Así, todo payout sale del saldo que el dashboard muestra como disponible.

En esta página