Volver al blog

Checkout Multimoneda en Shopify: Guía Completa para Desarrolladores 2026

V
Vlado Grigirov
April 23, 2026
Currency API Shopify E-commerce Multi-Currency Exchange Rates Finexly Headless Commerce

Checkout Multimoneda en Shopify: Guía Completa para Desarrolladores 2026

Si estás construyendo una tienda Shopify —o una app que da servicio a una— el checkout multimoneda ya no es algo opcional. Los compradores internacionales esperan ver los precios en su propia moneda desde la página de producto hasta el botón final de "Pagar ahora". Cuando esa experiencia se rompe, los carritos abandonados aumentan, los chargebacks crecen y los tickets de soporte se acumulan. Esta guía explica cómo funciona realmente el sistema multimoneda de Shopify por dentro, dónde se queda corta su herramienta nativa, y cómo integrar una API de tipos de cambio como Finexly para cubrir esos huecos.

Ya sea que estés construyendo un storefront headless, una app Shopify personalizada, o simplemente afinando un tema Liquid en una tienda Shopify Plus madura, esta guía cubre las decisiones de arquitectura, las integraciones de API y los casos límite que separan un checkout multimoneda que funciona de uno que silenciosamente pierde ingresos.

Por qué importa el checkout multimoneda en Shopify en 2026

El e-commerce transfronterizo ya representa una parte significativa del comercio online. Los compradores que llegan a un producto con precio en moneda extranjera —o peor, en su moneda pero con tipos de cambio chapuceros— abandonan el checkout mucho más que el resto. La fricción no es solo psicológica. Las transacciones con tarjeta en moneda extranjera suelen disparar comisiones bancarias adicionales, totales inesperados y hasta alertas de fraude.

La investigación de Shopify y múltiples estudios de conversión muestran el mismo patrón: las tiendas que presentan precios en la moneda local, respetan las convenciones de redondeo de cada mercado y cobran en esa moneda en el checkout convierten sustancialmente mejor que las tiendas monomoneda. El esfuerzo técnico solía ser considerable; hoy se reduce a un puñado de llamadas API y una estrategia limpia de actualización de tipos.

Antes de sumergirnos en código, conviene entender una distinción que confunde a la mayoría de desarrolladores la primera vez que tocan las APIs multimoneda de Shopify.

Entendiendo Shop Currency vs. Presentment Currency

El modelo multimoneda de Shopify gira en torno a dos conceptos:

  • Shop currency — la moneda base que el comerciante usa para sus precios, reportes y pagos. Todos los productos se almacenan internamente en esta moneda.
  • Presentment currency — la moneda que el comprador ve realmente en el storefront, en el carrito y en el checkout.

Cuando un cliente alemán navega una tienda con shop currency USD, el producto puede mostrarse como €92,50 (presentment currency) mientras Shopify registra internamente la venta a $99,00 (shop currency). Los pedidos, reembolsos y transacciones guardan ambos valores. En la GraphQL Admin API los verás como los campos shopMoney y presentmentMoney en cada objeto monetario —líneas de pedido, reembolsos, transacciones, envíos.

El error común es asumir que un precio obtenido de la API siempre está en una o en la otra. No lo está. En las versiones recientes de la API, todas las lecturas del Refund API usan presentment currency por defecto, y si creas una transacción de reembolso en un pedido multimoneda sin pasar explícitamente el campo currency, la llamada devolverá un error. Trátalo como regla estricta: lee siempre el código de moneda adjunto al valor monetario, nunca asumas.

Las opciones nativas de Shopify (y dónde se quedan cortas)

Shopify ofrece dos funcionalidades principales para comercio multimoneda:

1. Shopify Payments con conversión automática. Si tu tienda es elegible para Shopify Payments, puedes habilitar varias presentment currencies y Shopify convierte los precios con tipos actualizados cada 15 minutos desde un proveedor externo. Aplica una pequeña comisión de conversión (normalmente 1,5–2% según la región) y gestiona el redondeo por moneda.

2. Tipos manuales vía Shopify Markets. Para comerciantes que quieren control —o que no están en Shopify Payments— Shopify Markets permite definir tus propios tipos por moneda. Tú los defines y Shopify aplica la fórmula:

converted_price = (product_price × conversion_rate) × (1 + conversion_fee)

Luego aplica las reglas de redondeo por moneda.

