При недоплате нельзя автоматически выдавать заказ, а при переплате нельзя автоматически отправлять возврат. Сначала подтвердите сеть, настоящий контракт токена, адрес получателя, статус и сумму транзакции. Затем примените заранее записанное правило и оформите один однозначный результат.

В GramPayBot ожидается точная сумма. Меньший перевод классифицируется как частичный, больший — как переплата; ни один из них незаметно не становится обычным оплаченным инвойсом.

Таблица решений

Проверенный результатСтатус для решенияТипичное действие
Получена точная ожидаемая суммаМожно штатно сопоставить после подтвержденияИсполнить после статуса paid
Получено меньшеНедоплата / частичная оплатаЗафиксировать разницу и дать инструкцию
Получено большеПереплатаРешить, принять ли, зачесть или вернуть излишек
С инвойсом связаны несколько переводовНеоднозначная ситуацияПроверить каждый хеш вручную
Неверны токен, сеть или получательЭто не оплата данного инвойсаПерейти к сценарию ошибки маршрута

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

BTCPay Server также отделяет частично оплаченные и переплаченные счета от обычного settled-инвойса. В традиционных платежах Stripe отдельно учитывает остаток и переплату. Это не заменяет правила вашего бизнеса, но показывает, зачем исключениям нужны собственные состояния.

Почему возникает недоплата

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

Комиссии вывода работают по-разному и меняются. Binance, например, сообщает, что комиссия вывода динамическая и показывается на странице вывода. Поэтому нельзя обещать универсальное «сеть всегда вычитает комиссию из суммы». Покупатель должен проверить финальное превью и убедиться, что получателю придёт точная сумма.

Почему возникает переплата

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

В интерфейсе USDT и USDC отображаются десятичными числами, но on-chain значение хранится в целых минимальных единицах. В официальном примере Circle показана обработка USDC с шестью десятичными знаками. Интеграция должна детерминированно преобразовывать единицы, а не сравнивать приблизительные числа с плавающей точкой.

Сначала проверьте сам перевод

  1. Откройте исходный хеш в обозревателе нужной сети.
  2. Убедитесь, что транзакция успешна и достаточно подтверждена.
  3. Проверьте контракт или mint, а не только тикер USDT/USDC.
  4. Сравните полный адрес получателя с инвойсом.
  5. Возьмите сумму из события token transfer или изменения баланса.
  6. Сравните её со всей точной суммой checkout.
  7. Проверьте, не привязан ли другой перевод к этому инвойсу.
  8. Сопоставьте время блока со сроком действия.

Если контракт неправильный, это не просто недоплата или переплата, а другой актив. Используйте инструкцию проверки контрактов USDT и USDC.

После проверки привяжите каждый принятый хеш ровно к одному инвойсу и заказу. Инструкция по сопоставлению платежей с заказами показывает, как сохранить эту связь без скриншотов и Telegram username.

Точное сопоставление в GramPayBot

GramPayBot заранее фиксирует ожидаемые сеть, токен, получателя и сумму. Текущая сумма на checkout содержит не более четырёх знаков после запятой и может включать идентифицирующий дробный хвост. Поэтому надо отправить всё показанное число — например, 180.0134 USDT, а не округлённые 180 USDT. У USDT или USDC в блокчейне может быть шесть десятичных разрядов базовых единиц, но это не означает, что GramPayBot показывает шестизначный хвост инвойса.

  • точный подтверждённый перевод может оплатить инвойс;
  • меньший классифицируется как partial;
  • больший — как overpaid;
  • несколько подходящих или уже использованный перевод не считаются чистым совпадением.

Обычный matcher не складывает произвольный второй перевод с первым как автоматическую «доплату». Не просите клиента просто отправить остаток на адрес без нового явного сценария.

Сценарий для недоплаты

1. Рассчитайте подтверждённую разницу

недоплата = точная сумма инвойса − подтверждённая полученная сумма

Сохраните оба числа со всеми знаками в единицах токена.

