Ir al contenido

Dispersar bolívares

Una llamada. Entrega los bolívares de la cotización al beneficiario, en su propio banco, por el instrumento que pidas.

Ventana de terminal
curl -s $BASE/v1/payouts \
-H "x-api-key: $KEY" -H 'content-type: application/json' \
-H 'Idempotency-Key: payout-2026-0001' \
-d '{"quoteId":"70ec44b5-c1df-45b1-86fe-8f92c3959689","method":"pago_movil",
"beneficiaryId":"8ade3e33-6f1c-4d0a-9d33-2c6b0a41f7e2",
"sender":{"nationalId":"V18234112","firstName":"Ana","lastName":"Pérez",
"phone":"04241234567","email":"ana@example.com"}}'
Campo Obligatorio Qué es
quoteId sí Fija el importe en Bs y nuestra comisión. No hay campo de monto en esta llamada
method sí pago_movil o transferencia
beneficiaryId uno de los dos Beneficiario ya dado de alta
beneficiary uno de los dos Sus datos en línea
sender de facto sí Quién ordena el envío. Ver abajo
methodPolicy no preferred (por defecto) o strict. Ver abajo
customerId no A qué usuario tuyo corresponde. Para tu trazabilidad y para los límites por usuario

Llega al teléfono del beneficiario. Necesita banco, móvil, cédula y nombre.

Ventana de terminal
curl -s $BASE/v1/payouts -H "x-api-key: $KEY" -H 'content-type: application/json' \
-H 'Idempotency-Key: payout-2026-0002' \
-d '{"quoteId":"'$QUOTE'","method":"pago_movil",
"beneficiary":{"fullName":"José Marcano","nationalId":"V18234112",
"bankCode":"0138","phone":"04141234567"},
"sender":{"nationalId":"V12345678","firstName":"Ana","lastName":"Pérez",
"phone":"04241234567","email":"ana@example.com"}}'

Tope por operación: 100.000,00 Bs (10000000), el que fija el banco receptor para pago móvil. Ver límites.

201 Created
{
"id": "89920401-26da-4f69-b57d-bc20e0366ce2", "status": "submitted",
"message": "El riel aceptó el envío y todavía no lo ha liquidado. Se confirmará por webhook (payment.settled); no lo reintentes con otra Idempotency-Key.",
"bankReference": null, "asset": "BS", "amount": "5000000",
"feeAmount": "50000", "totalDebited": "5050000",
"method": "pago_movil", "methodRequested": "pago_movil", "methodChanged": false,
"beneficiaryId": "8ade3e33-6f1c-4d0a-9d33-2c6b0a41f7e2",
"beneficiary": { "fullName": "María Gómez", "nationalId": "V12345678",
"bankCode": "0138", "instrument": "pago_movil" }
}
Campo Qué es
amount Lo que recibe el beneficiario: 50.000,00 Bs
feeAmount Nuestra comisión: 500,00 Bs
totalDebited Lo que bajó de tu saldo: 50.500,00 Bs
bankReference El comprobante que verá el beneficiario. null hasta que el riel liquida
method vs methodRequested Por dónde salió vs. por dónde pediste que saliera
methodChanged true si se cambió de canal

POST /payouts responde 201 siempre que la operación se procesó, incluso cuando falló: el desenlace va en status, no en el HTTP.

status Qué pasó Qué haces
submitted El riel aceptó y está liquidando. Es el desenlace normal No reintentar. Esperar el webhook
settled Liquidada: el beneficiario tiene sus Bs Nada
failed Ningún riel la aceptó. El asiento ya se revirtió: no se te cobra nada Corregir y reintentar con otra cotización
unknown El riel no confirmó y no sabemos si pagó NUNCA reintentar. Se resuelve solo

La respuesta trae reason, y feeAmount viene en "0" porque el asiento se revirtió entero.

201 Created — dispersión rechazada
{
"id": "89920401-26da-4f69-b57d-bc20e0366ce2", "status": "failed",
"reason": "beneficiary_missing_phone",
"asset": "BS", "amount": "5000000", "feeAmount": "0",
"beneficiaryId": "8ade3e33-6f1c-4d0a-9d33-2c6b0a41f7e2",
"beneficiary": { "fullName": "María Gómez", "nationalId": "V12345678",
"bankCode": "0134", "instrument": "transferencia" }
}

Los más frecuentes son beneficiary_missing_phone (falta el móvil, también en transferencia), beneficiary_mismatch, sender_required, amount_below_rail_minimum y no_route. Catálogo completo en errores; qué hacer con cada uno, en cuando algo falla.

Quién ordena el envío. Se obtiene por tres caminos, en este orden: el bloque sender de la petición; el usuario referenciado por customerId, si tiene documento, nombre, móvil y correo; el remitente por defecto de tu programa.

"sender": { "nationalId": "V18234112", "firstName": "Ana", "lastName": "Pérez",
"phone": "04241234567", "email": "ana@example.com", "nationality": "VEN" }
Campo Obligatorio Formato
nationalId sí Venezolano: V, E o J + hasta 9 dígitos. Extranjero: 5 a 20 alfanuméricos, sin letra venezolana delante
firstName · lastName sí Mínimo 2 caracteres
phone sí Móvil venezolano (0412/0414/0416/0424/0426). Se aceptan 04141234567, +584141234567 y 4141234567, y se normalizan a 04XXXXXXXXX. Un fijo se rechaza
email sí —
nationality no ISO 3166-1 alfa-3. Ausente equivale a VEN, y decide qué formato se exige en nationalId

Si mandas el bloque, todos sus campos son obligatorios salvo nationality. Los errores llegan como 400 validation_failed con error.meta.field (p. ej. sender.phone) y error.meta.origen (request, customer o env), que dice cuál de los tres caminos falló.

methodPolicy Comportamiento
preferred (por defecto) Se entrega por el otro instrumento si hace falta, y te lo decimos con methodChanged: true
strict Sólo el instrumento pedido. Si no puede, la dispersión falla y el asiento se revierte
Salió por transferencia habiendo pedido pago móvil
{ "status": "submitted", "method": "transferencia",
"methodRequested": "pago_movil", "methodChanged": true }

Usa strict cuando el instrumento sea parte de lo que le prometiste a tu usuario.

Éstos sí son errores HTTP: la dispersión no llegó a crearse.

error.code HTTP Cuándo
validation_failed 400 Falta beneficiaryId y beneficiary; la cotización no sirve para dispersar; el activo de la cotización no coincide con el del beneficiario; el sender está mal
beneficiary_not_found 404 El beneficiaryId no es tuyo o no existe
beneficiary_blocked 422 El beneficiario está bloqueado
beneficiary_instrument_missing 422 Sin teléfono para pago móvil, o sin cuenta para transferencia
quote_not_found 404
quote_already_consumed 409 Esa cotización ya la usó otra dispersión
quote_expired 422 Pide una nueva
limit_exceeded 422 error.meta dice qué límite y de cuánto
insufficient_tenant_funds 422 Tu saldo no alcanza (sólo si operas prefondeado)
idempotency_key_reused 409 Misma clave, cuerpo distinto
no_provider_available 503 No hay riel para ese país/activo/instrumento

Seguir el pago hasta el desenlace.