История создания API для курса валют

В этой статье рассказываю, что побудило меня создать свой API для конвертации валют и получения актуального курса от различных источников. Начиная от анализа потребностей в онлайн-платежах и заканчивая разработкой гибкого и эффективного микросервиса.

История создания API для курса валют

Вводные данные

В сфере онлайн-платежей, включая банки и платежные системы, возникла необходимость в получении курсов валют для конвертации суммы платежей, особенно в случаях, когда провайдер не поддерживает валюту платежа. Для этой задачи требуются следующие функциональные возможности от потенциального сервиса:

  • Быстрая обработка большого объема запросов для получения курсов валют и готовых результатов конвертации.
  • Возможность создания собственных стратегий конвертации, учитывая различные особенности, например, принятие оплаты в одной валюте и конвертацию в другую.

Пример конкретной задачи: Банк А принимает оплату только в PLN (польский злотый), но покупатель готов оплатить это только картой с валютой EUR. Нам необходимо определить сумму в PLN для отправки запроса к банку-эквайру. Какие есть варианты решения этой задачи?

  • Использование среднего курса валют с небольшим процентом наценки для нивелирования недополучения дохода нашему мерчанту.
  • Отказ от принятия оплаты в неподдерживаемой валюте (неоптимальный вариант для бизнеса, но идеальный для разработчика).
  • Попросить банк добавить поддержку нужной валюты (часто невозможно).

Изначально выбрал первый вариант, который казался успешным, пока не стали поступать жалобы о том, что суммы списания превышают заявленные. Дальнейший анализ показал, что средний курс валют сильно отличается от фактического и зависит от многих факторов, таких как провайдер, который выпустил карту, правила конвертации у банка, который принимает платеж.

История создания API для курса валют

Пример 1: У вас карта в евро. Вы совершаете покупки в отпуске в Италии тоже в евро. Сумма покупки — 50 евро, итого с вашего счёта спишется 50 евро.

Пример 2: У вас карта в евро. Вы совершаете покупку в Польше в польских злотых. В этом случае схема пересчёта следующая: польские злотые (PLN) → пересчитываются в USD по курсу Mastercard, далее USD → пересчитываются в CNY по курсу Mastercard, затем CNY → пересчитываются в евро по курсу банка.

Для точного расчета суммы после всех конвертаций нам нужна информация о курсах валют от следующих источников:

  • "Mastercard" PLN -> USD
  • "Mastercard" USD -> CNY
  • "Альфа-Банк Беларусь" CNY -> EUR

С такими вводными приступаем к анализу рынка...

Анализ рынка

Напомню, мы выделили основные критерии поиска:

1) Быстрая обработка большого объема запросов для получения курсов валют и готовых результатов конвертации.
2) Возможность создания собственных стратегий конвертации, учитывая различные особенности, например, принятие оплаты в одной валюте и конвертацию в другую.

История создания API для курса валют

+ быстрый и удобный API

+ есть возможность выбора источника курса валют (но на данный момент только центральные банки нескольких стран, что недостаточно для моего кейса)

+ есть курсы криптовалюты

дорого

нет возможности создания собственных стратегий для конвертации

+ быстрый и удобный API

+ приятная цена

нет возможности создания собственных стратегий для конвертации

нет возможности выбрать источник курса

+ быстрый и удобный API

+ приятная цена

нет возможности создания собственных стратегий для конвертации

нет возможности выбрать источник курса

+ быстрый и удобный API

+ приятная цена

+ есть курсы криптовалюты

нет возможности создания собственных стратегий для конвертации

нет возможности выбрать источник курса

+ быстрый и удобный API

+ приятная цена

нет возможности создания собственных стратегий для конвертации

нет возможности выбрать источник курса

Изначально выбрал https://openexchangerates.org и использовал именно его, но достаточно быстро появились новые бизнес-кейсы, такие как пример с “Альфа-Банк Беларусь” и покупкой в PLN, когда этого функционала перестало хватать. Об этом упоминалось выше.

Все сервисы имели почти одинаковый набор плюсов и минусов, но главное, что ни один из них не имел того, что требовалось мне. С этого момента произошло разочарование из-за отсутствия нужного инструмента, но с другой стороны появилось вдохновение от возможности создать то, что будет работать именно под мою конкретную задачу. Благодаря этому анализу у меня возникла некоторая насмотренность на то, как крупные игроки рынка делают свои API. Поэтому в моей голове уже начала складываться база того, как это должно выглядеть: source_currency, target_currency, amount, base_currency, и поехали, думал я. Но как я ошибался, что этим все ограничится.