Estas opciones cubren lo básico, pero se quedan cortas en varios escenarios reales:

  • Storefronts headless. Si estás construyendo con la Storefront API, Hydrogen o un frontend propio, tú controlas la presentación —y a menudo necesitas datos de tipos más ricos que los que Shopify expone (tipos históricos para analítica, cross-rates para monedas que Shopify no soporta directamente, o tipos para casos de uso no-pago como facturación a proveedores).
  • Comerciantes sin Shopify Payments. Tiendas con Stripe, PayPal, Adyen o procesadores locales no obtienen el pipeline automático y deben gestionar tipos por su cuenta.
  • Lógica de precios personalizada. Marketplaces, tiendas B2B con precios por tramos y tiendas con promociones localizadas necesitan calcular precios dinámicamente desde una fuente de verdad distinta a Shopify.
  • Apps que actúan post-checkout. Apps de contabilidad, herramientas antifraude, sistemas de fidelización y agregadores de marketplace necesitan normalizar pedidos multimoneda a una moneda común de reporte —y eso requiere tipos históricos fiables al timestamp exacto del pedido.

En todos estos casos, necesitas una API de tipos de cambio dedicada junto a Shopify.

Cuándo usar una API externa de tipos de cambio

Regla práctica: si cualquiera de los siguientes puntos es cierto, añade una API externa como Finexly:

  1. Operas un storefront headless o híbrido y necesitas acceso programático a tipos en vivo.
  2. Soportas monedas que Shopify Payments no autoconvierte en tu región.
  3. Construyes apps que procesan pedidos históricos y necesitas el tipo exacto en el momento del pedido para conciliación o auditoría.
  4. Quieres mostrar precios en monedas sin comprometerte a cobrar en ellas (p. ej., "€" mostrado como comodidad mientras cobras en USD).
  5. Necesitas actualizaciones de tipos más rápidas que los 15 minutos de Shopify —por ejemplo, durante anuncios de bancos centrales.

Para más contexto, hemos escrito una comparación de APIs de divisas y un artículo específico sobre REST vs WebSocket para datos FX.

Finexly ofrece tipos de cambio en tiempo real e históricos para más de 170 monedas a través de una interfaz REST limpia, sin comisiones ocultas incorporadas en los tipos ni sorpresas de precio por llamada.

Construyendo un checkout multimoneda con Finexly y Shopify

La arquitectura mínima para un checkout multimoneda fiable:

  1. Detecta la moneda del comprador —por geolocalización, locale del navegador o selector explícito.
  2. Obtén el tipo actual de Finexly (cacheado en el edge, refrescado cada pocos minutos).
  3. Convierte precios para mostrar —aplicando tus reglas de redondeo y margen.
  4. En el checkout, usa el parámetro de presentment currency de Shopify para que el pedido se cree con la moneda correcta.
  5. Guarda el tipo usado como metadato del pedido para conciliación.

Paso 1: Obtener el tipo actual de Finexly

La llamada más simple devuelve tipos contra una moneda base. Versión Node.js:

// Fetch live rates from Finexly
async function getRates(base = 'USD') {
  const url = `https://api.finexly.com/v1/latest?base=${base}&apikey=${process.env.FINEXLY_KEY}`;
  const res = await fetch(url);
  if (!res.ok) throw new Error(`Finexly error: ${res.status}`);
  const data = await res.json();
  return data.rates; // { EUR: 0.9234, GBP: 0.7891, JPY: 151.42, ... }
}

Python funciona igual:

import os, requests

def get_rates(base="USD"):
    url = "https://api.finexly.com/v1/latest"
    params = {"base": base, "apikey": os.environ["FINEXLY_KEY"]}
    r = requests.get(url, params=params, timeout=5)
    r.raise_for_status()
    return r.json()["rates"]

O con cURL para una prueba rápida:

curl "https://api.finexly.com/v1/latest?base=USD&apikey=YOUR_KEY"

En producción, envuélvelo en una capa de caché —Redis, Cloudflare KV o simplemente caché en proceso con TTL de 60–300 segundos. Nuestra guía de caché y manejo de errores cubre los patrones exactos que recomendamos.

Paso 2: Convertir precios en el storefront

Con los tipos en mano, convertir un precio de Shopify es directo:

function convertPrice(amountInBase, rate, roundingRule = 0.99) {
  const raw = amountInBase * rate;
  return Math.floor(raw) + roundingRule;
}

const rates = await getRates('USD');
const eurPrice = convertPrice(49.00, rates.EUR, 0.99);
// => e.g., 45.99

Paso 3: Pasar al checkout de Shopify en la moneda correcta

Con la Storefront API, pasa la presentment currency al crear el cart. En la GraphQL Cart API, el campo buyerIdentity —específicamente countryCode— determina qué presentment currency aplica al carrito:

