tgpay cryptoAPI
crypto-payapiinvoicesrefunds

Справочник API: счета и возвраты

7 мин чтенияОбновлено 2 нояб. 2026 г.

Методы счетов: createInvoice, getInvoices, deleteInvoice, refundInvoice. Общие правила (аутентификация, формат ответа, суммы, spend_id) — на странице Справочник Merchant API; пошаговое введение — Приём платежей через счета.

createInvoice

POST /pay/api/createInvoice — право invoices, лимит 60 в минуту.

ПараметрТипОбязателенЗначение
currency_typestringнетcrypto (по умолчанию) или fiat
assetstringв криптовалютном режимеактив счёта, например USDT. Передавайте вместо fiat
fiatstringв фиатном режимефиатная валюта цены (строки is_fiat из getCurrencies). В криптовалютном режиме игнорируется — чтобы задать цену в фиате, укажите currency_type: "fiat"
accepted_assetsstring / arrayнеттолько фиатный режим: активы, которыми может платить плательщик, — строка через запятую ("USDT,GRAM") или JSON-массив. Не указан — все поддерживаемые активы
amountstringда, если не задан open_amountположительное десятичное число в виде строки: в единицах актива в криптовалютном режиме, в фиатной валюте (не больше 2 знаков в дробной части) в фиатном
open_amountbooleanнетрасширение, только криптовалютный режим: без фиксированной суммы — плательщик вводит её при оплате (пожертвования и чаевые). Нельзя вместе с amount
descriptionstringнетдо 1024 символов, показывается плательщику
hidden_messagestringнетдо 2048 символов, открывается плательщику только после оплаты
payloadstringнетдо 4096 символов ваших данных, возвращаются как есть в счёте и вебхуке
allow_commentsbooleanнетразрешить плательщику комментарий (по умолчанию true)
allow_anonymousbooleanнетразрешить плательщику остаться анонимным (по умолчанию true)
paid_btn_namestringнеткнопка после оплаты: viewItem, openChannel, openBot или callback
paid_btn_urlstringнетhttp(s)-адрес кнопки, до 512 символов — обязателен, когда задан paid_btn_name, без него игнорируется
swap_tostringнетавтоматически обменивать полученные платежи на этот актив. Обмен «по возможности»: если в момент оплаты он невозможен, платёж всё равно проходит без обмена
expires_inintegerнетсекунды до истечения срока действия счёта, до 2678400 (31 день); не указан или 0 — срок по умолчанию, сейчас также 31 день. Фактический срок возвращается в expiration_date
rate_lock_secondsintegerнетрасширение, только фиатный режим: зафиксировать на этот срок курсы конвертации, действовавшие в момент создания (см. ниже)

Описание, сообщение после оплаты и кнопка могут быть скрыты от плательщиков, пока содержимое проверяется или не одобрено. Сам счёт при этом остаётся доступным для оплаты.

Результат — и содержимое вебхука invoice_paid — это объект счёта. Его ключевые поля:

  • Идентификаторы и статус: invoice_id, hash (публичный ID внутри pay_url), status (active / paid / expired), pay_url — ссылка t.me, которую вы отправляете плательщику (bot_invoice_url, mini_app_invoice_url, web_app_invoice_url — её псевдонимы).
  • Суммы: amount (номинал — в фиате у фиатного счёта, иначе в криптовалюте; null, пока счёт со свободной суммой не оплачен), amount_minor (всегда минимальные единицы криптовалюты: у криптовалютного счёта — номинал; у фиатного — null до оплаты, затем минимальные единицы paid_asset; у счёта со свободной суммой — null до оплаты), а у оплаченных фиатных счетов paid_asset / paid_amount / paid_fiat_rate — фактически списанная криптовалюта и использованный курс. asset у фиатного счёта остаётся null и после оплаты.
  • Комиссия: fee_asset / fee_amount, фиксируются при оплате — для учёта используйте именно их (fee и usd_rate — устаревшие псевдонимы Crypto Bot). См. комиссии и лимиты.
  • Плательщик: paid_by_user_id (null, если плательщик выбрал анонимность), paid_anonymously, comment.
  • Возвраты (расширение): refunded_amount / refunded_minor (накопительно) и refunded_at — ставится после полного возврата.
  • Фиксация курса (расширение): rate_lock_until и rate_lock_rates — зафиксированные курсы по каждому принимаемому активу; null, если фиксация не запрашивалась.
  • Время и данные оплаты: created_at, paid_at, paid_usd_rate (курс к USD, зафиксированный при оплате).
  • Параметры создания: currency_type, accepted_assets, open_amount, is_anonymous, description, hidden_message, payload, paid_btn_name / paid_btn_url, expiration_date (expires_at — псевдоним), поля обмена (swap_to, is_swapped, swapped_to, swapped_rate, swapped_output, …).

