From 6b3f27578128eb1c920f20ac524f557ca14960c0 Mon Sep 17 00:00:00 2001 From: slava Date: Tue, 19 May 2026 19:18:43 +0500 Subject: [PATCH] =?UTF-8?q?Handle=20immediate=20payment=20completion=20and?= =?UTF-8?q?=20error=20screen=20scenarios=20in=20`PayByPhoneScript`=20and?= =?UTF-8?q?=20`PayByCardScript`.=20Adjust=20flow=20to=20skip=20redundant?= =?UTF-8?q?=20steps=20on=20early=20success=20and=20improve=20error=20detec?= =?UTF-8?q?tion=20after=20"=D0=94=D0=B0=D0=BB=D0=B5=D0=B5".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/dushanbe/PayByCardScript.cpp | 32 ++++++++++++++++++++++----- android/dushanbe/PayByPhoneScript.cpp | 32 ++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/android/dushanbe/PayByCardScript.cpp b/android/dushanbe/PayByCardScript.cpp index 0d85b12..1be5522 100644 --- a/android/dushanbe/PayByCardScript.cpp +++ b/android/dushanbe/PayByCardScript.cpp @@ -307,11 +307,33 @@ void PayByCardScript::makePayment( AdbUtils::makeTap(deviceId, daleeBtn.x(), daleeBtn.y()); QThread::msleep(2000); - // 8. После "Далее" кнопка меняется на "Оплатить" — ждём и нажимаем + // 8. После "Далее" возможны три исхода: + // a) кнопка меняется на "Оплатить" → обычный поток (8 → 9 → 10); + // b) платёж проходит мгновенно, минуя bottom sheet → сразу "Платеж выполнен"; + // c) экран ошибки. + // earlySuccess=true означает b — шаги 9 и 10 пропускаем, идём сразу к парсингу чека. bool oplatitFound = false; + bool earlySuccess = false; for (int attempt = 0; attempt < 10; ++attempt) { xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(deviceId, width, height); + + if (!xmlScreenParser.findNodeByContentDesc( + QString::fromUtf8("Платеж выполнен"), true).isEmpty()) { + qDebug() << "[Dushanbe::PayByCard] Payment completed immediately after 'Далее'"; + oplatitFound = true; + earlySuccess = true; + break; + } + if (!xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Ошибка"), true).isEmpty() || + !xmlScreenParser.findTextNode(QString::fromUtf8("Ошибка")).isEmpty()) { + m_error = "Transfer failed: error screen detected after 'Далее'"; + qWarning() << "[Dushanbe::PayByCard]" << m_error; + AppLogger::log("dushanbe/PayByCard", deviceId, m_error, + AdbUtils::captureScreenshotBytes(deviceId), "CREATE_TRANSACTION"); + return; + } + Node oplatitBtn = xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Оплатить")); if (oplatitBtn.isEmpty()) { oplatitBtn = xmlScreenParser.findButtonNode(QString::fromUtf8("Оплатить"), false); @@ -338,8 +360,8 @@ void PayByCardScript::makePayment( // 9. Ждём bottom sheet "Подтверждение платежа" и тапаем "Подтверждаю" // content-desc содержит "Подтверждение платежа...Подтверждаю" // Кнопка "Подтверждаю" визуально внизу bottom sheet - bool confirmed = false; - for (int attempt = 0; attempt < 10; ++attempt) { + bool confirmed = earlySuccess; + for (int attempt = 0; !earlySuccess && attempt < 10; ++attempt) { xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(deviceId, width, height); @@ -391,8 +413,8 @@ void PayByCardScript::makePayment( // 10. Ждём результат — "Платеж выполнен" или ошибку. // Промежуточный статус "Выполняется" может висеть до ~1.5 мин, пока банк // подтверждает перевод, поэтому общий таймаут — 60 итераций × 2 сек = 2 мин. - bool success = false; - for (int attempt = 0; attempt < 60; ++attempt) { + bool success = earlySuccess; + for (int attempt = 0; !earlySuccess && attempt < 60; ++attempt) { xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(deviceId, width, height); diff --git a/android/dushanbe/PayByPhoneScript.cpp b/android/dushanbe/PayByPhoneScript.cpp index 85f06af..16de45a 100644 --- a/android/dushanbe/PayByPhoneScript.cpp +++ b/android/dushanbe/PayByPhoneScript.cpp @@ -307,11 +307,33 @@ void PayByPhoneScript::makePayment( AdbUtils::makeTap(deviceId, daleeBtn.x(), daleeBtn.y()); QThread::msleep(2000); - // 8. После "Далее" кнопка меняется на "Оплатить" + // 8. После "Далее" возможны три исхода: + // a) кнопка меняется на "Оплатить" → обычный поток (8 → 9 → 10); + // b) платёж проходит мгновенно, минуя bottom sheet → сразу "Платеж выполнен"; + // c) экран ошибки. + // earlySuccess=true означает b — шаги 9 и 10 пропускаем, идём сразу к парсингу чека. bool oplatitFound = false; + bool earlySuccess = false; for (int attempt = 0; attempt < 10; ++attempt) { xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(deviceId, width, height); + + if (!xmlScreenParser.findNodeByContentDesc( + QString::fromUtf8("Платеж выполнен"), true).isEmpty()) { + qDebug() << "[Dushanbe::PayByPhone] Payment completed immediately after 'Далее'"; + oplatitFound = true; + earlySuccess = true; + break; + } + if (!xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Ошибка"), true).isEmpty() || + !xmlScreenParser.findTextNode(QString::fromUtf8("Ошибка")).isEmpty()) { + m_error = "Transfer failed: error screen detected after 'Далее'"; + qWarning() << "[Dushanbe::PayByPhone]" << m_error; + AppLogger::log("dushanbe/PayByPhone", deviceId, m_error, + AdbUtils::captureScreenshotBytes(deviceId), "CREATE_TRANSACTION"); + return; + } + Node oplatitBtn = xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Оплатить")); if (oplatitBtn.isEmpty()) { oplatitBtn = xmlScreenParser.findButtonNode(QString::fromUtf8("Оплатить"), false); @@ -336,8 +358,8 @@ void PayByPhoneScript::makePayment( } // 9. Ждём bottom sheet "Подтверждение платежа" и тапаем "Подтверждаю" - bool confirmed = false; - for (int attempt = 0; attempt < 10; ++attempt) { + bool confirmed = earlySuccess; + for (int attempt = 0; !earlySuccess && attempt < 10; ++attempt) { xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(deviceId, width, height); @@ -387,8 +409,8 @@ void PayByPhoneScript::makePayment( // 10. Ждём результат — "Платеж выполнен" или ошибку. // Промежуточный статус "Выполняется" может висеть до ~1.5 мин, пока банк // подтверждает перевод, поэтому общий таймаут — 60 итераций × 2 сек = 2 мин. - bool success = false; - for (int attempt = 0; attempt < 60; ++attempt) { + bool success = earlySuccess; + for (int attempt = 0; !earlySuccess && attempt < 60; ++attempt) { xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter)); closeGooglePlayBannerIfVisible(deviceId, width, height);