mutation CreateCart {
  cartCreate(input: {
    buyerIdentity: { countryCode: DE }
    lines: [{ merchandiseId: "gid://shopify/ProductVariant/123", quantity: 1 }]
  }) {
    cart { id checkoutUrl
      cost { totalAmount { amount currencyCode } }
    }
  }
}

Shopify mostrará los precios en la presentment currency adecuada para ese país, y el checkoutUrl cobrará en esa moneda —asumiendo que tu pasarela de pago está configurada para ello.

En un storefront clásico (no headless) no creas carritos vía API. Puedes usar la Geolocation app de Shopify o fijar la moneda con el parámetro URL ?currency=EUR. Los filtros Liquid como {{ product.price | money }} respetarán la presentment currency activa.

Paso 4: Guardar el tipo usado con cada pedido

Este es el paso que la mayoría de integraciones se saltan —y lamentan más tarde. Cuando se crea el pedido, guarda el tipo de Finexly (y el timestamp) en metafields:

await admin.graphql(`
  mutation AddRateMetafield($orderId: ID!, $rate: String!, $ts: String!) {
    orderUpdate(input: {
      id: $orderId
      metafields: [
        { namespace: "fx", key: "rate", value: $rate, type: "single_line_text_field" }
        { namespace: "fx", key: "rate_timestamp", value: $ts, type: "single_line_text_field" }
        { namespace: "fx", key: "source", value: "finexly", type: "single_line_text_field" }
      ]
    }) { order { id } userErrors { field message } }
  }
`, { variables: { orderId, rate: String(rates.EUR), ts: new Date().toISOString() } });

El futuro-tú te agradecerá esto cuando tres meses después un contable pregunte por qué el total EUR del pedido #10042 no cuadra con USD × tipo actual.

Mostrando precios convertidos: Liquid vs Headless

Liquid (temas clásicos)

Shopify ofrece la familia de filtros money que respetan la presentment currency activa automáticamente cuando Shopify Payments multimoneda está habilitado:

<!-- Respects presentment currency -->
<p class="price">{{ product.price | money }}</p>

<!-- Explicit formatting -->
<p class="price">{{ product.price | money_with_currency }}</p>

Si usas tipos manuales o quieres añadir tipos de Finexly para más monedas, inyecta los tipos con un pequeño script en theme.liquid que llame a un App Proxy que consulte Finexly con caché delante.

Headless (Hydrogen, Next.js, custom)

En un setup headless tienes control total. Patrón típico en Next.js:

// app/lib/fx.ts - server-side rate fetcher with caching
export async function getFxRates(base = 'USD') {
  const res = await fetch(
    `https://api.finexly.com/v1/latest?base=${base}&apikey=${process.env.FINEXLY_KEY}`,
    { next: { revalidate: 120 } }
  );
  return res.json();
}

export default async function Product({ params }) {
  const [product, fx] = await Promise.all([
    getProduct(params.handle),
    getFxRates('USD'),
  ]);
  const userCurrency = getUserCurrency();
  const displayPrice = product.priceUsd * fx.rates[userCurrency];
  return <ProductView product={product} price={displayPrice} currency={userCurrency} />;
}

Consulta nuestro tutorial de conversor de divisas en Next.js para profundizar en caché y revalidación.

Gestionando las partes difíciles: redondeo, comisiones y frescura

Reglas de redondeo. El yen japonés no tiene decimales. El franco suizo se redondea tradicionalmente al 0,05 más cercano. Los clientes en la mayoría de países esperan precios terminados en ,99 o ,95. Las reglas nativas de Shopify cubren lo básico, pero si conviertes fuera de Shopify Payments, implementa reglas explícitas por moneda:

const ROUNDING = {
  JPY: (v) => Math.round(v),
  CHF: (v) => Math.round(v * 20) / 20,
  default: (v) => Math.floor(v) + 0.99,
};
function round(value, currency) {
  return (ROUNDING[currency] || ROUNDING.default)(value);
}

Margen de conversión. Si no usas la comisión incorporada de Shopify Payments, añade un pequeño margen (típicamente 1–3%) al tipo mostrado para cubrir el spread del procesador de pago. Hazlo explícito y configurable por mercado.

Frescura del tipo. Los tipos se mueven. Durante anuncios de bancos centrales o eventos macro mayores, los tipos pueden variar 1–2% en minutos. Para tiendas de AOV alto, un tipo obsoleto es pérdida directa. Finexly actualiza tipos cada 60 segundos; combinado con un edge cache de 2 minutos te da precios casi en vivo sin martillear la API. Ver también manejando la volatilidad cambiaria.