2. Остановите исполнение

Не помечайте заказ оплаченным только потому, что пришла большая часть. Иначе сотрудники начнут по-разному принимать одинаковые отклонения.

3. Выберите один вариант

  • принять недоплату вручную как скидку или списание;
  • создать новый отдельный инвойс на остаток;
  • отменить исполнение и вернуть подтверждённую сумму;
  • передать случай в поддержку или compliance.

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

4. Сообщите результат покупателю

Укажите полученную сумму, разницу, принятое решение и ID нового инвойса или возврата. Сообщение «платёж неполный» без следующего шага бесполезно.

Сценарий для переплаты

1. Исключите дубль и чужой перевод

Проверьте, была ли одна транзакция с лишней суммой или две транзакции, и не относится ли один хеш к другому заказу.

2. Отделите сумму инвойса от излишка

переплата = подтверждённая полученная сумма − точная сумма инвойса

Не меняйте исходную сумму задним числом, чтобы получить красивое равенство.

3. Примените правило

  • принять инвойс вручную и вернуть излишек;
  • зачислить излишек в согласованный клиентский баланс;
  • принять всю сумму как осознанные чаевые или дополнительную покупку;
  • вернуть весь перевод и выставить счёт заново.

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

4. Отдельно подтвердите адрес возврата

Не отправляйте излишек автоматически на on-chain адрес отправителя. Биржа могла выполнить вывод из общего кошелька, который не зачисляет входящие возвраты конкретному пользователю.

Аутентифицируйте клиента через исходный заказ, запросите адрес в той же сети, подтвердите комиссии и сохраните хеш исходящей транзакции. Возврат — новый перевод, а не отмена старого.

Какие правила определить заранее

  • допустима ли погрешность недоплаты и как она считается;
  • разрешены ли отдельные инвойсы на остаток;
  • минимальный экономически разумный возврат с учётом комиссии;
  • поддерживается ли клиентский кредит;
  • кто согласует ручное принятие и возврат;
  • как обрабатываются дубли;
  • сколько хранится журнал исключений.

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

Инструкция покупателю

  1. Открыть актуальный инвойс, а не адрес из старого сообщения.
  2. Выбрать точно указанные токен и сеть.
  3. Скопировать сумму со всеми десятичными знаками.
  4. Проверить, уменьшает ли биржа сумму получателя на комиссию.
  5. Сверить recipient amount на финальном экране.
  6. Отправить один раз и сохранить хеш.
  7. Остановиться и написать продавцу, если уже был тестовый платёж или срок истёк.

Полный процесс описан в статье как оплатить инвойс в USDT или USDC.

Журнал исключения

Сохраните ID инвойса и заказа, ожидаемый маршрут и сумму, все связанные хеши, подтверждённую сумму каждого перевода, разницу, сроки, способ проверки клиента, решение и согласовавшего, а также ссылку на новый инвойс, кредит или возврат.

Это не даёт учесть один перевод дважды и позволяет другому сотруднику воспроизвести решение.

Частые вопросы

Завершит ли второй платёж недоплаченный инвойс автоматически?

Не рассчитывайте на это. Штатный matcher ожидает один точный перевод и не складывает произвольные частичные транзакции. Дождитесь нового инвойса или явной инструкции продавца.

Можно ли округлить сумму checkout?

Нет. Отправляйте полное число: дробные знаки могут участвовать в идентификации инвойса.

Переплаченный инвойс автоматически считается оплаченным?

Нет. Это исключение для ручной проверки.

Возвращать на адрес отправителя?

Не автоматически. Сначала подтвердите клиента и подходящий адрес возврата, особенно если платёж пришёл с биржи.

Настоящий перевод USDT доказывает оплату заказа?

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

Следующий шаг

Создайте отслеживаемую ссылку на оплату

Выставьте счёт в USDT или USDC вручную, отправьте hosted checkout и отслеживайте статус без API.

Ссылки на оплату →