Exchange (FX / Conversión de Monedas)

Sistema de cotización y conversión de divisas para obtener tasas en tiempo real y ejecutar movimientos transfronterizos.

Todos los endpoints requieren autenticación con Authorization: Bearer [TOKEN] y x-api-key.


Visión General

¿Qué es Exchange?

El módulo Exchange en Colurs permite:

  • Obtener cotizaciones FX entre pares de monedas
  • Ejecutar movimientos transfronterizos con dispersión automática a cuentas bancarias
  • Calcular tasas de cambio con comisiones personalizadas por usuario

Comportamiento

  • Síncrono: Creación y consulta de cotizaciones (respuesta inmediata)
  • Asíncrono: Ejecución de movimientos transfronterizos (confirmación vía webhook)

Los webhooks notifican los cambios de estado del movimiento: initiated, processing, completed, rejected, failed, returned, canceled.


Monedas Soportadas

Pares disponibles

El sistema soporta 25 pares de monedas en formato origen/destino (ej: usd/cop, cop/usd).

Moneda OrigenMonedas Destino
USDCOP, MXN, PEN, CLP
COPUSD, MXN, PEN, CLP
MXNCOP, USD, PEN, CLP
PENUSD, MXN, COP, CLP
CLPUSD, MXN, PEN, COP

Restricciones

  • Monto mínimo: 50 USD o equivalente en la moneda origen
  • Horarios: Por defecto solo en horario hábil (lunes–viernes). Con off_market: true se permite operar 24/7

Flujo General

Obtener cotización FX

Solicita una cotización con POST /v2/exchange/quotes/. Válida 3 minutos.

(Opcional) Previsualizar

Consulta el detalle con GET /v2/exchange/quotes/{quote_uuid}/ o .../preview/.

Obtener cuenta bancaria

Usa GET /list_third_party_banks/?country=CO (o el país correspondiente) para el destino.

Iniciar movimiento

Ejecuta con POST /v2/exchange/initiate/ usando la cotización y la cuenta bancaria.

Recibir confirmación

El sistema notifica por webhook cuando el movimiento está completed y se realiza la dispersión automática.


Cotizaciones

Solicitar cotización FX

Obtiene una cotización válida por 3 minutos. Solo la cotización más reciente puede usarse para iniciar un movimiento.

Endpoint

POST /v2/exchange/quotes/

Headers

Authorization: Bearer [ACCESS_TOKEN]
Content-Type: application/json
x-api-key: [API_KEY]

Request

CampoTipoRequeridoDescripción
currency_pairstringPar de monedas (ej: usd/cop)
source_amountdecimalCondicionalMonto en moneda origen
destination_amountdecimalCondicionalMonto en moneda destino
typestringstatic_quote (default) o rolling_quote
off_marketbooleanPermitir operación 24/7 (default: false)

Debe enviarse exactamente uno de source_amount o destination_amount.

Respuesta exitosa (201)

201 CREATED
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "cobre_quote_id": "qt_abc123",
  "quote_type": "static_quote",
  "currency_pair": "usd/cop",
  "source_currency": "usd",
  "destination_currency": "cop",
  "source_amount": 100.00,
  "destination_amount": 407731.25,
  "fx_rate": 4077.3125,
  "colurs_fx": 4036.2344,
  "fees_breakdown": {
    "spread": 0.0050
  },
  "status": "pending",
  "is_last_quote": true,
  "off_market": false,
  "is_valid": true,
  "is_expired": false,
  "valid_until": "2026-02-03T10:03:00Z",
  "created_at": "2026-02-03T10:00:00Z"
}
⏱️

La cotización expira en 3 minutos. Solo la más reciente del par puede usarse para iniciar un movimiento.

Errores posibles

CódigoCausa
400Monto mínimo no cumplido ($50 USD o equivalente)
400Ambos source_amount y destination_amount enviados
400Mercado cerrado (fuera de horario y off_market=false)
400Par de monedas no configurado
502Error al procesar la cotización

Obtener cotización por UUID

Consulta los detalles de una cotización por su UUID.

Endpoint

GET /v2/exchange/quotes/{quote_uuid}/

Headers