Ошибки: 400 invalid_currency (в криптовалютном режиме не указан asset; в фиатном — не указан fiat, вместе с ним передан asset или задан open_amount), 400 invalid_amount (в том числе сумма, которая округляется до нуля при точности актива), 400 unknown_asset, 400 unsupported_fiat, 400 paid_btn_url_required, а для запросов фиксации курса — 400 rate_lock_fiat_only, 409 ratelock_disabled, 409 rate_unavailable (нет свежего курса по одному из принимаемых активов — повторите запрос). 400 invalid_request означает некорректные параметры: неизвестный currency_type или paid_btn_name, текст длиннее допустимого, expires_in вне диапазона 0–2678400, сумма, переданная JSON-числом.

Как оплачиваются счета

Плательщик платит с баланса кошелька в Mini App — мгновенно и без комиссии сети, при достаточном балансе и подтверждении платежа. Он может также оплатить счёт из внешнего кошелька: если этот способ доступен, приложение показывает депозитный адрес и срок оплаты. Депозит зачисляется в кошелёк плательщика. Для автоматической оплаты нужны депозит на этот адрес, достаточный доступный баланс, отсутствие ограничений на исходящие платежи и действующие счёт и запрос на оплату. Поздний депозит остаётся в кошельке и сам по себе не означает, что счёт оплачен. В обоих случаях вы видите одно и то же: обычный счёт со статусом paid и событие invoice_paid, если настроен Webhook URL, — никаких дополнительных параметров или полей.

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

Фиксация курса на фиатном счёте

Передайте rate_lock_seconds, чтобы при создании зафиксировать текущий курс каждого принимаемого актива. Пока фиксация действует, плательщик видит именно зафиксированные суммы, а платёж конвертируется по зафиксированному курсу — курсовой риск на этот срок берёте вы. Параметр принимает от 0 до 86400 секунд: 0 — без фиксации, любое другое значение приводится к допустимому сроку — не меньше 60 секунд и не больше платформенного максимума. Значение вне диапазона 0–86400 отклоняется с 400 invalid_request. Фактический срок фиксации возвращается в rate_lock_until.

Когда фиксация заканчивается, действующий счёт можно оплатить по курсу на момент оплаты. Чтобы оба срока совпали, задайте expires_in в допустимом для фиксации диапазоне и сравните expiration_date с rate_lock_until в ответе.

getInvoices

GET /pay/api/getInvoices — право read. Фильтры: asset, fiat, invoice_ids (через запятую), status (active / paid / expired — expired — расширение; active не включает счета, у которых уже истёк срок), плюс offset / count (по умолчанию 100, максимум 1000). Возвращает {"items": [счёт, …]}, новые первыми.

deleteInvoice

POST /pay/api/deleteInvoice — право invoices. Один параметр: invoice_id. Удаляет неоплаченный счёт — активный или истёкший — и возвращает true. Счёт удаляется, а не помечается: он пропадает из getInvoices, его pay_url перестаёт работать, вебхук не отправляется. Если удаление нужно учитывать, фиксируйте его на своей стороне. Ошибки: 404 invoice_not_found, 409 invoice_already_paid — оплаченный счёт удалить нельзя, средства уже переведены.

refundInvoice

POST /pay/api/refundInvoice — право refunds, лимит 30 в минуту. Расширение API Crypto Bot: возвращает всю фактически уплаченную криптосумму или её часть с баланса приложения плательщику, в том числе анонимному, не раскрывая его личность. Для фиатного счёта используйте paid_asset и paid_amount: при возврате фиат не пересчитывается заново.

ПараметрТипОбязателенЗначение
invoice_idintegerдаоплаченный счёт
amountstringнеткриптосумма возврата в активе исходного платежа (paid_asset для фиатного счёта). Не указана — весь невозвращённый остаток. Общая сумма частичных возвратов не может превышать исходную криптосумму платежа
spend_idstringнетключ идемпотентности — используйте его, чтобы повтор после таймаута воспроизвёл результат, а не вернул деньги дважды

Результат — обновлённый объект счёта с накопительными refunded_amount / refunded_minor; refunded_at ставится после полного возврата. Статус остаётся paid. Комиссия платформы не возвращается. На балансе приложения должно хватать исходного актива платежа, даже если swap_to обменял поступление на другой актив. При каждом возврате отправляется вебхук refund_completed, если вы его включили.

Ошибки: 404 invoice_not_found, 409 invoice_not_paid, 409 already_refunded (возвращать больше нечего), 409 amount_too_big (больше невозвращённого остатка), 409 insufficient_funds, 400 invalid_amount, 400 invalid_request (не указан invoice_id, spend_id длиннее 64 символов), 403 verification_required (исходящие операции владельца ограничены), 503 merchant_payouts_paused и две ошибки spend_id — 409 idempotency_conflict / 409 idempotency_in_progress.