Inyo

Cotizaciones (FX)

La API de Cotizaciones FX te permite solicitar y fijar tasas de cambio para un corredor de divisas y un monto específicos. El quoteId devuelto garantiza la tasa durante una ventana fija, protegiéndote a ti y a tu cliente de las fluctuaciones cambiarias durante el flujo de la transacción.


Cómo Funciona el Pricing

Dos componentes determinan el costo para el usuario final:

  • Spread FX — Tu margen sobre la tasa de cambio, configurado por corredor por Inyo durante el onboarding. Según tu contrato, también puedes sobrescribir el spread por cotización — como porcentaje o como monto fijo. Ver Ajustes de Spread.
  • Comisión por Transacción — Una comisión por transacción, también configurada durante el onboarding. Según tu contrato, es posible que puedas sobrescribir las comisiones a nivel de cotización (p. ej., para ofertas promocionales de "cero comisión").

Tanto el spread como la comisión configurados pueden sobrescribirse en una solicitud de cotización individual. Si no envías una sobrescritura, se aplican los valores configurados del corredor.

Tipos de Monto

Al solicitar una cotización, el campo amountType controla cómo se aplican las comisiones:

TipoComportamientoEjemplo (comisión = $4, monto = $100)
NETLa comisión se agrega sobre el monto. Se convierte el monto completo.El remitente paga $104. $100 se convierten a la moneda de destino.
GROSSLa comisión se deduce del monto. Solo se convierte el remanente.El remitente paga $100. $96 se convierten a la moneda de destino.

Solicitar una Cotización

Endpoint: POST /organizations/{tenant}/payout/quotes
Autenticación: Nivel de agente (x-api-key + x-agent-id + x-agent-api-key)

Cuerpo de la Solicitud

CampoTipoRequeridoDescripción
fromCurrencystringSíMoneda de origen (ISO 4217), p. ej., USD
toCurrencystringSíMoneda de destino (ISO 4217), p. ej., BRL
toCountrystringNoPaís de destino (ISO 3166-1 alpha-2) — desambigua cuando una moneda se usa en múltiples corredores
amountnumberSíMonto a convertir (debe ser > 0)
amountTypestringNoGROSS o NET (ver arriba). Por defecto es NET.
spreadobjectNoSobrescribe el spread FX configurado para esta cotización (ver Ajustes de Spread)
spread.ratenumber—Monto del spread, 0–1. Para PERCENTAGE es una fracción (p. ej. 0.02 = 2%); para FIXED es un monto absoluto que se resta de la tasa
spread.typestring—PERCENTAGE (por defecto) o FIXED
spreadRatenumberNoAtajo heredado para una sobrescritura de spread PERCENTAGE, 0–1. Prefiere el objeto spread; se ignora si se envía spread.rate
feeobjectNoSobrescribe la comisión por defecto (si tu contrato lo permite)
fee.amountnumber—Monto de la comisión
fee.currencystring—Moneda de la comisión (normalmente coincide con fromCurrency)

Solicitud de Ejemplo

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/quotes \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "fromCurrency": "USD",
  "toCurrency": "BRL",
  "amount": 1000,
  "fee": {
    "amount": 4.99,
    "currency": "USD"
  },
  "amountType": "NET"
}'

Respuesta de Ejemplo

{
  "quotes": [
    {
      "id": "f28be3f9-ad4d-4a6c-a85d-ae5515a4a158",
      "agentId": "8500786a-68e9-45fd-b1d8-c590f1e06450",
      "fromAsset": "USD",
      "toAsset": "BRL",
      "effectiveRate": 5.39023,
      "totalCost": {
        "amount": 1004.99,
        "currency": "USD"
      },
      "fee": {
        "amount": 4.99,
        "currency": "USD"
      },
      "amountType": "NET",
      "product": "REMITTANCE",
      "expireAt": "2025-09-15T12:07:01Z",
      "createdAt": "2025-09-15T11:37:01Z",
      "sourceAmount": {
        "amount": 1000.00,
        "currency": "USD"
      },
      "destinationAmount": {
        "amount": 5390.23,
        "currency": "BRL"
      }
    }
  ]
}

Campos de la Respuesta

CampoDescripción
idIdentificador único de la cotización. Guárdalo — es requerido para la transacción.
fromAsset / toAssetMonedas de origen y destino
effectiveRateLa tasa FX aplicada a esta conversión (incluye tu spread)
sourceAmountEl monto convertido, en la moneda de origen
destinationAmountEl monto que recibirá el destinatario
totalCostTotal que paga el remitente, en la moneda de origen (monto + comisión para cotizaciones NET)
feeLa comisión por transacción aplicada a esta cotización
amountTypeNET o GROSS — cómo se aplicó la comisión
productProducto de la cotización — REMITTANCE
expireAtTimestamp ISO 8601 en que la cotización deja de ser válida
createdAtTimestamp ISO 8601 en que se generó la cotización

Ajustes de Spread

Tu corredor tiene un spread FX configurado, pero si tu contrato lo permite puedes sobrescribirlo en una cotización individual — útil para tasas promocionales, pricing específico por socio o acuerdos puntuales negociados. La sobrescritura solo afecta la cotización en la que la envías; no cambia la configuración de tu corredor.

Hay dos tipos de spread:

TipoFórmulaSignificado
PERCENTAGEeffectiveRate = baseRate × (1 − rate)rate es una fracción 0–1. 0.02 recorta un 2% de la tasa mid-market. El tipo por defecto.
FIXEDeffectiveRate = baseRate − raterate es un monto absoluto que se resta directamente de la tasa (con piso en 0).

Envía la sobrescritura como un objeto spread:

# Spread porcentual — 2.5% de margen en esta cotización
curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/quotes \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "fromCurrency": "USD",
  "toCurrency": "BRL",
  "amount": 1000,
  "spread": { "rate": 0.025, "type": "PERCENTAGE" }
}'
# Spread fijo — resta 0.08 de la tasa en esta cotización
curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/payout/quotes \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "fromCurrency": "USD",
  "toCurrency": "BRL",
  "amount": 1000,
  "spread": { "rate": 0.08, "type": "FIXED" }
}'

Precedencia — la API resuelve el spread en este orden:

  1. El objeto spread (spread.rate + spread.type), si está presente.
  2. Si no, spreadRate — un atajo heredado que siempre significa una sobrescritura PERCENTAGE.
  3. Si no, el spread configurado del corredor.

spreadRate y el objeto spread son mutuamente excluyentes en la práctica — si envías spread.rate, se ignora spreadRate. Usa el objeto spread para integraciones nuevas; es la única forma de solicitar un spread FIXED.

Sobrescribir la Comisión

La comisión por transacción es una sobrescritura separada e independiente — envía un objeto fee con un amount (y currency opcional). Se aplica sobre cualquier spread vigente, y un fee.amount de 0 es la forma de emitir una cotización promocional sin comisión.


Ejemplo Detallado de Conversión

Escenario: Convertir 1,000 USD → BRL

CampoValor
Moneda de OrigenUSD
Moneda de DestinoBRL
Monto de Origen1,000.00 USD
Tasa Efectiva5.39023000
Monto de Destino5,390.23 BRL
Comisión4.99 USD
Costo Total1,004.99 USD
ProductoREMITTANCE
Validez de la Cotización30 minutos (por defecto)

Consultar una Cotización

Endpoint: GET /organizations/{tenant}/payout/quotes/{quoteId}
Autenticación: Nivel de agente

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/payout/quotes/$QUOTE_ID \
  --header "x-api-key: $API_KEY" \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY"

Usa esto para verificar si una cotización sigue siendo válida antes de enviar una transacción.


Manejo de la Expiración de Cotizaciones

Las cotizaciones son válidas por 30 minutos por defecto. La ventana es configurable por tenant (hasta 24 horas) — verifica expireAt en lugar de asumir una duración. Sigue estas pautas:

  • Siempre verifica expireAt antes de usar una cotización en una transacción.
  • Renueva proactivamente — solicita una nueva cotización cuando haya transcurrido ~90% del período de validez.
  • Nunca almacenes cotizaciones en caché — a diferencia de los destinos y las listas de bancos, las cotizaciones son sensibles al tiempo y deben obtenerse frescas.
  • Las cotizaciones expiradas serán rechazadas — si envías una transacción con un quoteId expirado, la API devuelve un error 400 o 422.

Patrón de UX Recomendado

1. User selects amount and destination  →  Request quote
2. Display rate, fees, and receive amount
3. Start a countdown timer based on expireAt
4. If timer reaches ~80%, show "Rate expiring" warning
5. If expired, auto-refresh and update the display
6. On "Confirm", immediately submit the transaction with the quoteId

Todos los Endpoints

OperaciónMétodoEndpoint
Solicitar cotizaciónPOST/organizations/{tenant}/payout/quotes
Obtener cotización por IDGET/organizations/{tenant}/payout/quotes/{quoteId}