Authorization: Bearer [ACCESS_TOKEN]
x-api-key: [API_KEY]
Accept: application/json

Respuesta (200)

Mismo formato que la creación de cotización.

Errores

CódigoCausa
404Cotización no encontrada

Listar cotizaciones

Lista las cotizaciones del usuario.

Endpoint

GET /v2/exchange/quotes/list/

Parámetros query

ParámetroTipoDefaultDescripción
include_expiredbooleanfalseIncluir cotizaciones expiradas
limitint10 (max 50)Número de resultados

Respuesta (200)

Array de objetos con el mismo formato que una cotización individual.


Última cotización válida

Obtiene la última cotización válida (no expirada, no usada) para un par.

Endpoint

GET /v2/exchange/quotes/last/?currency_pair=usd/cop

Parámetros query

ParámetroTipoRequeridoDescripción
currency_pairstringPar de monedas (ej: usd/cop)

Respuesta (200)

Objeto de cotización o 404 si no hay cotización válida.


Pares de monedas disponibles

Lista todos los pares de monedas soportados.

Endpoint

GET /v2/exchange/currency-pairs/

Headers

Authorization: Bearer [ACCESS_TOKEN]
x-api-key: [API_KEY]
Accept: application/json

Respuesta (200)

200 OK
{
  "currency_pairs": [
    "usd/cop", "usd/mxn", "usd/pen", "usd/clp",
    "cop/usd", "cop/mxn", "cop/pen", "cop/clp",
    "mxn/cop", "mxn/usd", "mxn/pen", "mxn/clp",
    "pen/usd", "pen/mxn", "pen/cop", "pen/clp",
    "clp/usd", "clp/mxn", "clp/pen", "clp/cop"
  ]
}

Movimientos Transfronterizos

Iniciar movimiento

Crea un movimiento transfronterizo usando una cotización FX válida. Al completarse, el sistema realiza la dispersión automática a la cuenta bancaria indicada.

Endpoint

POST /v2/exchange/initiate/

Headers

Authorization: Bearer [ACCESS_TOKEN]
Content-Type: application/json
x-api-key: [API_KEY]

Request

CampoTipoRequeridoDescripción
quote_idUUIDUUID de la cotización válida
source_account_idstringID de cuenta origen
destination_account_idstringID de cuenta destino
bank_account_idintID de cuenta bancaria del usuario (ThirdPartyBankAccount)
destination_descriptionstringDescripción del movimiento
external_idstringID externo para tracking

Requisitos de la cotización: debe estar vigente, pertenecer al usuario, no haber sido usada y ser la más reciente del par.

Respuesta exitosa (201)

201 CREATED
{
  "sale_crypto_id": "123",
  "quote_id": "456"
}

Errores posibles

CódigoMensaje / Causa
400La cotización ha expirado
400La cotización ya fue utilizada
400Solo se puede usar la cotización más reciente
404Cotización no encontrada
502Error al procesar el movimiento

Ejecutar dispersión manual

Para casos especiales, permite crear una dispersión manual asociada a un movimiento transfronterizo.

Endpoint

POST /v2/exchange/execute/

Headers

Authorization: Bearer [ACCESS_TOKEN]
Content-Type: application/json
x-api-key: [API_KEY]
🔧

Uso interno o casos especiales. El flujo estándar realiza la dispersión automática al completarse el movimiento.


Estados del Movimiento

EstadoDescripción
initiatedMovimiento iniciado
processingEn proceso
completedCompletado → se crea dispersión automática
rejectedRechazado
failedFallido
returnedDevuelto
canceledCancelado

Webhooks

El sistema envía notificaciones de cambio de estado para movimientos transfronterizos. Debes configurar una URL en tu integración para recibir estos eventos.

Eventos soportados

  • initiated — Movimiento iniciado
  • processing — En proceso
  • completed — Completado (dispersión automática)
  • rejected — Rechazado
  • failed — Fallido
  • returned — Devuelto
  • canceled — Cancelado

Seguridad

  • Se verifica la firma del webhook mediante el header correspondiente.
  • Solo se procesan eventos de tipo movimiento transfronterizo.
📡

Configura la URL de webhook y el secreto de firma en tu cuenta Colurs para recibir las notificaciones.