Saltar al contenido principal
Esta receta paga fiat a un tercero, como un proveedor, un vendedor o uno de tus usuarios, y fondea el pago con stablecoins. Depositas USDT o USDC en la billetera de VelaFi del comercio, registras la cuenta bancaria del destinatario como beneficiario y creas una orden crypto_to_fiat para cada pago. VelaFi convierte la cripto al tipo de cambio cotizado y envía el fiat por el riel local (por ejemplo, SPEI, Pix, CVU, Bre-B) o por Circle Payment Network (CPN) para USD y EUR. Para la referencia completa de campos, consulta la guía Off-ramp (cripto a fiat) y Crear una orden de off-ramp.

Cómo funciona

Antes de empezar

  • Acceso a la API. Una clave de API, las IP de tus servidores en la lista blanca y un token de negocio para el header X-BH-TOKEN. Consulta Autenticación.
  • Un comercio verificado con una cuenta activada para la moneda y el canal del pago. El beneficiario debe usar un método de pago (paymentId) de esa cuenta. Consulta Activar la cuenta de un comercio.
  • ORDER_WEBHOOK registrado. Tu endpoint debe devolver HTTP 2xx con el cuerpo {"callbackStatus":"SUCCESS"}; de lo contrario, la entrega cuenta como fallida. Consulta Webhooks y Entrega y reintentos.

Construye el flujo

1

Fondea la billetera cripto del comercio

Obtén la dirección de depósito del comercio para el token y la red que vas a enviar:
Envía la cripto a address (con addressExt si needAddressTag es true), por al menos minQuantity. Consulta Obtener la dirección de depósito cripto para ver los pares de token y red admitidos.No hay webhook para los depósitos de cripto entrantes. Confirma el abono con Listar depósitos cripto (status 2 es exitoso) y revisa el monto disponible para gastar en free con Obtener el saldo cripto.
2

Registra el beneficiario

Obtén la plantilla de campos del método de pago con GET /v2/payments/templates?paymentId={paymentId} y después envía los campos completados con POST /v2/payments. Usa el mismo merchantId que en tus órdenes.
Response
Guarda data.id. Es el userPaymentId para tus órdenes. Solo un beneficiario en status 1 (válido) puede recibir pagos. 2 significa que la verificación sigue en curso. 3 significa que falló: lee failReason y, si la cuenta ya existe, usa sameAccountNumberId en lugar de crear un registro nuevo. Registra un beneficiario una sola vez y reutilízalo. Consulta Administrar beneficiarios.
3

Opcional: fija el tipo de cambio con una cotización

Llama a Obtener una cotización cripto/fiat con from igual a la cripto, to igual al fiat y createQuoteId=true. El price está expresado en fiat por 1 unidad de cripto.
Un quoteId es válido durante 10 segundos en producción (300 segundos en el sandbox), es de un solo uso y está vinculado al country, la cripto y el fiat para los que se emitió. Sin un quoteId, la orden se cotiza al momento de crearse.
4

Crea la orden de pago

Llama a POST /v2/order/crypto_to_fiat con el userPaymentId del beneficiario. Usa el country y el fiat del beneficiario. Envía fiatAmount para fijar lo que recibe el beneficiario, o cryptoAmount para fijar lo que gastas. Si envías ambos, prevalece fiatAmount. Envía siempre un clientId único.
Response
Cómo se fondea la orden. La cripto proviene del saldo de la billetera del comercio para esa crypto. VelaFi la descuenta cuando crea la orden, y la orden pasa a 40 (o primero a 10, 11 o 31 cuando se requiere revisión o documentos). Si el saldo es demasiado bajo, la solicitud se rechaza con un error de saldo insuficiente y no se crea ninguna orden.Variante con fondeo posterior. Si VelaFi habilitó el off-ramp con fondeo posterior para tu cuenta (puede variar según la moneda fiat), una orden sin fondos suficientes se acepta y espera en 32 (En espera de depósito cripto). El detalle de la orden devuelve entonces orderExpireTimestamp, la fecha límite en segundos Unix. Deposita suficiente cripto en la billetera antes de la fecha límite. VelaFi revisa el saldo cada minuto, lo aplica a las órdenes en espera empezando por la más antigua y mueve una orden cubierta a 40. Si primero pasa la fecha límite, la orden se cancela (70). Consulta Fondeo de la orden.Si la solicitud excede el tiempo de espera, busca la orden por clientId antes de reintentar. Consulta Idempotencia y reintentos.
5

Da seguimiento al pago hasta que se complete

