Задать вопрос

Ton — Connect UI, подключаем к фреймворку, есть ошибки при оплате, как решить?

Взялся я тут как-то на досуге подключить к сайту оплату через экосистему тон.

Пал мой глаз на: Connect UI.
Для начала делается авторизация кошелька через Connect UI, а уже потом проводиться транзакция оплаты через привязанный кошелек. Авторизация кошелька прошла на ура, там проблем особо нет, все просто.

После авторизации, нажимаем кнопку оплатить, полученные данные уходят через js.
Пробовал оплату на тонкипере, подключил кошелек кипера, нажал кнопку оплатить, в тонкипере появилась транзакция, но с ошибкой, (User has already opened the previous request).

А в консоле на сайте, мне вывело такую ошибку.
[TON_CONNECT_SDK_ERROR] B: User rejects the action in the wallet. User has already opened the previous request

Что у меня происходит при клике на кнопку оплатить.
<a href="#" title="Оплатить подписку" style='display:none' class="tza buy" id='payment-button'> Оплатить</a>


Первый скрипт: (отправляю запрос в контроллер и от туда приходят данные), которые уходят с транзакцией при оплате.

Данные с контроллера приходят такие, ошибки вроде нет:
67d07cad9e7d9964790819.jpeg

$(document).on('click', 'a.tza', function(e) {
  e.preventDefault();
  let id = $(this).attr("data-id");
  let axresult = $(this).siblings('.ax-result');
  let $this = $(this); // Сохраняем ссылку на кнопку

  // Блокируем кнопку, чтобы предотвратить повторные нажатия
  $this.prop('disabled', true);

  $(axresult, '.ax-result').removeClass('validdone validerror').html('');

  let formData = new FormData();
  formData.append('id', id);

  App.sendAx('/ax/pool/buy', formData, {
    silence: true,

    successFunction: function(d) {
      axresult.removeClass('validdone validerror').addClass('validdone').html(d.message);

      // Проверяем, что данные для транзакции существуют
      // Если сервер вернул данные для транзакции, инициируем оплату через TonConnect
      if (!d.transaction) {
        axresult.removeClass('validdone').addClass('validerror').html(
          'Ошибка: данные для транзакции отсутствуют');
        $this.prop('disabled', false); // Разблокируем кнопку
        return;
      }

      // Сохраняем данные транзакции в глобальной переменной
      window.transactionData = {
        validUntil: Math.floor(Date.now() / 1000) + 60, // транзакция действительна 60 секунд
        messages: [{
          address: d.transaction.recipient, // адрес получателя
          amount: d.transaction.amount, // сумма в нанотонах
          payload: d.transaction.payload // опциональный payload
        }]
      };

      // Проверяем, подключён ли кошелёк
      if (!tonConnectUI.connected) {
        // Если кошелёк не подключён, показываем кнопку "Connect Wallet"
        axresult.html('Пожалуйста, подключите кошелёк, чтобы продолжить оплату.');
        tonConnectButton.show();

        // Ждём подключения кошелька
        tonConnectUI.onStatusChange(wallet => {
          console.log('Статус кошелька:', wallet); // Отладка: выводим статус кошелька
          if (wallet) {
            // Кошелёк подключён, отправляем транзакцию
            axresult.html('Кошелёк подключён, выполняем оплату...');
            sendTransaction(id, axresult, $this); // Передаем кнопку для разблокировки
          }
        });
      } else {
        // Кошелёк уже подключён, сразу отправляем транзакцию
        axresult.html('Кошелёк уже подключён, выполняем оплату...');
        sendTransaction(id, axresult, $this); // Передаем кнопку для разблокировки
      }
    },
    errorFunction: function(d) {
      axresult.removeClass('validdone validerror').addClass('validerror').html(d.message);
      $this.prop('disabled', false); // Разблокируем кнопку
    }
  });
});


Вторая функция, которая отправляет и проверяет на ошибки, и отправляет в контроллер, если все ок, там сверяет и записываем в таблицу, что оплата прошла.

function sendTransaction(id, axresult, $button) {
  tonConnectUI.sendTransaction(window.transactionData)
    .then((result) => {
      axresult.html('Оплата успешно выполнена, подтверждаем...');

      // Отправляем запрос на сервер для подтверждения оплаты
      let confirmData = new FormData();
      confirmData.append('transaction_hash', result.boc); // Хэш транзакции (boc — закодированные данные)
      confirmData.append('pool_id', id);

      App.sendAx('/ax/pool/confirm_payment', confirmData, {
        silence: true,
        successFunction: function(confirmResponse) {
          axresult.removeClass('validdone validerror').addClass('validdone').html(confirmResponse.message);
          /*    // Скрываем кнопку "Connect Wallet" после успешной оплаты
             $('#ton-connect').hide(); */
        },
        errorFunction: function(confirmResponse) {
          axresult.removeClass('validdone validerror').addClass('validerror').html(confirmResponse.message);
        }
      });
    })
    .catch((error) => {
      console.error('Ошибка TonConnect UI:', error); // Отладка: выводим полную ошибку
      axresult.removeClass('validdone').addClass('validerror').html('Ошибка оплаты: ' + error.message);
      $button.prop('disabled', false); // Разблокируем кнопку в случае ошибки

      // Если ошибка связана с "зависшим" запросом, предлагаем пользователю переподключить кошелек
      if (error.message.includes("User has already opened the previous request")) {
        axresult.html('Ошибка: в кошельке остался незакрытый запрос. Пожалуйста, переподключите кошелёк.');
        tonConnectUI.disconnect().then(() => {
          axresult.html('Кошелёк отключён. Пожалуйста, подключите его заново.');
          tonConnectButton.show();
        });
      }
    })
    .finally(() => {
      $button.prop('disabled', false); // Разблокируем кнопку после завершения
    });
}
  • Вопрос задан
  • 41 просмотр
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы