POST /v2/merchant/claimfunds, VelaFi descuenta el saldo y envía el pago por el riel local, y un FUNDING_WEBHOOK te dice si se completó. El mismo saldo también se puede mover a otro de tus comercios con POST /v2/merchant/transfer.
El saldo normalmente proviene de depósitos. Consulta Cobrar pagos locales con cuentas virtuales.
Cómo funciona
Antes de empezar
- Acceso a la API. Una clave de API, la IP de tu servidor en la lista blanca y un token de negocio en el header
X-BH-TOKEN. Consulta Autenticación. - Un comercio verificado con una cuenta de moneda activa en un canal que admita pagos (consulta abajo). Consulta Activar la cuenta de un comercio.
- Saldo en esa cuenta de moneda, proveniente de depósitos en el mismo canal. Consulta Cobrar pagos locales con cuentas virtuales.
- Un endpoint de
FUNDING_WEBHOOKregistrado y que devuelva la confirmación requerida. Consulta Configuración de webhooks.
Canales que admiten pagos desde el saldo
Tres reglas aplican a cada pago:
- Mismo canal. El pago sale por el canal de la cuenta de moneda que tiene el saldo. Solo el saldo que entró por ese canal (o por VelaFi Pending Fund) se puede pagar por él.
- Misma cuenta de moneda del comercio. El beneficiario debe estar guardado bajo el mismo comercio, para la misma moneda y el mismo canal que esa cuenta. Un beneficiario guardado bajo otro comercio, o para otro canal (por ejemplo, un beneficiario de Tesored contra un saldo de Finco Pay), se rechaza.
- Monto más comisión. El saldo debe cubrir
amountmás la comisión del pago.
Paso a paso
1
Guarda el beneficiario
Obtén la plantilla de campos del canal con Guarda el
GET /v2/payments/templates y después guarda el destino con POST /v2/payments bajo el comercio que tiene el saldo. Consulta Administrar beneficiarios para ver las plantillas por canal.cURL
id devuelto: es el userPaymentId para los pagos. Paga solo a beneficiarios con status 1 (válido). Si el número de cuenta ya está guardado, la respuesta tiene status 3 y sameAccountNumberId; usa ese ID en lugar de crear un registro nuevo.2
Revisa el saldo
Lee
balance con GET /v2/merchant/accounts para el comercio, la moneda y el canal. Deja margen para la comisión.3
Crea el pago
Llama a
POST /v2/merchant/claimfunds. Siempre envía tu propio clientId único.cURL
Response
amount es lo que recibe el beneficiario. fee es la comisión de pago configurada para el canal y tu cuenta, y totalAmount (amount + fee) se descuenta del saldo cuando la llamada es exitosa. Los montos se redondean hacia abajo a la precisión de la moneda. Una respuesta 200 significa que el pago fue aceptado, no que ya llegó: está pendiente hasta que el webhook o el registro de fondeo indiquen lo contrario.4
Espera el resultado
Maneja el
FUNDING_WEBHOOK con type WITHDRAW para este txId (consulta Webhooks que debes manejar). Si no recibes ninguno, lee el registro con GET /v2/merchant/funding/records usando txId o clientId.Estados del pago
FUNDING_WEBHOOK se envía para 2, 3 y 4, no para pendiente.
Webhooks que debes manejar
El evento del pago es unFUNDING_WEBHOOK con type WITHDRAW. totalAmount es negativo para los retiros.
FUNDING_WEBHOOK (WITHDRAW, canceled)
- Relaciona el evento con tu pago por
clientIdotxId. - Haz que el handler sea idempotente sobre
eventType+txId+status. El mismo evento puede llegar más de una vez, y un pago puede pasar de2a4más tarde, así que maneja un reembolso después de una finalización. failCodeyfailReasonse envían solo para pagos cancelados que tienen un motivo registrado. Muchas fallas llegan sin motivo; no dependas de ellos para decidir qué hacer.bankOrderIdes la referencia de la transferencia en el proveedor de pagos, cuando está disponible. Guárdala para las solicitudes de soporte.- Devuelve HTTP
200con{"callbackStatus":"SUCCESS"}rápidamente. VelaFi espera como máximo 60 segundos; un timeout o cualquier otra respuesta cuenta como entrega fallida. Consulta Entrega y reintentos.
Maneja las fallas
Errores al crear el pago
Siclaimfunds devuelve un error, no se creó ningún registro de fondeo y no se descontó nada. Códigos comunes (consulta Códigos de error):
Timeouts y reintentos
La validación declientId hace que los reintentos sean seguros siempre que reutilices el mismo clientId:
- Si la llamada excede el tiempo de espera o devuelve un error de red, no crees un nuevo
clientId. Busca el pago conGET /v2/merchant/funding/records?clientId=.... - Si existe un registro, el pago se creó: sigue su estado.
- Si no existe ninguno, envía la misma solicitud otra vez con el mismo
clientId. Si la primera solicitud sí se procesó, recibes-1174en lugar de un segundo pago.
clientId duplicado devuelve el error -1174, no el pago original. Lee el original en los registros de fondeo.
Pagos fallidos
Cuando un pago termina en status3, el totalAmount completo regresa al saldo. Un clientId no se puede reutilizar, ni siquiera para un pago fallido, así que para volver a intentarlo:
- Revisa los datos del beneficiario (número de cuenta, tipo de llave, nombre del titular) y corrige o vuelve a guardar el beneficiario si es necesario.
- Crea un nuevo pago con un
clientIdnuevo, por ejemplopayout-0001-r1, y vincúlalo al original en tu sistema.
failReason, contacta al soporte de VelaFi con el txId y el bankOrderId.
Mueve saldo entre comercios
Para mover saldo de uno de tus comercios a otro sin una transferencia bancaria, usaPOST /v2/merchant/transfer. Ambos comercios deben pertenecer a tu cuenta y tener una cuenta de moneda activa para el mismo fiat y paymentId, en un canal que admita pagos.
1
Revisa la comisión
Llama a
GET /v2/merchant/transfer_fee con fiat. feeType 0 es un monto fijo y 1 es una fracción del monto (0.01 = 1%). La fee que devuelve la transferencia en sí es el monto que realmente se cobra.2
Crea la transferencia
cURL
fiatAmount + comisión de ese canal. La transferencia se completa en la misma llamada: la respuesta devuelve fromId (el registro TRANSFER_OUT del remitente) y toId (el registro TRANSFER_IN del destinatario), ambos con status 2. El destinatario recibe fiatAmount, y al remitente se le descuenta totalFiatAmount.clientId que los pagos: un clientId que ya usa cualquier registro de fondeo de tu cuenta devuelve -1174. Envía siempre uno, para que puedas buscar la transferencia después de un timeout. En los registros de fondeo, el registro TRANSFER_OUT lleva tu clientId; el registro TRANSFER_IN lleva TRANSFER_IN_ seguido de tu clientId. Busca ambos por txId (fromId, toId).
Concilia
GET /v2/merchant/funding/recordses la fuente de verdad de cada pago y transferencia. Filtra portype=WITHDRAW(oTRANSFER_OUT,TRANSFER_IN),fiaty una ventana de tiempo, y verifica que cada pago que creaste tenga un estado final (2,3o4). Investiga los que sigan pendientes.GET /v2/merchant/fiat/flowsmuestra cada movimiento del saldo:WITHDRAWcuando se crea el pago,WITHDRAW_ROLLBACKcuando un pago cancelado o reembolsado se abona de vuelta, yTRANSFER_OUT/TRANSFER_INpara las transferencias. Eltotalde cada línea es el saldo acumulado después de ese movimiento.
Prueba en el sandbox
Usahttps://api-test.velafi.com con credenciales de sandbox. Fondea un comercio de prueba con el simulador de depósitos fiat, guarda un beneficiario y después llama a claimfunds y transfer contra ese saldo. Úsalo para probar la validación de tus solicitudes, los códigos de error de arriba y tu lógica de reintentos con clientId.
- Los webhooks no se disparan en el sandbox. Da seguimiento a cada pago con Listar registros de fondeo, y prueba tu handler de webhooks con payloads de ejemplo, incluidos retiros cancelados (
3) y reembolsados (4). - Los simuladores no pueden producir un depósito fallido o devuelto.
Lista de verificación para salir a producción
- Cada pago y cada transferencia envía un
clientIdúnico que guardas antes de hacer la llamada. - Ante un timeout, buscas el
clientIdantes de reintentar y reenvías con el mismoclientId. - Un pago fallido se reintenta solo con un
clientIdnuevo, después de revisar los datos del beneficiario. - Los beneficiarios se guardan bajo el mismo comercio y el mismo canal que el saldo, y solo se usan beneficiarios con
status1. - La revisión del saldo incluye la comisión.
- El handler de
FUNDING_WEBHOOKmanejaWITHDRAWcon status2,3y4, y funciona cuando faltafailReason. - Un proceso programado marca los pagos que siguen pendientes después de tu tiempo de liquidación esperado.