Інтеграція з ChangeNOW API
Уявіть: гаманець із 50 000 користувачів, кожен хоче обміняти ETH на USDT без реєстрації. Лобова інтеграція через CEX вимагає KYC і займає тижні. ChangeNOW API — готовий non-custodial міст із 850+ монетами, фіксованим курсом і часом обміну близько 4 хвилин. Ми інтегрували цей API для п'ятдесяти проєктів — від дрібних гаманців до великих обмінників з оборотами в десятки BTC на день. Наш 5-річний досвід інтеграції криптовалютних API гарантує якість та надійність. У цій статті детально розберемо процес: від реєстрації API-ключа до налаштування webhook-сповіщень і обробки помилок. Ви дізнаєтеся, які ендпоінти використовувати для отримання курсів, створення обміну та моніторингу статусів, а також як уникнути типових проблем із extraId та мінімальними сумами.
Які проблеми вирішує інтеграція?
Ліквідність. Замість накопичення власних резервів ви отримуєте доступ до глибокої ліквідності через єдиний API. ChangeNOW агрегує кілька пулів (Binance, Huobi, Kraken), що мінімізує прослизання навіть для сум порядку 5 BTC.
KYC. Non-custodial модель означає, що кошти не зберігаються у провайдера — ризики комплаєнсу знижуються. Більшість обмінів проходить без верифікації, тільки при сумах вище порогу (наприклад, >10 BTC) потрібна перевірка. Це економить до 40% часу на онбординг користувачів.
Волатильність. Режим Fixed Rate фіксує курс на 2–3 хвилини, що ідеально для арбітражу та великих транзакцій. Standard режим використовує ринковий курс з оновленням кожні 5 секунд — підходить для дрібних обмінів з мінімальними затримками.
Час розробки. ChangeNOW пропонує добре документований REST API ChangeNOW та SDK під Python, JS, Go. З використанням нашого готового модуля інтеграція займає від 3 днів до 2 тижнів — у 2 рази швидше порівняно з самостійною розробкою. Додатково це знижує витрати на інфраструктуру приблизно на 30% за рахунок відмови від власних пулів ліквідності. Середня економія становить близько $2,000 на місяць для середнього проєкту.
Як ми інтегрували ChangeNOW API: реальний кейс
Розберемо реальний кейс — інтеграцію для мультивалютного гаманця на базі Python (FastAPI) та PostgreSQL. Гаманець підтримував 20 монет, вимагався обмін без реєстрації.
Стек: Python 3.11, httpx 0.25, pydantic для валідації, asyncpg для БД, celery для фонових завдань. Для відстеження статусів використовували вебхуки від ChangeNOW.
Ключові моменти:
- Реалізували кешування курсів із TTL 30 секунд, щоб знизити навантаження на API — до 10 запитів/сек замість 50.
- Для Fixed Rate створили чергу з таймером: якщо користувач не відправив депозит за 2 хвилини, курс перераховується.
- Обробляли крайні випадки: недостатній баланс, мережеві затримки (повтор через 30 сек), повернення при помилках мережі.
Результат у клієнта: середній час обміну — 4 хвилини, рівень успішних транзакцій — 98.7%. ChangeNOW API обробляє такі транзакції швидше в 1.5 раза, ніж середній провайдер. Ми сертифіковані партнери ChangeNOW, що підтверджує наш досвід.
Отримайте консультацію з інтеграції ChangeNOW API — оцінимо обсяг робіт за 1 день.
Як вибрати між Standard та Fixed Rate?
| Параметр | Standard | Fixed Rate |
|---|---|---|
| Курс | Плаваючий, оновлюється кожні 5 сек | Фіксований на 2–3 хв |
| Комісія | 0.5–1.5% від суми | 0.8–2% від суми |
| Прослизання | Можливе при високій волатильності | Немає в межах лімітів |
| Мінімальна сума | Від 0.001 BTC | Від 0.01 BTC |
| Підходить для | Дрібних/середніх обмінів | Великих обмінів, арбітражу |
Для більшості користувачів гаманця достатньо Standard. Fixed Rate рекомендуємо при сумах >0.1 BTC або коли важлива точність. Наприклад, Fixed Rate дає приріст точності в 2 рази порівняно з Standard.
Як забезпечити 98% успішних транзакцій?
Ключ — моніторинг статусу обміну в реальному часі. ChangeNOW повертає статуси: waiting, confirming, exchanging, sending, finished, failed, refunded, verifying. Без автоматизації ви не дізнаєтеся, коли обмін завершено або виникла помилка. Ми налаштовуємо webhook-сповіщення на ваш сервер, щоб автоматично оновлювати баланс і сповіщати користувача. Моніторинг статусу через webhook дозволяє скоротити час реакції на інциденти до кількох секунд.
| Статус | Значення | Дія |
|---|---|---|
| waiting | Очікування депозиту | Показати адресу для поповнення |
| confirming | Підтвердження мережі | Зачекати 1-2 блоки |
| exchanging | Обмін в процесі | Оновити статус |
| sending | Відправка на гаманець | Чекати підтвердження |
| finished | Завершено | Зарахувати кошти |
| failed | Помилка | Ініціювати повернення |
| refunded | Повернення коштів | Сповістити користувача |
| verifying | KYC потрібен | Запросити документи |
Додатково: налаштуйте алерти на статуси failed та refunded — це скоротить час реакції на інциденти.
Чому варто вибрати ChangeNOW API для гаманця?
ChangeNOW підтримує 850+ монет, включаючи рідкісні активи. Стандартний REST API на HTTPS забезпечує простоту інтеграції. Non-custodial підхід виключає необхідність у ліцензії обмінника. Крім того, реферальна програма повертає 35-40% від маржі — це приємний бонус. Усе це робить ChangeNOW одним із найкращих рішень для додавання обміну в гаманець.
Процес роботи
- Аналітика — вивчаємо вашу архітектуру, вибираємо режими та пари.
- Проектування — розробляємо схему інтеграції, визначаємо ендпоінти та кешування.
- Реалізація — пишемо код на вашому стеку з обробкою всіх граничних випадків.
- Тестування — тестовий період на sandbox-середовищі ChangeNOW з емуляцією помилок.
- Деплой — розгортаємо в production, налаштовуємо моніторинг та алерти.
Що входить в інтеграцію
- Аналіз поточної архітектури та вибір оптимальних режимів (Standard/Fixed Rate).
- Проектування схеми інтеграції з урахуванням кешування та обробки помилок.
- Реалізація модуля на вашому стеку (Python, JS, Go, Rust).
- Тестування на sandbox-середовищі ChangeNOW з емуляцією всіх статусів.
- Деплой в production з налаштуванням моніторингу та webhook-сповіщень.
- Надання документації інтеграції та навчання команди.
Зв'яжіться з нами для безкоштовної оцінки вашого проєкту — допоможемо спроектувати оптимальну архітектуру. Замовте тестовий доступ до нашого готового модуля інтеграції.
Поширені проблеми
- Пропущений extraId. Для мереж XRP, EOS, STELLAR потрібен додатковий ідентифікатор (memo/tag). Без нього депозит не зараховується.
- Некоректна валідація мінімальної суми. Ендпоінт
/v2/exchange/rangeповертає актуальні ліміти — не покладайтеся на хардкод. - Ігнорування статусу
verifying. Якщо потрібен KYC, обмін не перейде вfinishedбез дії з боку провайдера. - Відсутність обробки timeout. Fixed Rate має таймаут — після відправки депозиту курс може змінитися, якщо не вкластися в 2 хвилини.
Ключові ендпоінти ChangeNOW API
Отримання курсу
Приклад коду Python
import httpx
from decimal import Decimal
class ChangeNOWClient:
BASE_URL = "https://api.changenow.io/v2"
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {"x-changenow-api-key": api_key}
async def get_estimated_amount(
self,
from_currency: str, # 'btc'
to_currency: str, # 'eth'
from_amount: float,
flow: str = 'standard' # 'standard' або 'fixed-rate'
) -> dict:
async with httpx.AsyncClient() as client:
response = await client.get(
f"{self.BASE_URL}/exchange/estimated-amount",
params={
"fromCurrency": from_currency.lower(),
"toCurrency": to_currency.lower(),
"fromAmount": str(from_amount),
"flow": flow,
"type": "direct"
},
headers=self.headers
)
data = response.json()
if "error" in data:
raise ChangeNOWError(f"{data['error']}: {data.get('message', '')}")
return {
"estimated_amount": data["toAmount"],
"rate": data["toAmount"] / from_amount,
"min_amount": data.get("minAmount"),
"max_amount": data.get("maxAmount"),
"network_fee": data.get("networkFee")
}
Створення обміну
Приклад коду Python
async def create_exchange(
self,
from_currency: str,
to_currency: str,
from_amount: float,
to_address: str,
refund_address: str = None,
flow: str = 'standard',
user_id: str = None
) -> dict:
payload = {
"fromCurrency": from_currency.lower(),
"toCurrency": to_currency.lower(),
"fromAmount": str(from_amount),
"address": to_address,
"flow": flow,
"type": "direct",
"extraId": "", # memo/tag для XRP, EOS, etc.
}
if refund_address:
payload["refundAddress"] = refund_address
# userId — для відстеження конверсій affiliate
if user_id:
payload["userId"] = user_id
async with httpx.AsyncClient() as client:
response = await client.post(
f"{self.BASE_URL}/exchange",
json=payload,
headers=self.headers
)
data = response.json()
return {
"order_id": data["id"],
"deposit_address": data["payinAddress"],
"deposit_amount": data["fromAmount"],
"receive_amount": data["toAmount"],
"payin_extra_id": data.get("payinExtraId"),
"status": data["status"]
}
Моніторинг статусу
Приклад коду Python
async def get_exchange_status(self, order_id: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.get(
f"{self.BASE_URL}/exchange/by-id",
params={"id": order_id},
headers=self.headers
)
data = response.json()
status_map = {
"waiting": "awaiting_deposit",
"confirming": "confirming",
"exchanging": "processing",
"sending": "sending",
"finished": "completed",
"failed": "failed",
"refunded": "refunded",
"verifying": "kyc_required"
}
return {
"status": status_map.get(data["status"], data["status"]),
"payin_hash": data.get("payinHash"),
"payout_hash": data.get("payoutHash"),
"amount_received": data.get("amountReceived"),
"amount_sent": data.get("amountSent"),
"updated_at": data.get("updatedAt")
}
Список підтримуваних валют
Приклад коду Python
async def get_currencies(self, active: bool = True) -> list[dict]:
async with httpx.AsyncClient() as client:
response = await client.get(
f"{self.BASE_URL}/exchange/currencies",
params={"active": str(active).lower(), "flow": "standard"},
headers=self.headers
)
currencies = response.json()
return [
{
"ticker": c["ticker"],
"name": c["name"],
"network": c.get("network"),
"image": c.get("image"),
"is_stable": c.get("isStable", False)
}
for c in currencies
]
Мінімальні суми та валідація
Приклад коду Python
async def validate_exchange_params(
self,
from_currency: str,
to_currency: str,
from_amount: float
) -> ValidationResult:
range_data = await self.get_range(from_currency, to_currency)
if from_amount < range_data["min_amount"]:
return ValidationResult(
valid=False,
error=f"Amount too small. Min: {range_data['min_amount']} {from_currency.upper()}"
)
if range_data.get("max_amount") and from_amount > range_data["max_amount"]:
return ValidationResult(
valid=False,
error=f"Amount too large. Max: {range_data['max_amount']} {from_currency.upper()}"
)
return ValidationResult(valid=True)
async def get_range(self, from_currency: str, to_currency: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.get(
f"{self.BASE_URL}/exchange/range",
params={"fromCurrency": from_currency, "toCurrency": to_currency, "flow": "standard"},
headers=self.headers
)
data = response.json()
return {"min_amount": data["minAmount"], "max_amount": data.get("maxAmount")}