Espera los eventos ORDER_WEBHOOK (orderType es SELL) o consulta periódicamente GET /v2/order/detail?orderType=crypto_to_fiat&clientId={clientId}.traceNumber contiene el número de referencia del banco central para el pago cuando el riel devuelve uno. Compártelo con el beneficiario si pide un comprobante de pago.

Pagos en USD y EUR mediante Circle Payment Network

CPN transporta pagos en USD y EUR. Es solo para pagos: no puedes cobrar fondos ni crear órdenes fiat_to_crypto en CPN.
  1. Activa una cuenta CPN para el comercio y la moneda con trench establecido en Circle Payment Network. Consulta Activar la cuenta de un comercio empresa.
  2. Registra el beneficiario en un método de pago de CPN, por ejemplo 120 Wire (CPN) o 127 FEDWIRE (CPN) para USD y 124 SEPA (CPN) para EUR. Las plantillas de CPN piden la dirección del beneficiario, un useCase y un código reasonForPayment. Consulta las plantillas de CPN en Obtener plantillas de métodos de pago.
  3. Crea la orden crypto_to_fiat con fiat establecido en USD o EUR y el userPaymentId del beneficiario de CPN, exactamente como se describe arriba.
Como cualquier pago, una orden de CPN puede pasar a revisión de riesgos (11). Cuando eso ocurre, sube los documentos solicitados con Subir documentos de una orden. Después, la orden pasa a 12 y espera una decisión.

Webhooks que debes manejar

ORDER_WEBHOOK se envía solo para órdenes creadas mediante la API. No envía 71 (Cancelando) ni 73 (Reembolsando), y las órdenes rechazadas en revisión o en revisión de riesgos se envían como 70. Los eventos pueden llegar más de una vez y fuera de orden, y se pueden omitir estados intermedios. Elimina duplicados sobre orderId + orderStatus, y lee la orden con GET /v2/order/detail cuando un evento no coincida con el estado que tienes.

Maneja las fallas

failReason con frecuencia está vacío, porque muchos rieles no devuelven ningún motivo. Trata un failReason vacío como “desconocido”, no como éxito. Para evitar pagar dos veces, crea un pago de reemplazo solo después de que la orden original sea final (70 o 72).

Concilia

  • Cada pago: Obtener una orden por orderId o clientId es la fuente de verdad: orderStatus, cryptoAmount (descontado de la billetera), fiatAmount (pagado al beneficiario), fiatFee, orderPrice, orderFeeDetail, traceNumber, failCode y failReason.
  • Totales diarios: Listar órdenes con orderType=crypto_to_fiat y un rango de tiempo. También lista órdenes que no se crearon mediante la API.
  • Billetera: Listar depósitos cripto para las recargas, y Obtener el saldo cripto para free y locked.
Ejecuta un proceso programado que vuelva a leer cada pago que siga abierto de tu lado, y marca las órdenes que permanezcan en 40 o 50 más allá de tu tiempo normal de pago. Los webhooks se pueden perder después de tres intentos de entrega fallidos.

Prueba en el sandbox

  • Usa https://api-test.velafi.com. Los webhooks no se envían en el sandbox, así que consulta periódicamente GET /v2/order/detail.
  • Agrega USDT o USDC de prueba a la billetera de un comercio con el simulador de depósitos de cripto. Consulta Herramientas de prueba del sandbox.
  • Algunos IDs de métodos de pago son distintos en el sandbox; por ejemplo, CBU/CVU (Momentum) es 18 en lugar de 63. Consulta Métodos de pago.
  • Los simuladores solo producen depósitos exitosos. No puedes simular un pago rebotado, así que prueba tu manejo de 70 y 72 con payloads grabados.

Lista de verificación para salir a producción

  • La billetera está fondeada antes de crear las órdenes, o el off-ramp con fondeo posterior está habilitado y tu sistema fondea las órdenes en 32 antes de orderExpireTimestamp.
  • Los beneficiarios se registran una sola vez, se guardan por userPaymentId y solo se usan cuando status es 1.
  • Cada solicitud de creación envía un clientId único, y los timeouts se resuelven buscando el clientId antes de reintentar.
  • El endpoint de ORDER_WEBHOOK verifica la firma, devuelve {"callbackStatus":"SUCCESS"} con HTTP 2xx y elimina duplicados sobre orderId + orderStatus.
  • 70 y 72 (incluido 72 después de 60) liberan o revierten el pago de tu lado, y un reemplazo solo se crea después de que el original sea final.
  • Las órdenes atoradas en 40 o 50 se marcan y se escalan con el orderId.
  • Para USD y EUR, la cuenta CPN está activada y los beneficiarios de CPN incluyen los campos de cumplimiento requeridos.
Consulta la lista de verificación para salir a producción completa.