Назад к блогу

Мультивалютный чекаут в Shopify: Полное руководство для разработчиков 2026

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

Мультивалютный чекаут в Shopify: Полное руководство для разработчиков 2026

Если вы строите магазин Shopify — или приложение, обслуживающее такой магазин — мультивалютный чекаут больше не опция. Международные покупатели ожидают видеть цены в своей валюте от страницы товара до финальной кнопки «Оплатить». Когда этот опыт ломается, растёт количество брошенных корзин, учащаются чарджбэки, и копятся тикеты поддержки. Это руководство объясняет, как на самом деле работает мультивалютная система Shopify, где её нативные инструменты упираются в потолок и как подключить выделенный API курсов вроде Finexly, чтобы закрыть пробелы.

Строите ли вы headless-витрину, кастомное приложение Shopify или шлифуете Liquid-тему зрелого магазина Shopify Plus — руководство охватывает архитектурные решения, интеграции API и крайние случаи, которые отличают рабочий мультивалютный чекаут от того, что молча теряет выручку.

Почему мультивалютный чекаут важен в Shopify в 2026

Трансграничная e-commerce занимает заметную долю онлайн-ретейла. Покупатели, попадающие на товар в чужой валюте — или ещё хуже, в своей, но с неаккуратной конвертацией, — уходят с большей вероятностью. Трение не только психологическое: транзакции картой в иностранной валюте часто включают банковские комиссии, неожиданные итоги и даже фрод-флаги.

Исследования конверсии показывают один и тот же паттерн: магазины, показывающие цены в локальной валюте, уважающие правила округления и списывающие деньги в той же валюте, конвертят существенно лучше моновалютных. Техническая стоимость раньше была высока — сегодня это несколько вызовов API и чистая стратегия обновления курсов.

Shop currency против presentment currency

Модель мультивалютности Shopify строится на двух понятиях:

  • Shop currency — базовая валюта продавца для цен, отчётности и выплат.
  • Presentment currency — валюта, которую покупатель видит на витрине, в корзине и на чекауте.

Когда покупатель из России заходит в магазин с shop currency USD, товар может отображаться как ₽9 900 (presentment currency), тогда как Shopify внутренне записывает продажу в $99,00 (shop currency). Заказы, возвраты и транзакции хранят оба значения. В GraphQL Admin API это поля shopMoney и presentmentMoney.

Типичная ошибка — считать, что цена, полученная из API, всегда в какой-то одной из них. Это не так. В свежих версиях API все операции чтения в Refund API по умолчанию используют presentment currency, и если при создании транзакции возврата на мультивалютном заказе не передать поле currency, вызов вернёт ошибку. Жёсткое правило: всегда читайте код валюты, привязанный к денежному значению.

Нативные опции Shopify и их границы

Два основных механизма:

1. Shopify Payments с автоконвертацией. Если магазин подходит, включаются несколько presentment currency, и Shopify автоматически пересчитывает цены по курсам, обновляемым примерно раз в 15 минут. Добавляется небольшая комиссия за конвертацию (обычно 1,5–2%) и применяется округление по валюте.

2. Ручные курсы через Shopify Markets. Вы задаёте курсы сами, Shopify применяет формулу:

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

Базу это закрывает, но не хватает в нескольких реальных сценариях:

  • Headless-витрины. Со Storefront API, Hydrogen или кастомным фронтендом вы сами управляете отображением и часто нуждаетесь в более богатых данных (исторические курсы для аналитики, кросс-курсы, неплатёжные случаи — например, счета поставщикам).
  • Продавцы без Shopify Payments. Stripe, PayPal, Adyen или локальные процессоры — автоматический конвейер им недоступен.
  • Своя логика цен. Маркетплейсы, B2B с ценовыми уровнями, локализованные акции.
  • Приложения после чекаута. Синк с бухгалтерией, антифрод, лояльность, агрегаторы должны нормализовать мультивалютные заказы к единой отчётной валюте — с надёжными историческими курсами на точный момент заказа.

Во всех этих случаях рядом с Shopify нужен выделенный API курсов.

Когда подключать внешний API курсов

Правило: если что-то из нижеперечисленного верно, подключайте внешний API вроде Finexly:

  1. У вас headless или гибридная витрина и нужен программный доступ к живым курсам.
  2. Вы поддерживаете валюты, которые Shopify Payments не конвертирует автоматически в вашем регионе.
  3. Вы строите приложения, обрабатывающие исторические заказы, и нужен точный курс на момент заказа для сверки и аудита.
  4. Хотите показывать цены в валюте без обязательства списывать в ней.
  5. Нужны обновления чаще, чем 15-минутный цикл Shopify — например, во время объявлений центробанков.

Подробнее — в нашем сравнении API курсов и в статье REST vs WebSocket для FX-данных.

Finexly отдаёт курсы реального времени и исторические для 170+ валют через чистый REST, без скрытых комиссий в самих курсах.

Собираем мультивалютный чекаут с Finexly и Shopify

Минимальная архитектура:

  1. Определите валюту покупателя — по геолокации, locale браузера или явному селектору.
  2. Получите текущий курс от Finexly (кэшировано на edge, обновляется раз в несколько минут).
  3. Конвертируйте цены с учётом округления и маржи.
  4. На чекауте передайте presentment currency Shopify, чтобы заказ создался в правильной валюте.
  5. Сохраните использованный курс как метаданные заказа для сверки.

