Todo equipo financiero multinacional acaba topándose con el mismo muro: el ERP necesita un tipo de cambio para cada transacción en moneda extranjera, todos los días, para cada par de divisas que la empresa maneja, y alguien todavía los está escribiendo a mano. Una integración de API de tipos de cambio para ERP resuelve esto convirtiendo la carga diaria de tasas en un trabajo programado que se ejecuta antes de que el equipo de contabilidad inicie sesión. Esta guía explica cómo NetSuite, SAP S/4HANA y Microsoft Dynamics 365 Finance consumen las tasas cada uno, cómo construir un único pipeline de tasas que alimente a los tres, y los casos límite que corrompen silenciosamente el cierre de fin de mes si no se manejan bien.
Por qué los sistemas ERP necesitan un feed de tasas externo
Todo ERP con multidivisa habilitada almacena su propia tabla de tipos de cambio. NetSuite tiene la lista Currency Exchange Rates, SAP tiene la tabla TCURR (mantenida a través de la transacción OB08), y Dynamics 365 Finance tiene la página Currency exchange rates. Nada en tu libro mayor (GL) lee un feed de mercado directamente: los asientos leen esa tabla interna.
Ese diseño es deliberado y es el correcto. Los asientos financieros deben ser reproducibles: si un auditor vuelve a ejecutar un asiento contable de marzo, este debe generar el mismo número que generó en marzo. Una tabla de tasas fechadas e inmutables te da eso. Una llamada en vivo al mercado, no.
El problema es cómo se llena esa tabla. En la práctica, los tres enfoques habituales son:
- Entrada manual. Alguien abre el sitio del BCE o de un banco, copia las tasas y las teclea. Esto es lento, propenso a errores e imposible de auditar correctamente: no queda registro de de dónde salió el número.
- El proveedor integrado del ERP. NetSuite, SAP y Dynamics vienen con algún tipo de feed integrado. Funcionan, pero obtienes la cobertura de divisas, la fuente de tasas y el calendario de actualización que eligió el proveedor, y son difíciles de reconciliar con otros sistemas.
- Una API de divisas dedicada que alimenta un trabajo programado. Controlas la fuente, el momento, la lista de divisas y el rastro de auditoría, y el mismo feed puede alimentar simultáneamente tu plataforma de facturación, tu almacén de datos y tu ERP.
La opción 3 es lo que construye esta guía. La ventaja decisiva es la consistencia entre sistemas: si tu facturación de Stripe, tus dashboards de BI y tu ERP toman datos de la misma instantánea, tu conciliación de ingresos deja de generar variaciones cambiarias inexplicables.
Requisitos de un feed de tasas apto para ERP
No toda API de divisas es apta para contabilidad. Los feeds orientados al trading optimizan la latencia; los feeds para ERP optimizan la reproducibilidad. Esto es lo que realmente importa.
Instantáneas diarias, no datos tick a tick
Tu GL no necesita tasas al milisegundo. Necesita una tasa autorizada por par de divisas y por día, tomada en un momento consistente y aplicada de forma consistente. Un feed que te da un número ligeramente distinto según el segundo exacto en que lo consultaste es un pasivo, no una ventaja. Lo que quieres es un valor de cierre diario estable que puedas volver a consultar y obtener siempre la misma respuesta.
Endpoint histórico con relleno retroactivo completo
Necesitarás tasas históricas constantemente: para rellenar datos tras una interrupción, para revaluar saldos de periodos anteriores, para corregir un asiento con fecha de hace tres semanas y para satisfacer solicitudes de auditoría. Una API de tipos de cambio históricos que se remonte años atrás no es negociable. Si tu proveedor solo ofrece el "último" valor, has comprado un juguete.
Amplia cobertura de divisas, incluidos los pares poco líquidos
Los pares principales son fáciles. Los pares que rompen las cargas del ERP son aquellos en los que factura tu filial de Nairobi o tu proveedor vietnamita. Comprueba que tu proveedor cubra la cola larga —Finexly cubre más de 170 divisas— antes de descubrir el hueco durante el cierre.
Redondeo determinista y documentado
Los ERP almacenan las tasas con una precisión fija, y cada uno es distinta. Los errores de precisión en las tasas se acumulan a lo largo de miles de asientos. Decide tu regla de redondeo una sola vez, documéntala y aplícala de forma idéntica en todas partes — nuestra guía sobre redondeo de divisas y decimales cubre las trampas en detalle.
Un rastro de auditoría que te pertenece
Para cada tasa cargada querrás registrar: fuente, divisa base y divisa cotizada, tasa, fecha de vigencia, marca de tiempo de la consulta y el ID de ejecución del trabajo. Los auditores preguntan "¿de dónde salió esto?" y "¿quién pudo haberlo modificado?" — y una respuesta como "el proveedor integrado del ERP, creemos" es débil. Esto importa aún más en el caso de los tipos de cambio en la declaración de impuestos, donde las autoridades a menudo exigen tasas de una fuente específica aplicadas de forma consistente durante un periodo.
Cómo consume las tasas cada ERP
El pipeline es compartido; solo el paso final de entrega difiere según el sistema.
NetSuite
NetSuite ofrece tres rutas. La función integrada Currency Exchange Rate Integration (habilitada en Setup > Company > Enable Features) actualiza automáticamente las tasas una vez al día desde un proveedor integrado. El Import Assistant admite un CSV con tipos de cambio. Y SuiteScript puede escribir registros de tasas directamente, que es la ruta a seguir si quieres tu propia fuente y tu propio calendario.
Un script programado de SuiteScript 2.x que consulta tu API y crea registros currencyrate te da control total:
/**
* @NApiVersion 2.1
* @NScriptType ScheduledScript
*/
define(['N/https', 'N/record', 'N/runtime'], (https, record, runtime) => {
const fetchRates = (base, symbols) => {
const res = https.get({
url: `https://api.finexly.com/v1/latest?base=${base}&symbols=${symbols.join(',')}`,
headers: { Authorization: `Bearer ${runtime.getCurrentScript().getParameter({ name: 'custscript_fx_key' })}` }
});
if (res.code !== 200) throw Error(`Finexly returned ${res.code}`);
return JSON.parse(res.body);
};
const execute = () => {
const base = 'USD';
const symbols = ['EUR', 'GBP', 'JPY', 'CAD', 'AUD', 'CHF', 'SEK', 'MXN'];
const payload = fetchRates(base, symbols);
Object.entries(payload.rates).forEach(([quote, rate]) => {
const rec = record.create({ type: 'currencyrate' });
rec.setValue({ fieldId: 'basecurrency', value: currencyIdFor(base) });
rec.setValue({ fieldId: 'transactioncurrency', value: currencyIdFor(quote) });
rec.setValue({ fieldId: 'effectivedate', value: new Date(payload.date) });
rec.setValue({ fieldId: 'exchangerate', value: rate });
rec.save();
});
};
return { execute };
});Presta mucha atención a la dirección. El campo exchangerate de NetSuite espera la tasa expresada como unidades de divisa base por unidad de divisa de transacción en algunos contextos, y la inversa en otros, según la configuración de tu subsidiaria. Carga un par manualmente, comprueba qué produce el GL y ajusta esa dirección — esta es la causa más común de una carga de tasas que se ejecuta sin errores pero contabiliza al revés.
SAP S/4HANA y ECC
SAP almacena las tasas en TCURR y ofrece varias vías de carga. La transacción OB08 mantiene las tasas manualmente. La transacción TBD4 es la ruta estándar para actualizaciones automatizadas desde un proveedor de datos de mercado. BAPI_EXCHANGERATE_CREATE escribe tasas de forma programática, que es lo que usan la mayoría de las integraciones personalizadas. Algunos equipos, en cambio, generan el archivo de datos de mercado que espera la importación estándar de SAP y lo depositan en el servidor de aplicaciones para un trabajo programado.
Dos conceptos específicos de SAP que hay que respetar:
- Tipos de tasa de cambio. SAP distingue entre
M(conversión estándar, usada en la mayoría de los asientos),B(compra del banco),G(venta del banco), y a menudo tipos personalizados para tasas de planificación o presupuesto. Cargar soloMsuele ser el punto de partida correcto; confirma con el equipo de FI qué tipos están realmente configurados en tu instancia. - Factores de tasa.
TCURFcontiene los factores de origen/destino de un par. Para divisas con ratios numéricos grandes (JPY, KRW, IDR, VND frente a EUR o USD), el factor suele ser 1:100 o 1:1000. Si cargas una tasa bruta sin fijar el factor correspondiente, tus importes quedan desviados en dos o tres órdenes de magnitud, y, lo que es peor, parecen lo bastante plausibles como para sobrevivir a una revisión rápida.
Un patrón habitual es generar un archivo de carga a partir de tu API y dejar que un trabajo ABAP programado lo consuma:
import csv
from datetime import date
import requests
API = "https://api.finexly.com/v1/latest"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
BASE = "EUR"
SYMBOLS = ["USD", "GBP", "JPY", "CHF", "PLN", "CZK", "SEK", "NOK"]
RATE_TYPE = "M"
def build_tcurr_load(target: date, path: str) -> None:
r = requests.get(API, headers=HEADERS,
params={"base": BASE, "symbols": ",".join(SYMBOLS)}, timeout=15)
r.raise_for_status()
payload = r.json()
with open(path, "w", newline="") as fh:
w = csv.writer(fh, delimiter=";")
for quote, rate in payload["rates"].items():
# SAP expects the rate at the precision configured for the pair;
# 5 decimals is a safe default for majors.
w.writerow([RATE_TYPE, BASE, quote,
target.strftime("%Y%m%d"), f"{rate:.5f}"])
build_tcurr_load(date.today(), "/interface/fx/tcurr_load.csv")Microsoft Dynamics 365 Finance
Dynamics 365 Finance incluye un framework de exchange rate provider y una tarea periódica, Import currency exchange rates, que consulta a un proveedor configurado según un calendario. De fábrica obtienes un puñado de proveedores de bancos centrales. El framework es extensible: puedes implementar un proveedor personalizado en X++ para que tu propia API se convierta en una opción de primera clase dentro de la misma interfaz que ya usa el equipo de finanzas.
Si prefieres no escribir X++, la alternativa pragmática es enviar las tasas a través del Data Management Framework usando la entidad de datos de exchange rate, impulsada por una Azure Function o una Logic App con temporizador. Eso mantiene la integración en un lenguaje que tu equipo ya domina y evita un despliegue de código por cada cambio de calendario.
Construcción del pipeline
Sea cual sea el destino, la forma del trabajo es la misma. Consultar una vez, transformar según el ERP, cargar, verificar.
Paso 1: Consultar una instantánea
Obtén una única instantánea al día y trátala como la fuente de verdad para todos los sistemas posteriores:
curl "https://api.finexly.com/v1/latest?base=USD&symbols=EUR,GBP,JPY,CAD,AUD,CHF" \
-H "Authorization: Bearer YOUR_API_KEY"{
"base": "USD",
"date": "2026-09-03",
"rates": {
"EUR": 0.8631,
"GBP": 0.7402,
"JPY": 151.28,
"CAD": 1.3574,
"AUD": 1.4938,
"CHF": 0.8025
}
}Guarda esa respuesta en bruto, tal cual, antes de transformar nada. Cuando un controller pregunte en noviembre por qué la tasa de septiembre era la que era, el payload guardado responde la pregunta en segundos.
Paso 2: Derivar los pares que tu ERP realmente necesita
Tu API devuelve tasas frente a una única divisa base. Tu ERP puede necesitar GBP→JPY, y tus filiales pueden tener cada una su propia divisa funcional. Deriva las tasas cruzadas a partir de la única instantánea en lugar de hacer una llamada distinta por cada par — esto mantiene cada tasa derivada internamente consistente y mantiene bajo tu número de solicitudes:
def cross_rate(rates: dict, base: str, quote: str) -> float:
"""Both legs come from the same snapshot, so the cross is consistent."""
if base == quote:
return 1.0
return rates[quote] / rates[base]
# GBP -> JPY from a USD-based snapshot
gbp_jpy = cross_rate(payload["rates"], "GBP", "JPY") # 151.28 / 0.7402 = 204.38Si la aritmética de las tasas cruzadas no te resulta familiar, nuestra explicación sobre tipos de cambio cruzados la desarrolla adecuadamente.
Paso 3: Cargar y luego verificar
Nunca trates un HTTP 200 exitoso del ERP como prueba de que la carga funcionó. Después de escribir, vuelve a leer una muestra de pares y compárala con la instantánea. Un paso de verificación de tres líneas detecta direcciones invertidas, filas descartadas silenciosamente y truncamientos de precisión antes de que el equipo de contabilidad contabilice sobre datos incorrectos.
Paso 4: Programar con un manejo de fallos sensato
Ejecuta el trabajo en un calendario de días laborables, bien antes de que el equipo de finanzas empiece a trabajar, e incorpora estos comportamientos:
- Reintentos con backoff ante fallos de red transitorios — tres intentos en diez minutos cubre casi todos los casos.
- Recurrir a la última tasa válida conocida en lugar de no cargar nada, y marcarla claramente. Un ERP con una tasa desactualizada pero etiquetada es muchísimo mejor que un ERP con un hueco.
- Alertar a una persona en el segundo fallo consecutivo. Los fallos silenciosos del trabajo de FX se descubren en el cierre de mes, que es el peor momento posible.
- Rellenar al recuperarse. Cuando el trabajo vuelve a estar operativo, carga todas las fechas perdidas, no solo la de hoy. Nuestra guía de caché y manejo de errores cubre los patrones generales aquí.
Errores que rompen el cierre de fin de mes
Fines de semana y festivos. Los mercados de FX cierran. La mayoría de los ERP esperan una tasa para cada fecha de contabilización, incluidos los sábados. Decide tu política explícitamente — arrastrar la tasa del viernes o usar el propio relleno de huecos del ERP — y documéntala, porque los auditores preguntarán.
Dirección de tasa invertida. Ya lo vimos antes para NetSuite, pero el riesgo es universal. Cada ERP tiene su propia opinión sobre si el número almacenado son unidades de base por cotizada o la inversa. Valida con un par conocido donde la dirección sea obvia: si USD→JPY sale como 0.0066 en lugar de 151, la tienes al revés.
Desajuste de horarios entre sistemas. Si tu plataforma de facturación toma la instantánea de tasas a las 00:00 UTC y tu trabajo del ERP se ejecuta a las 06:00 hora local, las facturas y los asientos del GL usarán números distintos y alguien pasará una semana reconciliando la diferencia. Toma la instantánea una vez y distribúyela a todo.
Factores de tasa en divisas de alta denominación. El problema de TCURF en SAP mencionado antes tiene equivalentes en otros sistemas. Cualquier divisa donde una unidad de la base compre miles de unidades de la cotizada merece un caso de prueba específico.
Correcciones retroactivas. Cuando una tasa se carga mal y ya se han hecho asientos, por lo general no puedes simplemente sobrescribir la tabla — los asientos conservan la tasa antigua. Planifica el flujo de corrección con tu equipo de finanzas antes de necesitarlo.
Construir vs. comprar, con honestidad
Un pipeline de tasas es, en realidad, muy poco código — unos cientos de líneas incluyendo pruebas. Lo que compras a un proveedor de API de divisas son los datos, el uptime y el archivo histórico, no la lógica de integración.
| Entrada manual | Proveedor integrado del ERP | API dedicada + trabajo programado | |
|---|---|---|---|
| Esfuerzo de configuración | Ninguno | Bajo | 1–3 días |
| Esfuerzo continuo | 15–30 min/día | Mínimo | Casi nulo |
| Cobertura de divisas | Lo que consultes manualmente | Lista del proveedor | 170+ |
| Consistente entre sistemas | No | No | Sí |
| Rastro de auditoría propio | Débil | Limitado | Completo |
| Relleno histórico | Manual | Limitado | Completo |
Una vez que el pipeline existe, la misma instantánea alimenta de forma natural a los sistemas vecinos — las integraciones con software de contabilidad, la facturación multidivisa, y los dashboards de BI, todos quieren exactamente los datos que ya estás consultando.
Preguntas frecuentes
¿Puedo usar una API de divisas gratuita para cargar tasas en el ERP?
Para una entidad pequeña con un puñado de divisas y una carga diaria, sí — una llamada al día está muy por debajo de la mayoría de los planes gratuitos, incluido el plan gratuito de Finexly. Lo que los planes gratuitos suelen limitar es la profundidad histórica y el volumen de relleno retroactivo, que es justo lo que necesitas después de una interrupción o durante una auditoría. Comprueba el rango histórico antes de comprometerte.
¿Con qué frecuencia debe ejecutarse la carga de tasas del ERP?
Una vez por día laborable para la mayoría de las organizaciones, programada antes de que el personal de contabilidad empiece a trabajar. Las empresas con alta exposición al FX a veces añaden una segunda carga intradía para la fijación de precios a nivel de transacción, manteniendo a la vez una única tasa diaria para los asientos del GL. Con más frecuencia que eso, solo generas trabajo de reconciliación sin mejorar la precisión.
¿Qué tasa debo usar: spot, de cierre o un promedio?
La práctica estándar tanto bajo IFRS como bajo US GAAP es usar la tasa en la fecha de la transacción para transacciones individuales, y a menudo una tasa promedio para las partidas del estado de resultados a lo largo de un periodo. Esta decisión le pertenece a tu equipo de finanzas, no al de ingeniería; tu trabajo es hacer que la tasa que ellos elijan esté disponible de forma reproducible. La distinción entre tasas spot y forward también importa aquí si la empresa se cubre con hedging.
¿Debo reemplazar el proveedor integrado del ERP o ejecutar ambos?
Ejecuta ambos brevemente, en paralelo, comparando los resultados — es la validación más económica posible de tu nuevo pipeline. Una vez que tengas una semana de resultados coincidentes, desactiva el proveedor integrado. Ejecutar ambos indefinidamente crea ambigüedad sobre qué tasa es la autorizada, lo cual es peor que cualquiera de las dos opciones por separado.
¿Cómo manejo una divisa que mi proveedor no cubre?
Derívala a partir de una tasa cruzada si existe un par intermedio líquido. Si no — y esto es realmente poco frecuente más allá de la cola larga — documenta un proceso manual con un responsable designado y una fuente definida. No sustituyas silenciosamente por una divisa proxy; eso es justo el tipo de cosa que sale a la luz en una auditoría dos años después.
Empieza ahora
¿Listo para dejar de teclear tipos de cambio en tu ERP a mano? Obtén tu clave de API gratuita de Finexly — no se requiere tarjeta de crédito. Obtienes más de 170 divisas, datos históricos para relleno y auditoría, y una API REST que te llevará solo una tarde conectar a NetSuite, SAP o Dynamics. Empieza con el plan gratuito, revisa la documentación de la API, y pasa a un plan de pago solo cuando tu volumen de llamadas realmente lo requiera.
Explore More
Vlado Grigirov
Senior Currency Markets Analyst & Financial Strategist
Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...
View full profile →