Разработка

Ванильное представление о своем микросервисе быстро столкнулось с жесткой реальностью, так как оказалось, что все гораздо сложнее. Набор параметров на вход стал больше, также увеличилось количество логики в коде и интеграций с источниками курсов. В конечном итоге, получился минимальный набор для активно используемых эндпоинтов (не учитывая эндпоинты для получения информации о источниках, созданных конвертациях и т.д.).

  • /api/v1/rates - эндпоинт, который позволяет получать курсы валют, указывая необходимые параметры.
{ "rate_source_code": "alfa_bank_belarus", // Каждый источник курса имеет свой уникальный код. "exchange_type_code": "card", // Определяет, какой курс использовать. В банках могут быть разные курсы для карточек, наличных операций и т.д. "category_code": "bank", // Некоторые источники могут предоставлять курсы валют разных категорий, таких как банки и биржи. "branch": "main", // Некоторые источники курса имеют разные курсы валют для различных отделений или филиалов. "rounding": 2, // Округление результата до указанного числа цифр после запятой. "test_mode": true }
  • /api/v1/conversions - этот эндпоинт выполнит конвертацию в соответствии с указанной стратегией, учитывая все соответствующие правила и параметры конвертации.

{ "strategy_code": "alfa_bank_belarus_custom_1", // Код стратегии обмена, который создается отдельно (следующий эндпоинт, который ниже). "source_currency": "PLN", "target_currency": "EUR", "amount": 40.99, "source_currency_unit": "amount", // Формат суммы конвертации, который может быть как в привычном формате (1.00), так и в копеечном (100). Этот параметр регулирует формат. "target_currency_unit": "amount", // Как и выше, только это формат результата. "rounding": 2, "branch": "main", "test_mode": true }
  • /api/v1/conversion_strategies - для создания стратегии конвертации валют.

{ "code": "alfa_bank_belarus_custom_1", "name": "Custom strategy for Alfa-Bank Belarus", "data": [ { "priority": 1, // Приоритет внутренней конвертации. "action_type": "accurate", // Можно задавать точный курс валют у определенного источника, либо брать средний ("average"). "rate_source_code": "mastercard", "category_code": "payment_system", "exchange_type_code": "card", "target_currency": "USD", "base_currency": "BYN" // Валюта для конвертации, используемая в случае отсутствия у источника курса прямой конвертации запрошенных валют. }, { "priority": 2, "action_type": "accurate", "rate_source_code": "mastercard", "category_code": "payment_system", "exchange_type_code": "card", "target_currency": "CNY", "base_currency": "BYN" }, { "priority": 3, "action_type": "accurate", "rate_source_code": "alfa_bank_belarus", "category_code": "bank", "exchange_type_code": "card", "target_currency": "REQUESTED", "base_currency": "BYN" } ] }

Как только все было запущено в продакшн и протестировано, я почувствовал облегчение. Однако, спустя некоторое время осознал, что получился микросервис, который по своей функциональности объединяет все доступные на рынке API-сервисы для конвертации валют и получения курсов. Кроме того, он добавляет такие возможности, как:

  • Получение курсов из любых источников: банков, платежных систем, бирж и т.д. (ограничивается лишь вашим набором интеграций).
  • Создание собственных стратегий для конвертации, которые позволяют решать самые сложные кейсы.
  • Использование точной конвертации осуществляется по определенным параметрам, таким как источник курса, его тип обмена и категория. Альтернативно, можно использовать средний курс из всех источников, доступных в базе данных, с учетом фильтрации по категории источника валют.

Обсуждение в комментариях может привести к ценным идеям и обмену опытом. Если у вас возникали аналогичные сценарии или есть желание использовать более широкий функционал сервисов курсов валют, я бы с интересом прочитал ваши мысли и опыт.

Какие функции или возможности вам кажутся наиболее важными или полезными для улучшения этого сервиса? Я открыт к обсуждению и готов рассмотреть любые предложения по его улучшению.

P.S. Сам микросервис я трансформировал в отдельное API, к которому теперь есть доступ не только у меня. Если кто-то захочет использовать его или просто "потыкать палкой", то велкоме: https://irates.io.

Начать дискуссию