Шаг 1. Получаем курс у Finexly

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:

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"]

Быстрая проверка cURL:

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

В проде оборачивайте в кэш — Redis, Cloudflare KV или in-process cache с TTL 60–300 секунд. См. наш гид по кэшу и обработке ошибок.

Шаг 2. Конвертируем цены на витрине

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

Шаг 3. Передаём в чекаут Shopify в правильной валюте

При использовании Storefront API передавайте presentment currency при создании корзины. В GraphQL Cart API поле buyerIdentity.countryCode определяет применяемую presentment currency:

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

Shopify покажет цены в нужной presentment currency, а checkoutUrl спишет деньги в ней — при условии, что ваш платёжный шлюз сконфигурирован.

В классической (не headless) витрине корзины через API не создаются. Используйте приложение Geolocation или URL-параметр ?currency=EUR. Liquid-фильтры вроде {{ product.price | money }} будут учитывать активную presentment currency.

Шаг 4. Сохраняем использованный курс с каждым заказом

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() } });

Когда через три месяца бухгалтер спросит, почему EUR-сумма заказа #10042 не сходится с USD × текущий курс, будущий вы поблагодарит нынешнего.

Показ конвертированных цен: Liquid vs Headless

Liquid (классические темы)

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

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

Headless (Hydrogen, Next.js, custom)

// 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} />;
}

См. наш туториал конвертера валют на Next.js.

Сложные части: округление, комиссии, свежесть

Правила округления. У японской иены нет копеек. Швейцарский франк традиционно округляется до ближайших 0,05. В большинстве стран клиенты ждут цен с окончанием .99 или .95:

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);
}

Маржа конверсии. Если не используете Shopify Payments, добавьте в показываемый курс небольшой зазор (обычно 1–3%), чтобы покрыть спред платёжного процессора. Явно, с настройкой по рынкам.

Свежесть курса. Курсы двигаются. Во время заявлений центробанков или крупных макрособытий курсы могут сдвигаться на 1–2% за минуты. Finexly обновляет каждые 60 секунд; с 2-минутным edge-кэшем вы получите почти живой прайсинг без перегрузки API. См. работу с волатильностью валют.

Отслеживание и сверка мультивалютных заказов

Три подхода:

  1. Курс на момент заказа — самый честный с точки зрения экономики.
  2. Курс на момент выплаты — совпадает с тем, что пришло в банк.
  3. Средний месячный курс — удобнее для бухгалтерии; через исторический эндпоинт Finexly.
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"

Финансовые команды обычно предпочитают #1 для признания выручки и #2 для сверки кассы. Храните оба.

Частые ловушки

  • Бесконечный кэш курсов. 24 часа — слишком много. TTL 5–10 минут и circuit breaker при промахе.
  • Доверять клиенту. Никогда не считайте финальную цену только в JavaScript — перепроверяйте на сервере или в Shopify Function.
  • Округлять только итог. Округляйте по строкам, иначе «итог не равен сумме позиций».
  • Забывать про возвраты. При возврате мультивалютного заказа обязательно передавайте currency.
  • Игнорировать наблюдаемость. Логируйте каждый fetch курсов с источником, таймстампом и задержкой.

Часто задаваемые вопросы

Shopify Payments поддерживает все валюты? Нет. Список presentment currencies ограничен и зависит от региона. Для неподдерживаемых валют либо маршрутизируйте через другой процессор, либо показывайте конверсии без списания в целевой валюте.

Можно ли Finexly напрямую управлять курсами конверсии Shopify? Напрямую — нет. Shopify Payments использует собственный источник. Но можно загружать курсы Finexly в ручные настройки Markets через Admin API и таким образом фактически заменить автоматические курсы.

Как часто обновлять курсы? Для большинства витрин оптимально — edge-кэш 2–5 минут поверх обновлений Finexly раз в минуту. Для товаров с высоким AOV или низкой маржой — жёстче (30–60 секунд); для быстрых низко-AOV товаров — до 15 минут.

Нужен ли мультивалютный API, если у меня Shopify Payments с автоконвертацией? Чаще всего да — для всего, что рядом с чекаутом: бухгалтерская сверка, маркетинговая аналитика, счета поставщикам, отображение цен в рынках, которые Shopify не покрывает. См. наш гид по интеграции с бухгалтерией.

Как лучше тестировать мультивалютный чекаут? Bogus Gateway в dev-магазине, смена IP по VPN для имитации разных стран, и проверка, что подтверждение заказа, чек и Admin показывают совпадающие presentment-суммы. Затем — тест возврата: именно там большинство интеграций тихо ломаются.

Быстрее релизы с Finexly

Мультивалютный чекаут в Shopify снаружи выглядит просто, а внутри имеет длинный хвост крайних случаев. Хорошая новость: с надёжным API курсов снизу большинство кейсов сводятся к известным паттернам — кэшируй, округляй, сохраняй, сверяй.

Готовы встроить надёжные курсы в свой магазин или приложение Shopify? Получите бесплатный API-ключ Finexly — без кредитной карты. Начните с 1 000 бесплатных запросов в месяц и масштабируйтесь вместе с магазином.

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 →