Saltar al contenido principal

¿Qué es una Cotización?

Una Cotización es una cotización de precio para convertir entre monedas. Bloquea una tasa de cambio por 30 segundos, permitiendo a los usuarios ver exactamente cuánto recibirán antes de comprometerse con una transacción.
Las cotizaciones son necesarias antes de crear cualquier ramp. Aseguran transparencia de precio y protección contra fluctuaciones de tasa.

Cómo Funcionan las Cotizaciones

1

Solicitar Cotización

Especifica monedas, monto y métodos de pago
2

Recibir Tasa

Obtén tasa bloqueada válida por 30 segundos
3

Mostrar al Usuario

Muestra montos exactos que el usuario enviará/recibirá
4

Crear Ramp

Usa el ID de la cotización para ejecutar transacción a la tasa cotizada

Creando una Cotización

POST /api/v2/quotations
Solicitud:
{
  "fromCurrency": "COP",
  "toCurrency": "USDC",
  "amount": 100000,
  "amountIsToCurrency": false,
  "cashInMethod": "PSE",
  "cashOutMethod": "POLYGON"
}
Respuesta:
{
  "id": "quot-9f8e7d6c-5b4a-3c2d-1e0f",
  "fromCurrency": "COP",
  "toCurrency": "USDC",
  "fromAmount": 100000,
  "toAmount": 23.81,
  "rate": 4200.50,
  "spotPrice": 4180.25,
  "expiresAt": 1704657630000,
  "cashInMethod": "PSE",
  "cashOutMethod": "POLYGON"
}
const getQuote = async (fromAmount, fromCurrency = 'COP', toCurrency = 'USDC') => {
  const response = await fetch('https://teste-94u93qnn.uc.gateway.dev/api/v2/quotations', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      fromCurrency,
      toCurrency,
      amount: fromAmount,
      amountIsToCurrency: false,
      cashInMethod: 'PSE',
      cashOutMethod: 'POLYGON'
    })
  });
  
  const quote = await response.json();
  console.log(`Tasa: ${quote.rate}, Recibes: ${quote.toAmount} ${toCurrency}`);
  return quote;
};

Parámetros de la Cotización

Dirección del Monto

El flag amountIsToCurrency determina qué monto es fijo:
Usuario especifica cuánto enviar
{
  "fromCurrency": "COP",
  "toCurrency": "USDC",
  "amount": 100000,
  "amountIsToCurrency": false
}
Resultado: “Envía 100.000 COP, recibe ~23,81 USDC”Usar cuando: Usuario quiere gastar monto exacto de fiat

Tasas de Cambio

Componentes de la Tasa

{
  "rate": 4200.50,
  "spotPrice": 4180.25
}
spotPrice: Tasa de mercado de proveedores de liquidez
rate: Tasa final incluyendo tarifas y margen de KillB
Cálculo:
toAmount = fromAmount / rate
Spread = rate - spotPrice
Fee % = (spread / spotPrice) * 100

Factores de la Tasa

Las tasas de cambio están influenciadas por:
  1. Tasa de Mercado - Precio actual de mercado
  2. Método de Pago - Diferentes métodos tienen costos diferentes
  3. Volumen - Transacciones más grandes pueden obtener mejores tasas
  4. Red - Red blockchain afecta tarifas
  5. Tier del Cliente - Precio negociado de tu cliente
Las cuentas pre-fondeadas típicamente reciben mejores tasas debido a costos operacionales reducidos.

Expiración de la Cotización

Las cotizaciones expiran después de 30 segundos para proteger contra volatilidad del mercado.

Manejando la Expiración

async function createRampWithRetry(quoteId, userId, accountId) {
  try {
    const ramp = await createRamp(quoteId, userId, accountId);
    return ramp;
  } catch (error) {
    if (error.message.includes('expired')) {
      // Obtener nueva cotización
      const newQuote = await getQuotation(/* params */);
      return await createRamp(newQuote.id, userId, accountId);
    }
    throw error;
  }
}

Temporizador de Cuenta Regresiva

Muestra a los usuarios el tiempo restante:
function QuoteTimer({ expiresAt, onExpire }) {
  const [timeLeft, setTimeLeft] = useState(30);
  
  useEffect(() => {
    const interval = setInterval(() => {
      const remaining = Math.max(0, Math.floor((expiresAt - Date.now()) / 1000));
      setTimeLeft(remaining);
      
      if (remaining === 0) {
        onExpire();
      }
    }, 1000);
    
    return () => clearInterval(interval);
  }, [expiresAt]);
  
  return <div>Cotización expira en: {timeLeft}s</div>;
}

Modo de Simulación

Prueba cotizaciones sin crear ramps:
POST /api/v2/quotations/simulation
Mismos parámetros que cotización regular, pero:
  • No se retorna ID de cotización
  • Tasa es solo indicativa
  • No se puede usar para crear ramp
  • Sin expiración
Usar para:
  • Mostrar tasas estimadas
  • Funcionalidad de calculadora
  • Visualización de tasa de mercado
  • Educación del usuario
// Obtener cotización simulada para visualización
const simulatedQuote = await fetch('/api/v2/quotations/simulation', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    fromCurrency: 'COP',
    toCurrency: 'USDC',
    amount: userAmount,
    amountIsToCurrency: false,
    cashInMethod: 'PSE',
    cashOutMethod: 'POLYGON'
  })
}).then(r => r.json());

// Mostrar tasa al usuario
console.log(`Tasa estimada: ${simulatedQuote.rate}`);
console.log(`Recibirías: ${simulatedQuote.toAmount} USDC`);

// Cuando el usuario confirme, obtener cotización real
const realQuote = await getQuotation(/* mismos params */);

Mejores Prácticas de Visualización de Tasa

Mostrar:
- Monto de origen: "100.000 COP"
- Monto de destino: "23,81 USDC"  
- Tasa de cambio: "1 USDC = 4.200,50 COP"
- Información de tarifa: "Incluye tarifa de 0,5%"
"Esta tasa expira en 28 segundos"

- Mostrar cuenta regresiva visual
- Avisar en 10 segundos restantes
- Auto-actualizar en expiración
// Auto-actualizar cotizaciones periódicamente
setInterval(async () => {
  const newQuote = await getQuotation(amount);
  updateDisplay(newQuote);
}, 5000); // Cada 5 segundos
Mostrar:
- "Tasa: 1 USDC = 4.200,50 COP"
- "Tasa de mercado: 4.180,25 COP"
- "Spread: 0,48%"
- "Última actualización: hace 2 segundos"

Próximos Pasos