Comportamiento de FX y Bloqueo de Tasa
Cashela proporciona tipos de cambio (FX) transparentes para todas las transacciones en múltiples monedas. Esta guía explica cómo se calculan, bloquean y aplican las tasas.
Descripción General
Al procesar pagos en múltiples monedas, Cashela:
- Cotiza tasas en tiempo real de mercados FX mayoristas
- Aplica spreads transparentes revelados en cada cotización
- Bloquea las tasas por un período definido (típicamente 1 hora)
- Revela todas las comisiones por adelantado antes de confirmar la transacción
Cálculo del Tipo de Cambio
Componentes de la Tasa
| Componente | Descripción |
|---|---|
wholesale_fx_rate | Tasa base del mercado de proveedores FX mayoristas |
applied_spread | Porcentaje de spread de Cashela (revelado) |
final_rate | Tasa aplicada a la transacción (mayorista + spread) |
Ejemplo de Cálculo
Origen: 1,000 USDDestino: BRL
Tasa Mayorista: 5.4200Spread Aplicado: 0.5%Tasa Final: 5.4200 × (1 - 0.005) = 5.3929
Monto Destino: 1,000 × 5.3929 = 5,392.90 BRLBloqueo de Tasa
Cómo Funciona
- Solicita una cotización – Recibe tasa bloqueada válida por un período específico
- Revisa los términos – Muestra la tasa y comisiones a tu usuario
- Ejecuta dentro de la validez – Crea la transacción antes de la expiración
- Tasa garantizada – La transacción usa la tasa bloqueada sin importar movimientos del mercado
Respuesta de Cotización
{ "success": true, "data": { "id": "qtn_01HJ3KBCD8E9F0G1H2I3J4K5L6", "source": { "amount": 1000.00, "currency": "USD" }, "destination": { "amount": 5392.90, "currency": "BRL" }, "fx_rate": { "wholesale_rate": 5.4200, "applied_rate": 5.3929, "spread_percentage": 0.50 }, "fee": { "amount": 5.00, "currency": "USD" }, "total_cost": { "amount": 1005.00, "currency": "USD" }, "expiration_date": "2024-01-15T11:30:00.000Z", "valid_for_seconds": 3600 }}Duración del Bloqueo
| Producto | Duración Típica del Bloqueo |
|---|---|
| Pay-In | Un depósito conserva la cotización con la que se creó hasta que se paga o vence su ventana de pago (validity_period). Las tasas de Obtener tasas de cambio son indicativas y no quedan fijadas. |
| Cotización Pay-Out | 30 minutos. Ver Bloqueo de tasa en la cotización. |
Estructura de Comisiones
Tipos de Comisiones
| Tipo de Comisión | Descripción |
|---|---|
transaction_fee | Comisión fija o porcentual por transacción |
fx_spread | Incluido en el tipo de cambio |
network_fee | Comisiones de redes de pago (si aplica) |
Mostrar Comisiones
Siempre muestra las comisiones claramente a tus usuarios:
function displayPricingBreakdown(quotation) { const breakdown = { montoOrigen: `${quotation.source.amount} ${quotation.source.currency}`, tipoCambio: `1 ${quotation.source.currency} = ${quotation.fx_rate.applied_rate} ${quotation.destination.currency}`, comisionTransaccion: `${quotation.fee.amount} ${quotation.fee.currency}`, costoTotal: `${quotation.total_cost.amount} ${quotation.total_cost.currency}`, montoDestino: `${quotation.destination.amount} ${quotation.destination.currency}`, tasaBloqueadaHasta: new Date(quotation.expiration_date).toLocaleString() };
return breakdown;}Manejo de Expiración de Tasa
Verificar Antes de la Transacción
async function createTransactionSafely(quotationId, transactionData) { // 1. Obtener estado actual de la cotización const quotation = await api.getQuotation(quotationId);
// 2. Verificar si expiró const expiresAt = new Date(quotation.expiration_date); const now = new Date();
if (now >= expiresAt) { // Tasa expirada - necesita nueva cotización throw new QuotationExpiredError('El bloqueo de tasa ha expirado. Por favor obtén una nueva cotización.'); }
// 3. Advertir si expira pronto (dentro de 5 minutos) const minutesRemaining = (expiresAt - now) / (1000 * 60); if (minutesRemaining < 5) { console.warn('Cotización expirando pronto:', minutesRemaining.toFixed(1), 'minutos'); }
// 4. Crear transacción return await api.createTransaction({ quotation_id: quotationId, ...transactionData });}Buenas Prácticas
1. Siempre Muestra Tasas Bloqueadas
Muestra la tasa bloqueada y el tiempo de expiración a los usuarios:
<div class="rate-lock-info"> <p>Tipo de Cambio: 1 USD = 5.3929 BRL</p> <p>Tasa bloqueada hasta: 11:30 AM (en 45 minutos)</p> <p class="warning" id="expiry-warning" style="display:none;"> ⚠️ La tasa expira pronto. Completa tu transferencia ahora. </p></div>2. Maneja Cambios de Tasa con Gracia
Cuando una cotización expira durante el flujo:
try { await createTransaction(quotationId, data);} catch (error) { if (error.code === 'QUOTATION_EXPIRED') { // Obtener nueva cotización y mostrar tasa actualizada const newQuotation = await createQuotation(params);
if (hasRateChangedSignificantly(oldQuotation, newQuotation)) { // Pedir confirmación al usuario de la nueva tasa const confirmed = await showRateChangeConfirmation(oldQuotation, newQuotation); if (!confirmed) { throw new UserCancelledError(); } }
// Reintentar con nueva cotización await createTransaction(newQuotation.id, data); }}3. Registra Información de Tasas
Mantén registros para conciliación y cumplimiento:
await db.transactionLogs.create({ transactionId: transaction.id, quotationId: quotation.id, wholesaleRate: quotation.fx_rate.wholesale_rate, appliedRate: quotation.fx_rate.applied_rate, spreadPercentage: quotation.fx_rate.spread_percentage, sourceAmount: quotation.source.amount, destinationAmount: quotation.destination.amount, fee: quotation.fee.amount, timestamp: new Date()});Documentación Relacionada
- PayOut → Crear Cotización – Bloquear tasas para payouts
- PayIn → Obtener Tipos de Cambio – Tipos de cambio actuales
- Manejo de Errores – Manejo de errores de expiración de cotización