Seguimiento y conciliación de pedidos multimoneda

Cuando finanzas pregunta "¿cuánto ganamos realmente en USD el trimestre pasado?", la respuesta depende del tipo que uses. Tres enfoques comunes:

  1. Tipo al momento del pedido —el más fiel a la realidad económica; usa el tipo guardado en metafields.
  2. Tipo al momento del payout —coincide con lo que llegó a tu banco; usa los tipos de la API de payouts de Shopify.
  3. Tipo medio mensual —más suave para contabilidad; consulta medias mensuales desde el endpoint histórico de Finexly.

La API histórica de Finexly facilita los tres:

curl "https://api.finexly.com/v1/historical/2026-03-15?base=USD&apikey=YOUR_KEY"

curl "https://api.finexly.com/v1/timeseries?start=2026-03-01&end=2026-03-31&base=USD&symbols=EUR&apikey=YOUR_KEY"

La mayoría de equipos financieros prefieren el enfoque #1 para reconocimiento de ingresos y el #2 para conciliación de caja. Guarda ambos.

Errores frecuentes (y cómo evitarlos)

  • Cachear tipos para siempre. Un caché de 24 horas es demasiado largo para una tienda que recibe pedidos durante horario asiático y europeo. Limita TTL a 5–10 minutos y refresca en fallo de caché con circuit breaker.
  • Confiar en el cliente. Nunca calcules precios finales solo en JavaScript —un cliente hostil puede manipularlos. Revalida en servidor o en una Shopify Function antes de crear el pedido.
  • Ignorar el redondeo por línea vs total. Redondea por línea, no solo por total, para evitar bugs donde "el total no cuadra con la suma de ítems".
  • Olvidar los reembolsos. Al reembolsar un pedido multimoneda debes pasar el campo currency explícitamente o la API lo rechazará. La moneda del reembolso debe coincidir con la presentment currency original.
  • Saltar la observabilidad. Loguea cada fetch de tipo con origen, timestamp y tiempo de respuesta. Cuando un tipo parezca mal, necesitarás el rastro.

Preguntas frecuentes

¿Shopify Payments soporta todas las monedas? No. Shopify Payments soporta una lista creciente pero finita de presentment currencies, y la disponibilidad depende de la región del comerciante. Para monedas no soportadas, o bien encaminas esos mercados por otro procesador, o muestras conversiones sin cobrar en la moneda objetivo.

¿Puedo usar Finexly para manejar directamente los tipos de conversión de Shopify? No directamente —Shopify Payments usa su propia fuente interna. Lo que sí puedes hacer es alimentar tipos de Finexly en la configuración manual de Markets vía la Admin API, reemplazando efectivamente los tipos automáticos de Shopify.

¿Con qué frecuencia debo refrescar los tipos? Para la mayoría de storefronts, un edge cache de 2–5 minutos encima de las actualizaciones por minuto de Finexly es el punto óptimo. Para productos de AOV alto o margen bajo, baja a 30–60 segundos; para bienes de AOV bajo y alto volumen, puedes estirar a 15 minutos.

¿Necesito una API multimoneda si uso Shopify Payments con conversión automática? A menudo sí —para todo lo adyacente al checkout. Conciliación contable, analítica de marketing, facturación a proveedores y visualización de precios en mercados que Shopify no cubre se benefician de una API dedicada. Ver nuestra guía de integración con software contable.

¿Cuál es la mejor forma de probar el checkout multimoneda? Usa el Bogus Gateway de Shopify en una tienda de desarrollo, cambia tu IP con VPN para simular contextos de país diferentes, y verifica que la confirmación, recibo y Admin muestren importes de presentment coincidentes. Luego prueba un reembolso —ahí es donde la mayoría de integraciones se rompen silenciosamente.

Envía más rápido con Finexly

El checkout multimoneda en Shopify parece simple por fuera y tiene una cola larga de casos límite por dentro. La buena noticia: con una API de tipos sólida como base, la mayoría de esos casos se reducen a patrones conocidos —cache, redondea, guarda, concilia.

¿Listo para integrar tipos de cambio fiables en tu tienda o app Shopify? Obtén tu API key gratuita de Finexly —sin tarjeta de crédito. Empieza con 1.000 llamadas gratis al mes, escala a medida que crezcas y lanza un checkout multimoneda que tus clientes internacionales disfruten usar.

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 →