SwapZilla не хостит инвойсы — он даёт те два вызова, из которых инвойс состоит. Котировка по сумме счёта, создание ордера — и плательщик получает адрес для оплаты, а средства уходят прямо на кошелёк получателя. Ни мы, ни вы их не держите.
- Плательщик отправляет любой доступный актив, получатель получает тот, в котором выставил счёт.
- Курс фиксируется на время жизни предложения через
rate_type=fixed. - Ваш номер счёта едет вместе с ордером в
client_order_id. - Расчёт некастодиальный: плательщик → обменник → получатель.
Как устроена ссылка на оплату
-
Получатель указывает, что ему должны
Актив, сеть и адрес —
500 USDTв сетиTRC20на собственный кошелёк. Это ваша запись о счёте; SwapZilla узнаёт о ней только в момент, когда появляется плательщик. -
Плательщик открывает ссылку и выбирает монету
GET /v1/assets— честный список того, чем можно заплатить прямо сейчас: активы и сети, за которыми стоит хотя бы один провайдер. Из него и рисуется выбор. -
Котировка по сумме счёта, а не по сумме отправки
Именно этот вызов превращает обмен в инвойс: запрашиваете
amount_to=500— и предложение отвечает точной суммойFromAmount, которую нужно отправить. Добавьтеrate_type=fixed, и это число не изменится, пока идёт оплата. -
Создание ордера
POST /v1/partner/orders: предложение, адрес получателя вto_address, адрес плательщика вrefund_address, ваш номер счёта вclient_order_id. Передайтеexpected_to_amount— и ордер будет отклонён, а не создан, если выплата успела «уехать». -
Показать адрес и следить за ордером
DepositAddressиAmountFrom— это и есть вся страница оплаты: текстом, QR-кодом и с явно названной сетью. ОпрашивайтеGET /v1/partner/orders/{id}раз в 5–10 секунд доDONE; квитанция — этоAmountToReceivedиTxID.
Оба вызова целиком
Котировка счёта на 500 USDT, оплачиваемого в BTC:
curl -sG "https://api.swapzilla.io/v1/partner/quotes" \ -H "X-API-Key: $API_KEY" \ --data-urlencode "from_asset=BTC" \ --data-urlencode "from_network=BITCOIN" \ --data-urlencode "to_asset=USDT" \ --data-urlencode "to_network=TRC20" \ --data-urlencode "amount_to=500" \ --data-urlencode "rate_type=fixed"
Первое предложение — лучшее. Превращаем его в адрес для оплаты:
curl -s -X POST "https://api.swapzilla.io/v1/partner/orders" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"offer_id": "0b0c8f0e-2c1a-4f3f-8f57-2a1d1c4e77aa",
"to_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"refund_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
"client_order_id": "INV-2026-0413",
"expected_to_amount": 500
}'
И цикл, который переводит статусы ордера в состояния счёта:
const terminal = ["DONE", "TIME_EXPIRED", "FAILED", "REFUNDED"];
async function watch(orderID) {
for (;;) {
const r = await fetch(`https://api.swapzilla.io/v1/partner/orders/${orderID}`, {
headers: { "X-API-Key": process.env.API_KEY },
});
const order = await r.json();
await onInvoiceState(order); // ваш собственный учёт
if (terminal.includes(order.Status)) return order;
await new Promise((s) => setTimeout(s, 7000)); // 5–10 с — правильный ритм
}
}
Котировать нужно в момент открытия ссылки, а не в момент выставления счёта. Предложение живёт пять минут. Счёт, отправленный в понедельник и оплаченный в пятницу, котируется в пятницу: ссылка — это ваша страница, а предложение создаётся, когда на неё зашли.
Состояния счёта в терминах статусов ордера
| Статус ордера | Что показывает счёт | Что делаете вы |
|---|---|---|
| NEW WAIT_DEPOSIT | Ожидает оплаты | Показываете адрес и таймер. |
| CONFIRMING | Платёж виден в сети | Останавливаете таймер: со стороны плательщика всё сделано. |
| EXCHANGING SENDING | Идёт расчёт | Ничего — провайдер выполняет выплату. |
| DONE | Оплачен | Закрываете счёт по AmountToReceived, сохраняете TxID как квитанцию. |
| TIME_EXPIRED | Ссылка истекла неоплаченной | Пересчитываете котировку и выдаёте новый адрес. |
| FAILED REFUNDED | Не оплачен | Провайдер возвращает монеты на refund_address — ради этого его и спрашивали у плательщика. |
Чего здесь нет
| Не входит | Что это значит для вас |
|---|---|
| Хостинг страницы счёта и PDF | Ссылка, вёрстка и письма — ваши. API даёт сумму, адрес и статус. |
| Вебхуки | Их пока нет — опрашивайте ордер раз в 5–10 секунд до финального статуса. |
| Фиат | Крипта на входе, крипта на выходе. Счёт в евро — это ваш собственный источник курса, переводящий сумму в стейблкоин перед котировкой. |
| Частичная и повторная оплата | Один ордер принимает один платёж на одну сумму. Разбитый на части счёт — это несколько ордеров. |
| Инициация возврата | Возврат делает провайдер на refund_address, если обмен не удался; вызова, отменяющего проведённый платёж, нет. |
Кто так выставляет счета
- Фрилансеры, работающие с зарубежными заказчиками. Клиент платит тем, что у него есть; счёт закрывается в USDT в той сети, которой действительно пользуется кошелёк исполнителя.
- Студии и агентства со счетами по этапам: каждый этап — свой ордер и свой
client_order_id. - Платформы, выставляющие счета от имени своих пользователей: адрес получателя — пользовательский, поэтому платформа не держит клиентские деньги и не становится должником по ним.
- Все, кому платят из другой сети: BTC плательщика и USDT TRC20 получателя не обязаны встречаться в одном блокчейне.
Вопросы
Можно ли сделать бессрочную ссылку на оплату?
Ссылка может жить сколько угодно, предложение — нет. Предложения истекают через пять минут после котировки, поэтому долгоживущая ссылка ведёт на вашу страницу, которая считает котировку и создаёт ордер в момент прихода плательщика. Адрес для оплаты появляется тогда же, а не при выставлении счёта.
Держит ли SwapZilla деньги в процессе?
Нет. Обмен некастодиальный: плательщик отправляет средства на депозитный адрес провайдера, провайдер выплачивает на адрес получателя. Ни SwapZilla, ни ваша платформа не владеют средствами — поэтому и вызова на выплату не существует.
Как добиться, чтобы получатель получил ровно сумму счёта?
Котируйте через amount_to, а не amount_from, запрашивайте rate_type=fixed и передавайте expected_to_amount при создании ордера: если пересчитанная выплата больше не совпадает с обещанной в счёте, ордер будет отклонён, а не создан.
Что будет, если плательщик отправит не ту сумму?
Провайдер обрабатывает это по своим правилам: недоплата обычно возвращается на refund_address, переплата либо обменивается по текущему курсу, либо возвращается. Поэтому адрес для возврата у плательщика стоит спрашивать до создания ордера.
В каких монетах можно оплатить счёт?
В тех, что перечисляет GET /v1/assets на текущий момент: топ-100 активов по капитализации с сетями и провайдерами, которые их сейчас обслуживают. Актив зачисления получателю берётся из того же списка.
Нужен ли ключ, чтобы попробовать?
Для котировок и ордеров — да; /v1/assets, /v1/providers и /v1/validate-address отвечают и без него. Ключ выдаёт администратор SwapZilla, и используется он в заголовке X-API-Key с вашего сервера, а не из браузера.
Что ещё собирают на этом же ключе
- Крипто-процессинг и эквайринг для бизнесаЧекаут для магазинов и SaaS: приём 100+ активов, зачисление в одном, сверка по вашему order id.
- API обмена криптовалют, SDK и виджетОбмен внутри кошелька, бота, агрегатора или сайта: стриминг котировок, один вызов на ордер, ваш интерфейс.
- Крипто-payroll для подрядчиков и распределённых командРегулярные выплаты реестру подрядчиков: свой актив и сеть у каждого, точная сумма на руки, сверка по периодам.
- Multi-send: массовые выплаты на множество адресовРазовая веерная рассылка выплат на сотни адресов: кросс-чейн, статус по каждому, безопасные повторы.
- Свой MCP-сервер для ИИ-агентовГотовый swapzilla-mcp одной строкой — или свой, на вашем партнёрском ключе, с белыми списками и лимитами.
- Стриминг котировок, живые курсы и price alertsSSE-стрим котировок, всегда свежий фид курсов и отслеживание ордеров — основа для алертов.
Как получить ключ
Зарегистрируйтесь в партнёрском кабинете — партнёрский id и api_key для заголовка X-API-Key выпускаются сразу. Ключ становится рабочим после активации: напишите в @swapzilla_support_bot и коротко опишите интеграцию. Все эндпоинты, поля и статусы — в документации partner API.