Add PayByCardScript implementation and XML asset for payment automation in Ozon
Implemented `PayByCardScript` to enable automated card payments on the Ozon platform. Includes ad banner detection/handling, OCR-based transaction ID extraction, fee calculation, and database updates for transactions. Added XML asset `pay_by_card_success.xml` for payment result handling.
This commit is contained in:
parent
f95dabca77
commit
23d404b9c5
375
android/ozon/PayByCardScript.cpp
Normal file
375
android/ozon/PayByCardScript.cpp
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
#include "PayByCardScript.h"
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QTimeZone>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <tesseract/baseapi.h>
|
||||||
|
#include <leptonica/allheaders.h>
|
||||||
|
|
||||||
|
#include "adb/AdbUtils.h"
|
||||||
|
#include "dao/AccountDAO.h"
|
||||||
|
#include "dao/ApplicationDAO.h"
|
||||||
|
#include "dao/DeviceDAO.h"
|
||||||
|
#include "dao/TransactionDAO.h"
|
||||||
|
#include "time/DateUtils.h"
|
||||||
|
|
||||||
|
static QString recognizeTextFromImage(const QByteArray &pngData) {
|
||||||
|
auto *api = new tesseract::TessBaseAPI();
|
||||||
|
if (api->Init(nullptr, "rus+eng")) {
|
||||||
|
qWarning() << "[OCR] Failed to init Tesseract";
|
||||||
|
delete api;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Pix *pix = pixReadMem(reinterpret_cast<const l_uint8 *>(pngData.constData()),
|
||||||
|
static_cast<size_t>(pngData.size()));
|
||||||
|
if (!pix) {
|
||||||
|
qWarning() << "[OCR] Failed to read image";
|
||||||
|
api->End();
|
||||||
|
delete api;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
api->SetImage(pix);
|
||||||
|
char *text = api->GetUTF8Text();
|
||||||
|
QString result = QString::fromUtf8(text).trimmed();
|
||||||
|
delete[] text;
|
||||||
|
pixDestroy(&pix);
|
||||||
|
api->End();
|
||||||
|
delete api;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString extractTransactionId(const QString &ocrText) {
|
||||||
|
// "ID операции A60130542076330K0000040011670301" или "ID операции = Аб60650..."
|
||||||
|
QRegularExpression reId(R"(ID\s+операции\s*=?\s*([A-Za-zА-Яа-я0-9]+))");
|
||||||
|
if (auto m = reId.match(ocrText); m.hasMatch()) return m.captured(1);
|
||||||
|
|
||||||
|
// "№ Ф-2026-25235663"
|
||||||
|
QRegularExpression reRef(R"(№\s*(Ф-[\d-]+))");
|
||||||
|
if (auto m = reRef.match(ocrText); m.hasMatch()) return m.captured(1);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Ozon {
|
||||||
|
|
||||||
|
PayByCardScript::PayByCardScript(
|
||||||
|
AccountInfo account,
|
||||||
|
QString cardNumber,
|
||||||
|
const double amount,
|
||||||
|
QObject *parent
|
||||||
|
) : CommonScript(parent),
|
||||||
|
m_account(std::move(account)), m_cardNumber(std::move(cardNumber)),
|
||||||
|
m_amount(amount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PayByCardScript::~PayByCardScript() = default;
|
||||||
|
|
||||||
|
void PayByCardScript::doStart() {
|
||||||
|
const DeviceInfo device = DeviceDAO::getDeviceById(m_account.deviceId);
|
||||||
|
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
||||||
|
|
||||||
|
if (device.id.isEmpty() || app.id == -1) {
|
||||||
|
m_error = "Device or app not found: " + m_account.deviceId;
|
||||||
|
qCritical() << m_error;
|
||||||
|
emit finishedWithResult(m_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
||||||
|
|
||||||
|
// Закрываем рекламный bottom sheet
|
||||||
|
if (Node adNode = xmlScreenParser.tryToFindAdBanner(); !adNode.isEmpty()) {
|
||||||
|
qDebug() << "[PayByCard] Ad banner detected, closing...";
|
||||||
|
AdbUtils::makeTap(device.id, adNode.x(), adNode.y());
|
||||||
|
QThread::msleep(1000);
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если не на домашнем экране — перезапускаем
|
||||||
|
if (!xmlScreenParser.isHomeScreen()) {
|
||||||
|
qDebug() << "[PayByCard] Not on home screen, restarting app...";
|
||||||
|
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode,
|
||||||
|
device.screenWidth, device.screenHeight)) {
|
||||||
|
m_error = "Cannot reach home screen: " + device.id;
|
||||||
|
qWarning() << m_error;
|
||||||
|
AdbUtils::tryToKillApplication(device.id, app.package);
|
||||||
|
emit finishedWithResult(m_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Закрываем баннеры
|
||||||
|
tryToCloseAllBannersOnHomePage(device.id, device.screenWidth, device.screenHeight);
|
||||||
|
QThread::msleep(500);
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
||||||
|
|
||||||
|
// Закрываем баннер Google Play "Доступно обновление"
|
||||||
|
if (Node gpNode = xmlScreenParser.tryToFindGooglePlayBanner(); !gpNode.isEmpty()) {
|
||||||
|
qDebug() << "[PayByCard] Google Play update banner detected, closing...";
|
||||||
|
AdbUtils::makeTap(device.id, gpNode.x(), gpNode.y());
|
||||||
|
QThread::msleep(1500);
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Закрываем баннер "Заказать карту" — тапаем сверху экрана
|
||||||
|
if (Node orderCardNode = xmlScreenParser.findTextNode("Заказать карту"); !orderCardNode.isEmpty()) {
|
||||||
|
qDebug() << "[PayByCard] 'Заказать карту' banner detected, closing...";
|
||||||
|
AdbUtils::makeTap(device.id, device.screenWidth / 2, 100);
|
||||||
|
QThread::msleep(1000);
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(device.id, ++m_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
makePayment(device.id, app.pinCode, device.screenWidth, device.screenHeight);
|
||||||
|
|
||||||
|
emit finishedWithResult(m_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PayByCardScript::makePayment(
|
||||||
|
const QString &deviceId,
|
||||||
|
const QString &pinCode,
|
||||||
|
const int width,
|
||||||
|
const int height
|
||||||
|
) {
|
||||||
|
// 1. Нажимаем "Перевести" на домашнем экране
|
||||||
|
Node transferBtn = xmlScreenParser.findButtonNode("Перевести", false);
|
||||||
|
if (transferBtn.isEmpty()) {
|
||||||
|
m_error = "Кнопка 'Перевести' не найдена на домашнем экране";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[PayByCard] Tapping 'Перевести'...";
|
||||||
|
AdbUtils::makeTap(deviceId, transferBtn.x(), transferBtn.y());
|
||||||
|
QThread::msleep(2000);
|
||||||
|
|
||||||
|
// 2. Ждём экран "Платежи и переводы"
|
||||||
|
bool paymentsPageLoaded = false;
|
||||||
|
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
Node title = xmlScreenParser.findTextNode("Платежи и переводы");
|
||||||
|
if (!title.isEmpty()) {
|
||||||
|
paymentsPageLoaded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qDebug() << "[PayByCard] Waiting for 'Платежи и переводы', attempt" << attempt + 1 << "/ 10";
|
||||||
|
QThread::msleep(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!paymentsPageLoaded) {
|
||||||
|
m_error = "Экран 'Платежи и переводы' не загрузился";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Нажимаем "По номеру карты" в секции "ДРУГИЕ СПОСОБЫ"
|
||||||
|
Node cardBtn = xmlScreenParser.findButtonNode("По номеру карты", false);
|
||||||
|
if (cardBtn.isEmpty()) {
|
||||||
|
m_error = "Кнопка 'По номеру карты' не найдена на экране платежей";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[PayByCard] Tapping 'По номеру карты'...";
|
||||||
|
AdbUtils::makeTap(deviceId, cardBtn.x(), cardBtn.y());
|
||||||
|
QThread::msleep(2000);
|
||||||
|
|
||||||
|
// 4. Ждём экран "Перевод по номеру карты"
|
||||||
|
bool cardScreenLoaded = false;
|
||||||
|
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
Node title = xmlScreenParser.findTextNode("Перевод по номеру карты");
|
||||||
|
if (!title.isEmpty()) {
|
||||||
|
cardScreenLoaded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qDebug() << "[PayByCard] Waiting for 'Перевод по номеру карты', attempt" << attempt + 1 << "/ 10";
|
||||||
|
QThread::msleep(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cardScreenLoaded) {
|
||||||
|
m_error = "Экран 'Перевод по номеру карты' не загрузился";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[PayByCard] Card payment screen loaded successfully";
|
||||||
|
|
||||||
|
// 5. Вводим номер карты в поле "Номер карты получателя"
|
||||||
|
Node cardInput = xmlScreenParser.findEditTextByHint("Номер карты получателя");
|
||||||
|
if (cardInput.isEmpty()) {
|
||||||
|
m_error = "Поле 'Номер карты получателя' не найдено";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdbUtils::makeTap(deviceId, cardInput.x(), cardInput.y());
|
||||||
|
QThread::msleep(500);
|
||||||
|
AdbUtils::inputText(deviceId, m_cardNumber);
|
||||||
|
QThread::msleep(2000);
|
||||||
|
|
||||||
|
// 6. Ждём распознавания карты и вводим сумму
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
|
||||||
|
Node sumInput = xmlScreenParser.findEditTextByHint("Сумма от");
|
||||||
|
if (sumInput.isEmpty()) {
|
||||||
|
m_error = "Поле ввода суммы не найдено";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdbUtils::makeTap(deviceId, sumInput.x(), sumInput.y());
|
||||||
|
QThread::msleep(500);
|
||||||
|
AdbUtils::inputText(deviceId, QString::number(static_cast<int>(m_amount)));
|
||||||
|
QThread::msleep(1000);
|
||||||
|
|
||||||
|
qDebug() << "[PayByCard] Card number and amount entered";
|
||||||
|
|
||||||
|
// 7. Ждём расчёта комиссии (текст после "Комиссия" перестаёт быть "Рассчитаем...")
|
||||||
|
double fee = 0;
|
||||||
|
bool feeCalculated = false;
|
||||||
|
for (int attempt = 0; attempt < 15; ++attempt) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
|
||||||
|
bool foundKomissiya = false;
|
||||||
|
for (const Node &node : xmlScreenParser.findAllNodes()) {
|
||||||
|
if (node.className == "android.widget.TextView" && node.text.trimmed() == "Комиссия") {
|
||||||
|
foundKomissiya = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (foundKomissiya && node.className == "android.widget.TextView" && !node.text.isEmpty()) {
|
||||||
|
const QString feeText = node.text.trimmed();
|
||||||
|
if (feeText.startsWith("Рассчитаем")) {
|
||||||
|
foundKomissiya = false;
|
||||||
|
break; // ещё не рассчитана
|
||||||
|
}
|
||||||
|
// Парсим "45 ₽" → 45.0
|
||||||
|
QString digits = feeText;
|
||||||
|
digits.remove(QRegularExpression("[^0-9,\\.]"));
|
||||||
|
digits.replace(',', '.');
|
||||||
|
fee = digits.toDouble();
|
||||||
|
feeCalculated = true;
|
||||||
|
qDebug() << "[PayByCard] Fee parsed:" << fee << "from text:" << feeText;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (feeCalculated) break;
|
||||||
|
qDebug() << "[PayByCard] Waiting for fee calculation, attempt" << attempt + 1 << "/ 15";
|
||||||
|
QThread::msleep(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!feeCalculated) {
|
||||||
|
qWarning() << "[PayByCard] Fee not calculated after timeout, proceeding with fee=0";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. Нажимаем "Перевести" (или "Перевести X ₽")
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
Node transferBtn2 = xmlScreenParser.findButtonNode("Перевести", true);
|
||||||
|
if (transferBtn2.isEmpty()) {
|
||||||
|
m_error = "Кнопка 'Перевести' не найдена на экране ввода суммы";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[PayByCard] Tapping transfer button:" << transferBtn2.text;
|
||||||
|
AdbUtils::makeTap(deviceId, transferBtn2.x(), transferBtn2.y());
|
||||||
|
QThread::msleep(3000);
|
||||||
|
|
||||||
|
// 9. Ждём результат: "Успешно" или "Не удалось"
|
||||||
|
for (int attempt = 0; attempt < 15; ++attempt) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
|
||||||
|
if (!xmlScreenParser.findTextNode("Успешно").isEmpty()) {
|
||||||
|
qDebug() << "[PayByCard] Payment successful!";
|
||||||
|
m_error.clear();
|
||||||
|
|
||||||
|
// Сохраняем транзакцию в БД
|
||||||
|
TransactionInfo tx;
|
||||||
|
tx.accountId = m_account.id;
|
||||||
|
tx.amount = -m_amount;
|
||||||
|
tx.fee = fee;
|
||||||
|
tx.phone = m_cardNumber;
|
||||||
|
tx.bankName = "ozon";
|
||||||
|
tx.type = TransactionType::Card;
|
||||||
|
tx.status = TransactionStatus::Complete;
|
||||||
|
tx.timestamp = DateUtils::getUtcNow();
|
||||||
|
tx.completeTime = QDateTime::currentDateTime().toTimeZone(QTimeZone("Europe/Moscow"));
|
||||||
|
tx.bankTime = tx.completeTime.toString("dd.MM.yyyy, HH:mm");
|
||||||
|
const int txId = TransactionDAO::insertTransaction(tx);
|
||||||
|
qDebug() << "[PayByCard] Saved transaction to DB, id:" << txId << "fee:" << fee;
|
||||||
|
|
||||||
|
// Ищем кнопку "Документы" и достаём ID операции
|
||||||
|
Node docBtn = xmlScreenParser.findButtonNode("Документы", false);
|
||||||
|
if (!docBtn.isEmpty() && txId != -1) {
|
||||||
|
qDebug() << "[PayByCard] Tapping 'Документы'...";
|
||||||
|
AdbUtils::makeTap(deviceId, docBtn.x(), docBtn.y());
|
||||||
|
QThread::msleep(2000);
|
||||||
|
|
||||||
|
// Ждём появления кнопки "Поделиться"
|
||||||
|
bool docLoaded = false;
|
||||||
|
for (int da = 0; da < 20; ++da) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||||
|
Node shareBtn = xmlScreenParser.findNodeByContentDesc("Поделиться");
|
||||||
|
if (!shareBtn.isEmpty()) {
|
||||||
|
docLoaded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qDebug() << "[PayByCard] Waiting for 'Поделиться', attempt" << da + 1 << "/ 20";
|
||||||
|
QThread::msleep(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (docLoaded) {
|
||||||
|
QThread::msleep(500);
|
||||||
|
const QByteArray screenshot = AdbUtils::captureScreenshotBytes(deviceId);
|
||||||
|
if (!screenshot.isEmpty()) {
|
||||||
|
TransactionDAO::updateReceiptImage(txId, screenshot);
|
||||||
|
qDebug() << "[PayByCard] Receipt saved to DB, txId:" << txId;
|
||||||
|
|
||||||
|
const QString ocrText = recognizeTextFromImage(screenshot);
|
||||||
|
if (!ocrText.isEmpty()) {
|
||||||
|
qDebug() << "[PayByCard] OCR result:\n" << ocrText;
|
||||||
|
const QString externalId = extractTransactionId(ocrText);
|
||||||
|
if (!externalId.isEmpty()) {
|
||||||
|
TransactionDAO::updateBankTrExternalId(txId, externalId);
|
||||||
|
qDebug() << "[PayByCard] Extracted transaction ID:" << externalId;
|
||||||
|
} else {
|
||||||
|
qWarning() << "[PayByCard] Could not extract transaction ID from OCR text";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "[PayByCard] OCR returned empty text";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "[PayByCard] Screenshot is empty";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "[PayByCard] 'Поделиться' not found, skipping receipt";
|
||||||
|
}
|
||||||
|
|
||||||
|
AdbUtils::goBack(deviceId);
|
||||||
|
QThread::msleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xmlScreenParser.findTextNode("Не удалось").isEmpty()) {
|
||||||
|
m_error = "Перевод не удался (экран 'Не удалось')";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[PayByCard] Waiting for payment result, attempt" << attempt + 1 << "/ 15";
|
||||||
|
QThread::msleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_error = "Не дождались результата перевода";
|
||||||
|
qWarning() << "[PayByCard]" << m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ozon
|
||||||
36
android/ozon/PayByCardScript.h
Normal file
36
android/ozon/PayByCardScript.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "CommonScript.h"
|
||||||
|
|
||||||
|
namespace Ozon {
|
||||||
|
|
||||||
|
class PayByCardScript final : public CommonScript {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
~PayByCardScript() override;
|
||||||
|
|
||||||
|
PayByCardScript(
|
||||||
|
AccountInfo account,
|
||||||
|
QString cardNumber,
|
||||||
|
double amount,
|
||||||
|
QObject *parent = nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void doStart() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const AccountInfo m_account;
|
||||||
|
const QString m_cardNumber;
|
||||||
|
const double m_amount;
|
||||||
|
QString m_error;
|
||||||
|
|
||||||
|
void makePayment(
|
||||||
|
const QString &deviceId,
|
||||||
|
const QString &pinCode,
|
||||||
|
int width,
|
||||||
|
int height
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ozon
|
||||||
@ -142,6 +142,15 @@ Node ScreenXmlParser::findFirstEditText() {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node ScreenXmlParser::findEditTextByHint(const QString &hintPrefix) {
|
||||||
|
for (const Node &node : m_nodes) {
|
||||||
|
if (node.className == "android.widget.EditText" && node.hint.contains(hintPrefix)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
Node ScreenXmlParser::findButtonNode(const QString &text, const bool contains) {
|
Node ScreenXmlParser::findButtonNode(const QString &text, const bool contains) {
|
||||||
for (const Node &node: m_nodes) {
|
for (const Node &node: m_nodes) {
|
||||||
if (contains) {
|
if (contains) {
|
||||||
@ -591,6 +600,9 @@ void ScreenXmlParser::parseAndSaveXml(const QString &xml) {
|
|||||||
if (reader.attributes().hasAttribute("resource-id")) {
|
if (reader.attributes().hasAttribute("resource-id")) {
|
||||||
node.resourceId = reader.attributes().value("resource-id").toString();
|
node.resourceId = reader.attributes().value("resource-id").toString();
|
||||||
}
|
}
|
||||||
|
if (reader.attributes().hasAttribute("hint")) {
|
||||||
|
node.hint = reader.attributes().value("hint").toString();
|
||||||
|
}
|
||||||
|
|
||||||
m_nodes.append(node);
|
m_nodes.append(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,8 @@ public:
|
|||||||
|
|
||||||
Node findFirstEditText();
|
Node findFirstEditText();
|
||||||
|
|
||||||
|
Node findEditTextByHint(const QString &hintPrefix);
|
||||||
|
|
||||||
Node findButtonNode(const QString &text, bool contains);
|
Node findButtonNode(const QString &text, bool contains);
|
||||||
|
|
||||||
QList<Node> findAllButtons();
|
QList<Node> findAllButtons();
|
||||||
|
|||||||
BIN
assets/ozon/pay/pay_by_card.png
Normal file
BIN
assets/ozon/pay/pay_by_card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
820
assets/ozon/pay/pay_by_card.xml
Normal file
820
assets/ozon/pay/pay_by_card.xml
Normal file
@ -0,0 +1,820 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||||
|
<hierarchy rotation="0">
|
||||||
|
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||||
|
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||||
|
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/action_bar_root"
|
||||||
|
class="android.widget.LinearLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||||
|
<node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||||
|
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||||
|
drawing-order="2" hint="">
|
||||||
|
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/main_activity_top"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||||
|
<node index="1" text="" resource-id="ru.ozon.fintech.finance:id/over_host_fragment"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2400]" drawing-order="4" hint="">
|
||||||
|
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/over_fragment_top"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||||
|
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||||
|
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="1"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="3" text="" resource-id="" class="android.view.ViewGroup"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc="" checkable="false" checked="false"
|
||||||
|
clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||||
|
drawing-order="3" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||||
|
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||||
|
password="false" selected="false" bounds="[0,0][1080,2400]" drawing-order="2"
|
||||||
|
hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="ru.ozon.fintech.finance:id/main_activity_host_fragment"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||||
|
<node index="0" text="" resource-id="ru.ozon.fintech.finance:id/web_view_top"
|
||||||
|
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2400]" drawing-order="1" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="ru.ozon.fintech.finance:id/web_view_holder"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2337]" drawing-order="2" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.widget.FrameLayout"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false" enabled="true"
|
||||||
|
focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2337]" drawing-order="1" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.webkit.WebView"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false" focused="false"
|
||||||
|
scrollable="false" long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]" drawing-order="0"
|
||||||
|
hint="">
|
||||||
|
<node index="0" text="⠀" resource-id=""
|
||||||
|
class="android.webkit.WebView"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="true" focused="true"
|
||||||
|
scrollable="false" long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false" focused="false"
|
||||||
|
scrollable="false" long-clickable="false"
|
||||||
|
password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2337]" drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id="svelte"
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false"
|
||||||
|
clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="MFTransferByCardNumber@lk-pay"
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="movable-pan-iframe"
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false" selected="false"
|
||||||
|
bounds="[42,779][1039,942]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="frame-container"
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,779][1039,929]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,779][1039,929]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id="svelte"
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,779][1039,929]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,779][1039,929]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint="">
|
||||||
|
<node NAF="true"
|
||||||
|
index="0"
|
||||||
|
text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.EditText"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="true"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,847][987,903]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint="Номер карты получателя"/>
|
||||||
|
<node index="1"
|
||||||
|
text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,779][1039,929]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
<node index="2"
|
||||||
|
text="Номер карты получателя"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,826][601,884]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="1" text=""
|
||||||
|
resource-id="svelte-announcer"
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,779][47,787]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node index="1" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,262]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node NAF="true" index="0" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.Button"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="true"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[28,154][118,241]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="1"
|
||||||
|
text="Перевод по номеру карты"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[133,165][945,231]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="2" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false" selected="false"
|
||||||
|
bounds="[0,259][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="СЧЁТ СПИСАНИЯ"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,343][1039,388]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="1" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,417][1039,606]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,417][231,606]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
<node index="1" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[231,417][1039,606]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0"
|
||||||
|
text="1 037,50 ₽"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[231,506][430,572]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
<node index="1"
|
||||||
|
text="Основной счёт"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[231,448][819,504]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="2" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,417][1039,606]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="2" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[0,601][1080,711]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="3" text="ПОЛУЧАТЕЛЬ"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,706][1039,753]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="4" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,958][1039,1110]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,958][924,1110]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,1005][924,1060]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint="">
|
||||||
|
<node NAF="true"
|
||||||
|
index="0" text=""
|
||||||
|
resource-id="input___eEQR_Pc"
|
||||||
|
class="android.widget.EditText"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="true"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,1005][924,1060]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint="Сумма от 100 ₽ до 500 000 ₽"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node NAF="true" index="1"
|
||||||
|
text="" resource-id=""
|
||||||
|
class="android.widget.Button"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="true"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[931,1000][997,1068]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="5" text="Комиссия"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,1168][997,1218]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="6"
|
||||||
|
text="Рассчитаем после ввода всех данных"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[84,1215][997,1281]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="7" text=""
|
||||||
|
resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="false"
|
||||||
|
enabled="true"
|
||||||
|
focusable="false"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,2105][1039,2254]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="Перевести"
|
||||||
|
resource-id=""
|
||||||
|
class="android.widget.Button"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc=""
|
||||||
|
checkable="false"
|
||||||
|
checked="false"
|
||||||
|
clickable="true"
|
||||||
|
enabled="true"
|
||||||
|
focusable="true"
|
||||||
|
focused="false"
|
||||||
|
scrollable="false"
|
||||||
|
long-clickable="false"
|
||||||
|
password="false"
|
||||||
|
selected="false"
|
||||||
|
bounds="[42,2105][1039,2254]"
|
||||||
|
drawing-order="0"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node index="1" text=""
|
||||||
|
resource-id="modal-container"
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,2336][1080,2336]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="2" text="⠀"
|
||||||
|
resource-id="svelte-announcer"
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][5,5]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="1" text="" resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false"
|
||||||
|
clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="2" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false"
|
||||||
|
clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="1" text="" resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
</node>
|
||||||
|
<node index="3" text="" resource-id=""
|
||||||
|
class="android.view.View"
|
||||||
|
package="ru.ozon.fintech.finance" content-desc=""
|
||||||
|
checkable="false" checked="false"
|
||||||
|
clickable="false" enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint="">
|
||||||
|
<node index="0" text="" resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
<node index="1" text="" resource-id=""
|
||||||
|
class="android.widget.TextView"
|
||||||
|
package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false"
|
||||||
|
checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false"
|
||||||
|
focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[0,0][1080,2337]"
|
||||||
|
drawing-order="0" hint=""/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node index="1" text=""
|
||||||
|
resource-id="ru.ozon.fintech.finance:id/web_view_toolbar"
|
||||||
|
class="android.view.ViewGroup" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false"
|
||||||
|
enabled="true" focusable="false" focused="false" scrollable="false"
|
||||||
|
long-clickable="false" password="false" selected="false"
|
||||||
|
bounds="[0,0][1080,147]" drawing-order="1" hint=""/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node index="1" text=""
|
||||||
|
resource-id="ru.ozon.fintech.finance:id/main_activity_bottom_navigation_holder"
|
||||||
|
class="android.widget.FrameLayout" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||||
|
focusable="false" focused="false" scrollable="false" long-clickable="false"
|
||||||
|
password="false" selected="false" bounds="[0,2201][1080,2400]" drawing-order="3"
|
||||||
|
hint=""/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node index="1" text="" resource-id="" class="android.view.View" package="ru.ozon.fintech.finance"
|
||||||
|
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||||
|
focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
|
||||||
|
selected="false" bounds="[818,0][1080,262]" drawing-order="2" hint=""/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</hierarchy>
|
||||||
BIN
assets/ozon/pay/pay_by_card_enter_sum.png
Normal file
BIN
assets/ozon/pay/pay_by_card_enter_sum.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
1
assets/ozon/pay/pay_by_card_enter_sum.xml
Normal file
1
assets/ozon/pay/pay_by_card_enter_sum.xml
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/ozon/pay/pay_by_card_success.png
Normal file
BIN
assets/ozon/pay/pay_by_card_success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 607 KiB |
1
assets/ozon/pay/pay_by_card_success.xml
Normal file
1
assets/ozon/pay/pay_by_card_success.xml
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -42,6 +42,7 @@ public:
|
|||||||
QString contentDesc;
|
QString contentDesc;
|
||||||
QString resourceId;
|
QString resourceId;
|
||||||
QString className;
|
QString className;
|
||||||
|
QString hint;
|
||||||
bool clickable = false;
|
bool clickable = false;
|
||||||
bool focusable = false;
|
bool focusable = false;
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#include "toss/LoginAndCheckAccountsTossScript.h"
|
#include "toss/LoginAndCheckAccountsTossScript.h"
|
||||||
#include "ziraat/GetLastDaysHistoryZiraatScript.h"
|
#include "ziraat/GetLastDaysHistoryZiraatScript.h"
|
||||||
#include "ziraat/LoginAndCheckAccountsZiraatScript.h"
|
#include "ziraat/LoginAndCheckAccountsZiraatScript.h"
|
||||||
|
#include "ozon/PayByCardScript.h"
|
||||||
#include "ozon/PayByPhoneScript.h"
|
#include "ozon/PayByPhoneScript.h"
|
||||||
#include "rshb/PayByPhoneScript.h"
|
#include "rshb/PayByPhoneScript.h"
|
||||||
|
|
||||||
@ -273,7 +274,9 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
|||||||
txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank";
|
txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank";
|
||||||
txObj["bank_participator_id"]= tx.phone;
|
txObj["bank_participator_id"]= tx.phone;
|
||||||
txObj["status"] = tx.status == TransactionStatus::Complete ? "completed" : (tx.status == TransactionStatus::Wait ? "progress" : "completed");
|
txObj["status"] = tx.status == TransactionStatus::Complete ? "completed" : (tx.status == TransactionStatus::Wait ? "progress" : "completed");
|
||||||
txObj["extra"] = QJsonObject();
|
QJsonObject extraObj;
|
||||||
|
extraObj["fee"] = static_cast<int>(tx.fee * 100);
|
||||||
|
txObj["extra"] = extraObj;
|
||||||
if (tx.timestamp.isValid()) {
|
if (tx.timestamp.isValid()) {
|
||||||
txObj["created_at"] = tx.timestamp.toTimeZone(QTimeZone("Europe/Moscow")).toString(Qt::ISODateWithMs);
|
txObj["created_at"] = tx.timestamp.toTimeZone(QTimeZone("Europe/Moscow")).toString(Qt::ISODateWithMs);
|
||||||
} else if (!tx.bankTime.isEmpty()) {
|
} else if (!tx.bankTime.isEmpty()) {
|
||||||
@ -292,23 +295,33 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
|||||||
}
|
}
|
||||||
taskData = arr;
|
taskData = arr;
|
||||||
} else if (event.type == EventType::CreateTransaction) {
|
} else if (event.type == EventType::CreateTransaction) {
|
||||||
|
// Определяем тип транзакции из JSON задачи
|
||||||
|
const QJsonObject taskJson = QJsonDocument::fromJson(event.json.toUtf8()).object();
|
||||||
|
const QString txType = taskJson["body"].toObject()["transaction_type"].toString();
|
||||||
|
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
obj["amount"] = -static_cast<int>(event.amount * 100);
|
obj["amount"] = -static_cast<int>(event.amount * 100);
|
||||||
obj["currency"] = 643;
|
obj["currency"] = 643;
|
||||||
obj["transaction_type"] = "top-up";
|
obj["transaction_type"] = txType.isEmpty() ? "top-up" : txType;
|
||||||
obj["bank_participator_id"]= event.phone;
|
obj["bank_participator_id"]= event.phone;
|
||||||
obj["status"] = "completed";
|
obj["status"] = "completed";
|
||||||
obj["created_at"] = QDateTime::currentDateTime().toTimeZone(QTimeZone("Europe/Moscow")).toString(Qt::ISODateWithMs);
|
obj["created_at"] = QDateTime::currentDateTime().toTimeZone(QTimeZone("Europe/Moscow")).toString(Qt::ISODateWithMs);
|
||||||
|
|
||||||
// Берём bank_transaction_id из последней сохранённой транзакции
|
// Берём bank_transaction_id и fee из последней сохранённой транзакции
|
||||||
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 1);
|
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 1);
|
||||||
|
int feeInCents = 0;
|
||||||
for (const auto &tx : txList) {
|
for (const auto &tx : txList) {
|
||||||
if (!tx.bankTrExternalId.isEmpty() && qAbs(tx.amount) == event.amount && tx.phone == event.phone) {
|
if (!tx.bankTrExternalId.isEmpty() && qAbs(tx.amount) == event.amount && tx.phone == event.phone) {
|
||||||
obj["bank_transaction_id"] = tx.bankTrExternalId;
|
obj["bank_transaction_id"] = tx.bankTrExternalId;
|
||||||
|
feeInCents = static_cast<int>(tx.fee * 100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject extraObj;
|
||||||
|
extraObj["fee"] = feeInCents;
|
||||||
|
obj["extra"] = extraObj;
|
||||||
|
|
||||||
taskData = obj;
|
taskData = obj;
|
||||||
} else {
|
} else {
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
@ -390,9 +403,21 @@ void EventHandler::startThreadForTask(const AccountInfo &account, const EventInf
|
|||||||
|
|
||||||
if (event.type == EventType::CreateTransaction) {
|
if (event.type == EventType::CreateTransaction) {
|
||||||
const QString recipientBank = event.comment; // резолвленное имя банка-получателя
|
const QString recipientBank = event.comment; // резолвленное имя банка-получателя
|
||||||
if (appCode == "ozon") setup(new Ozon::PayByPhoneScript(account, event.phone, recipientBank, event.amount));
|
|
||||||
else if (appCode == "rshb") setup(new Rshb::PayByPhoneScript(account, event.phone, recipientBank, event.amount));
|
// Определяем тип транзакции из JSON задачи
|
||||||
else qWarning() << "[EventHandler] CREATE_TRANSACTION: unknown appCode:" << appCode;
|
const QJsonObject taskJson = QJsonDocument::fromJson(event.json.toUtf8()).object();
|
||||||
|
const QString txType = taskJson["body"].toObject()["transaction_type"].toString();
|
||||||
|
|
||||||
|
if (txType == "bank") {
|
||||||
|
// Перевод по номеру карты
|
||||||
|
if (appCode == "ozon") setup(new Ozon::PayByCardScript(account, event.phone, event.amount));
|
||||||
|
else qWarning() << "[EventHandler] CREATE_TRANSACTION bank: unknown appCode:" << appCode;
|
||||||
|
} else {
|
||||||
|
// Перевод по номеру телефона (top-up)
|
||||||
|
if (appCode == "ozon") setup(new Ozon::PayByPhoneScript(account, event.phone, recipientBank, event.amount));
|
||||||
|
else if (appCode == "rshb") setup(new Rshb::PayByPhoneScript(account, event.phone, recipientBank, event.amount));
|
||||||
|
else qWarning() << "[EventHandler] CREATE_TRANSACTION: unknown appCode:" << appCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Watchdog-таймер: 5 минут — убиваем зависший поток
|
// // Watchdog-таймер: 5 минут — убиваем зависший поток
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user