Add GetLastTransactionsScript and PayByCardScript implementations for Black app
Implemented `GetLastTransactionsScript` for automated retrieval of transactions, handling home screen navigation, "Ver más" button detection, and transaction list parsing with database storage. Introduced `PayByCardScript` for automated card payments, covering recipient selection, amount input, payment confirmation, and transaction logging. Added XML assets and updates to support these workflows.
@ -196,13 +196,9 @@ void CommonScript::updateTransactionData(
|
||||
|
||||
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
||||
if (!app.bankProfileId.isEmpty()) {
|
||||
qDebug() << "[Black] bankProfileId already exists:" << app.bankProfileId;
|
||||
return;
|
||||
}
|
||||
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 840);
|
||||
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
||||
@ -220,9 +216,16 @@ void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QStr
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(deviceId);
|
||||
ns.setPayload(QJsonDocument(profileBody).toJson());
|
||||
ns.addExtra("app_id", app.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[Black] createBankProfileIfNeeded: postBankProfile done";
|
||||
|
||||
if (app.bankProfileId.isEmpty()) {
|
||||
ns.addExtra("app_id", app.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[Black] createBankProfileIfNeeded: postBankProfile done";
|
||||
} else {
|
||||
ns.addExtra("bank_profile_id", app.bankProfileId);
|
||||
ns.patchBankProfile();
|
||||
qDebug() << "[Black] createBankProfileIfNeeded: patchBankProfile done";
|
||||
}
|
||||
}
|
||||
|
||||
void CommonScript::stop() {
|
||||
|
||||
@ -2,10 +2,14 @@
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "net/NetworkService.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
@ -115,12 +119,28 @@ void GetCardInfoScript::doStart() {
|
||||
qWarning() << "[Black::GetCardInfo] Failed to upsert account";
|
||||
}
|
||||
|
||||
// 6. Отправляем данные аккаунтов на сервер
|
||||
AccountInfo savedAccount = AccountDAO::findAppAccount(m_deviceId, m_appCode, lastNumbers);
|
||||
if (savedAccount.id != -1) {
|
||||
QList<QPair<AccountInfo, Node>> accounts;
|
||||
accounts.append({savedAccount, Node()});
|
||||
postAccountsData(accounts);
|
||||
// 6. Отправляем материал на сервер (если ещё нет material_id)
|
||||
const AccountInfo savedAccount = AccountDAO::findAppAccount(m_deviceId, m_appCode, lastNumbers);
|
||||
const ApplicationInfo updatedApp = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
|
||||
if (savedAccount.id != -1 && !updatedApp.bankProfileId.isEmpty()) {
|
||||
if (savedAccount.materialId.isEmpty()) {
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(m_deviceId);
|
||||
|
||||
QJsonObject materialBody;
|
||||
materialBody["bank_profile_id"] = updatedApp.bankProfileId;
|
||||
materialBody["card_number"] = savedAccount.cardNumber;
|
||||
materialBody["name"] = updatedApp.fullName;
|
||||
ns.setPayload(QJsonDocument(materialBody).toJson());
|
||||
ns.addExtra("account_id", savedAccount.id);
|
||||
ns.postMaterial();
|
||||
qDebug() << "[Black::GetCardInfo] postMaterial done for CVU" << lastNumbers;
|
||||
} else {
|
||||
qDebug() << "[Black::GetCardInfo] material already exists for CVU" << lastNumbers << ", skipping";
|
||||
}
|
||||
} else {
|
||||
qWarning() << "[Black::GetCardInfo] bankProfileId empty or account not found, skipping material";
|
||||
}
|
||||
|
||||
qDebug() << "[Black::GetCardInfo] Done. CVU:" << cvuNumber << "balance:" << balance;
|
||||
|
||||
168
android/black/GetLastTransactionsScript.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
#include "GetLastTransactionsScript.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QTimeZone>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "dao/TransactionDAO.h"
|
||||
#include "AppLogger.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
GetLastTransactionsScript::GetLastTransactionsScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent
|
||||
) : CommonScript(parent),
|
||||
m_deviceId(std::move(deviceId)), m_appCode(std::move(appCode)) {
|
||||
}
|
||||
|
||||
GetLastTransactionsScript::~GetLastTransactionsScript() = default;
|
||||
|
||||
void GetLastTransactionsScript::doStart() {
|
||||
const DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId);
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
|
||||
if (device.id.isEmpty() || app.id == -1) {
|
||||
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
|
||||
qCritical() << m_error;
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
|
||||
// Если не на домашнем экране — перезапускаем приложение
|
||||
if (!xmlScreenParser.isHomeScreen()) {
|
||||
qDebug() << "[Black::GetLastTransactions] Not on home screen, restarting app...";
|
||||
if (!runAppAndGoToHomeScreen(device.id, app.package, app.pinCode,
|
||||
device.screenWidth, device.screenHeight)) {
|
||||
m_error = "Cannot reach home screen: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
AppLogger::log("black/GetLastTransactions", m_deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(m_deviceId),
|
||||
"FETCH_TRANSACTIONS");
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
}
|
||||
|
||||
// Тапаем "Ver más" рядом с "Tu actividad" для перехода на экран транзакций
|
||||
Node verMasBtn = xmlScreenParser.findVerMasAfterTuActividad();
|
||||
if (verMasBtn.isEmpty()) {
|
||||
// Попробуем проскроллить вниз чтобы увидеть "Tu actividad" + "Ver más"
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
const int x = device.screenWidth / 2;
|
||||
const int offset = device.screenHeight / 4;
|
||||
AdbUtils::makeSwipe(m_deviceId, x, device.screenHeight - offset, x, offset);
|
||||
QThread::msleep(1000);
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
verMasBtn = xmlScreenParser.findVerMasAfterTuActividad();
|
||||
if (!verMasBtn.isEmpty()) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (verMasBtn.isEmpty()) {
|
||||
m_error = "Button 'Ver más' not found: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::GetLastTransactions] Tapping 'Ver más' at" << verMasBtn.x() << verMasBtn.y();
|
||||
AdbUtils::makeTap(m_deviceId, verMasBtn.x(), verMasBtn.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// Ждём загрузки экрана транзакций
|
||||
// Сперва появляется экран загрузки (Tu Actividad без транзакций),
|
||||
// затем подгружаются транзакции
|
||||
bool loaded = false;
|
||||
for (int attempt = 0; attempt < 15; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isTransactionListScreen()) {
|
||||
loaded = true;
|
||||
break;
|
||||
}
|
||||
if (xmlScreenParser.isTransactionLoadingScreen()) {
|
||||
qDebug() << "[Black::GetLastTransactions] Loading screen detected, waiting for transactions, attempt" << attempt + 1 << "/ 15";
|
||||
} else {
|
||||
qDebug() << "[Black::GetLastTransactions] Waiting for transaction screen, attempt" << attempt + 1 << "/ 15";
|
||||
}
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
// Проверяем: если экран загрузки есть, но транзакций нет — это нормально (пустой аккаунт)
|
||||
if (xmlScreenParser.isTransactionLoadingScreen()) {
|
||||
qDebug() << "[Black::GetLastTransactions] No transactions found (empty account)";
|
||||
AdbUtils::goBack(m_deviceId);
|
||||
QThread::msleep(1000);
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
m_error = "Transaction list screen not loaded: " + m_deviceId;
|
||||
qWarning() << m_error;
|
||||
emit finishedWithResult(m_error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Находим accountId для сохранения транзакций
|
||||
int accountId = -1;
|
||||
const QList<AccountInfo> accounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
||||
if (!accounts.isEmpty()) {
|
||||
accountId = accounts.first().id;
|
||||
qDebug() << "[Black::GetLastTransactions] Using accountId:" << accountId;
|
||||
} else {
|
||||
qWarning() << "[Black::GetLastTransactions] No account found for" << m_deviceId << m_appCode;
|
||||
}
|
||||
|
||||
// Берём все транзакции что видны на экране
|
||||
const QTimeZone argTz("America/Argentina/Buenos_Aires");
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||
QList<TransactionInfo> pageItems = xmlScreenParser.parseTransactionItems();
|
||||
|
||||
qDebug() << "[Black::GetLastTransactions] Found" << pageItems.size() << "transactions on screen";
|
||||
|
||||
for (const TransactionInfo &tx : pageItems) {
|
||||
TransactionInfo saveTx = tx;
|
||||
saveTx.bankName = "black";
|
||||
saveTx.status = TransactionStatus::Complete;
|
||||
saveTx.timestamp = QDateTime::currentDateTimeUtc();
|
||||
|
||||
// Парсим дату из bankTime: "21 de febrero de 2026 - 09:39"
|
||||
QDateTime parsed = xmlScreenParser.parseSpanishDate(saveTx.bankTime);
|
||||
if (parsed.isValid()) {
|
||||
parsed.setTimeZone(argTz);
|
||||
saveTx.completeTime = parsed;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::GetLastTransactions]"
|
||||
<< "date:" << saveTx.bankTime
|
||||
<< "desc:" << saveTx.description
|
||||
<< "name:" << saveTx.name
|
||||
<< "amount:" << (saveTx.amount >= 0 ? "+" : "") + QString::number(saveTx.amount, 'f', 2);
|
||||
|
||||
// Сохраняем в БД
|
||||
if (accountId != -1) {
|
||||
saveTx.accountId = accountId;
|
||||
if (TransactionDAO::insertTransactionIfNotExists(saveTx)) {
|
||||
qDebug() << "[Black::GetLastTransactions] Saved transaction to DB";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "[Black::GetLastTransactions] Total transactions:" << pageItems.size();
|
||||
|
||||
// Возвращаемся на домашний экран
|
||||
AdbUtils::goBack(m_deviceId);
|
||||
QThread::msleep(1000);
|
||||
|
||||
emit finishedWithResult(m_error);
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
27
android/black/GetLastTransactionsScript.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "CommonScript.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class GetLastTransactionsScript final : public CommonScript {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GetLastTransactionsScript(
|
||||
QString deviceId,
|
||||
QString appCode,
|
||||
QObject *parent = nullptr
|
||||
);
|
||||
|
||||
~GetLastTransactionsScript() override;
|
||||
|
||||
protected:
|
||||
void doStart() override;
|
||||
|
||||
private:
|
||||
const QString m_deviceId;
|
||||
const QString m_appCode;
|
||||
QString m_error;
|
||||
};
|
||||
|
||||
} // namespace Black
|
||||
@ -5,6 +5,7 @@
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "net/NetworkService.h"
|
||||
@ -161,6 +162,18 @@ void GetProfileInfoScript::doStart() {
|
||||
// 7. Создаём bank profile если нет
|
||||
createBankProfileIfNeeded(m_deviceId, m_appCode);
|
||||
|
||||
// 8. Отправляем данные аккаунтов на сервер если нет material_id
|
||||
const QList<AccountInfo> allAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
||||
QList<QPair<AccountInfo, Node>> accountsToPost;
|
||||
for (const auto &acc : allAccounts) {
|
||||
if (acc.materialId.isEmpty()) {
|
||||
accountsToPost.append({acc, Node()});
|
||||
}
|
||||
}
|
||||
if (!accountsToPost.isEmpty()) {
|
||||
postAccountsData(accountsToPost);
|
||||
}
|
||||
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
emit finishedWithResult(m_error);
|
||||
}
|
||||
|
||||
374
android/black/PayByCardScript.cpp
Normal file
@ -0,0 +1,374 @@
|
||||
#include "PayByCardScript.h"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "dao/TransactionDAO.h"
|
||||
#include "AppLogger.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
PayByCardScript::PayByCardScript(
|
||||
AccountInfo account,
|
||||
QString cardNumber,
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
|
||||
// 0. Убеждаемся что на домашнем экране
|
||||
if (!xmlScreenParser.isHomeScreen()) {
|
||||
qDebug() << "[Black::PayByCard] Not on home screen, restarting app...";
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(m_account.deviceId, m_account.appCode);
|
||||
if (!runAppAndGoToHomeScreen(deviceId, app.package, pinCode, width, height)) {
|
||||
m_error = "Cannot reach home screen: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
AppLogger::log("black/PayByCard", deviceId, m_error,
|
||||
AdbUtils::captureScreenshotBytes(deviceId),
|
||||
"CREATE_TRANSACTION");
|
||||
AdbUtils::tryToKillApplication(deviceId, app.package);
|
||||
return;
|
||||
}
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
}
|
||||
|
||||
// 1. Тапаем "Enviar a\nCBU o alias" на домашнем экране
|
||||
Node enviarBtn = xmlScreenParser.findNodeByContentDesc("Enviar a\nCBU o alias", true);
|
||||
if (enviarBtn.isEmpty()) {
|
||||
// Попробуем проскроллить
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
const int x = width / 2;
|
||||
const int offset = height / 4;
|
||||
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
|
||||
QThread::msleep(1000);
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
enviarBtn = xmlScreenParser.findNodeByContentDesc("Enviar a\nCBU o alias", true);
|
||||
if (!enviarBtn.isEmpty()) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enviarBtn.isEmpty()) {
|
||||
m_error = "Button 'Enviar a CBU o alias' not found: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::PayByCard] Tapping 'Enviar a CBU o alias'";
|
||||
AdbUtils::makeTap(deviceId, enviarBtn.x(), enviarBtn.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// 2. Ждём экран ввода номера карты (CBU/CVU/Alias)
|
||||
bool onInputScreen = false;
|
||||
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isPayInputCardNumberScreen()) {
|
||||
onInputScreen = true;
|
||||
break;
|
||||
}
|
||||
qDebug() << "[Black::PayByCard] Waiting for input card screen, attempt" << attempt + 1;
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
if (!onInputScreen) {
|
||||
m_error = "Input card number screen not loaded: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Вводим номер карты в EditText
|
||||
Node editText = xmlScreenParser.findEditTextByHint("Ingresar CBU, CVU o Alias");
|
||||
if (editText.isEmpty()) {
|
||||
editText = xmlScreenParser.findFirstEditText();
|
||||
}
|
||||
if (editText.isEmpty()) {
|
||||
m_error = "EditText for card number not found: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
AdbUtils::makeTap(deviceId, editText.x(), editText.y());
|
||||
QThread::msleep(500);
|
||||
AdbUtils::inputText(deviceId, m_cardNumber);
|
||||
QThread::msleep(1000);
|
||||
|
||||
// Нажимаем "Continuar"
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
Node continuarBtn = xmlScreenParser.findNodeByContentDesc("Continuar");
|
||||
if (continuarBtn.isEmpty()) {
|
||||
continuarBtn = xmlScreenParser.findButtonNode("Continuar", false);
|
||||
}
|
||||
if (continuarBtn.isEmpty()) {
|
||||
m_error = "Button 'Continuar' not found on input card screen: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::PayByCard] Tapping 'Continuar' after card number input";
|
||||
AdbUtils::makeTap(deviceId, continuarBtn.x(), continuarBtn.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// 3. Ждём экран подтверждения получателя (pay_transfer_confirm)
|
||||
bool onTransferConfirm = false;
|
||||
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isPayTransferConfirmScreen()) {
|
||||
onTransferConfirm = true;
|
||||
break;
|
||||
}
|
||||
qDebug() << "[Black::PayByCard] Waiting for transfer confirm screen, attempt" << attempt + 1;
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
if (!onTransferConfirm) {
|
||||
m_error = "Transfer confirm screen not loaded: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Нажимаем "Transferir"
|
||||
Node transferirBtn = xmlScreenParser.findNodeByContentDesc("Transferir");
|
||||
if (transferirBtn.isEmpty()) {
|
||||
transferirBtn = xmlScreenParser.findButtonNode("Transferir", false);
|
||||
}
|
||||
if (transferirBtn.isEmpty()) {
|
||||
m_error = "Button 'Transferir' not found on transfer confirm screen: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::PayByCard] Tapping 'Transferir' on confirm screen";
|
||||
AdbUtils::makeTap(deviceId, transferirBtn.x(), transferirBtn.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// 4. Ждём экран ввода суммы (pay_input_sum)
|
||||
bool onInputSum = false;
|
||||
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isPayInputSumScreen()) {
|
||||
onInputSum = true;
|
||||
break;
|
||||
}
|
||||
qDebug() << "[Black::PayByCard] Waiting for input sum screen, attempt" << attempt + 1;
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
if (!onInputSum) {
|
||||
m_error = "Input sum screen not loaded: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Вводим сумму в EditText
|
||||
Node sumEditText = xmlScreenParser.findFirstEditText();
|
||||
if (sumEditText.isEmpty()) {
|
||||
m_error = "EditText for sum not found: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
AdbUtils::makeTap(deviceId, sumEditText.x(), sumEditText.y());
|
||||
QThread::msleep(500);
|
||||
|
||||
// Удаляем содержимое поля (там "0,00") — удаляем пока не станет "0,00" или пусто
|
||||
for (int d = 0; d < 20; ++d) {
|
||||
QProcess proc;
|
||||
proc.start(AdbUtils::adbPath(), {"-s", deviceId, "shell", "input", "keyevent", "67"});
|
||||
proc.waitForFinished(2000);
|
||||
}
|
||||
QThread::msleep(500);
|
||||
|
||||
// Проверяем что осталось в поле после очистки
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
Node afterClear = xmlScreenParser.findFirstEditText();
|
||||
qDebug() << "[Black::PayByCard] After clear, field text:" << afterClear.text;
|
||||
|
||||
// Поле работает как ввод в центах: каждая цифра сдвигает значение влево
|
||||
// Для 500,00 нужно ввести "50000"
|
||||
const QString amountStr = QString::number(static_cast<int>(m_amount * 100));
|
||||
AdbUtils::inputText(deviceId, amountStr);
|
||||
QThread::msleep(1000);
|
||||
|
||||
// Проверяем что сумма ввелась верно
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
Node currentEdit = xmlScreenParser.findFirstEditText();
|
||||
qDebug() << "[Black::PayByCard] Sum field text:" << currentEdit.text;
|
||||
|
||||
// Если сумма неверная — пробуем ещё раз: удаляем всё и вводим заново
|
||||
const QString expectedAmount = QString::number(static_cast<int>(m_amount));
|
||||
QString cleanText = currentEdit.text.trimmed();
|
||||
cleanText.remove('.');
|
||||
if (cleanText.endsWith(",00")) cleanText.chop(3);
|
||||
if (cleanText != expectedAmount) {
|
||||
qDebug() << "[Black::PayByCard] Sum mismatch (" << cleanText << "!=" << expectedAmount << "), retrying...";
|
||||
AdbUtils::makeTap(deviceId, currentEdit.x(), currentEdit.y());
|
||||
QThread::msleep(300);
|
||||
for (int d = 0; d < 20; ++d) {
|
||||
QProcess proc;
|
||||
proc.start(AdbUtils::adbPath(), {"-s", deviceId, "shell", "input", "keyevent", "67"});
|
||||
proc.waitForFinished(2000);
|
||||
}
|
||||
QThread::msleep(500);
|
||||
AdbUtils::inputText(deviceId, amountStr);
|
||||
QThread::msleep(1000);
|
||||
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
currentEdit = xmlScreenParser.findFirstEditText();
|
||||
qDebug() << "[Black::PayByCard] Sum field text (retry):" << currentEdit.text;
|
||||
}
|
||||
|
||||
// Нажимаем "Continuar"
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
Node continuarSumBtn = xmlScreenParser.findNodeByContentDesc("Continuar");
|
||||
if (continuarSumBtn.isEmpty()) {
|
||||
continuarSumBtn = xmlScreenParser.findButtonNode("Continuar", false);
|
||||
}
|
||||
if (continuarSumBtn.isEmpty()) {
|
||||
m_error = "Button 'Continuar' not found on input sum screen: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::PayByCard] Tapping 'Continuar' after sum input";
|
||||
AdbUtils::makeTap(deviceId, continuarSumBtn.x(), continuarSumBtn.y());
|
||||
QThread::msleep(2000);
|
||||
|
||||
// 5. Ждём экран финального подтверждения (pay_confirm)
|
||||
bool onPayConfirm = false;
|
||||
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isPayConfirmScreen()) {
|
||||
onPayConfirm = true;
|
||||
break;
|
||||
}
|
||||
qDebug() << "[Black::PayByCard] Waiting for pay confirm screen, attempt" << attempt + 1;
|
||||
QThread::msleep(1500);
|
||||
}
|
||||
|
||||
if (!onPayConfirm) {
|
||||
m_error = "Pay confirm screen not loaded: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Парсим имя получателя из "Vas a transferir \na ИМЯ"
|
||||
const QString recipientName = xmlScreenParser.parseRecipientNameFromConfirm();
|
||||
qDebug() << "[Black::PayByCard] Recipient name:" << recipientName;
|
||||
|
||||
// Нажимаем "Transferir" для финального подтверждения
|
||||
Node finalTransferirBtn = xmlScreenParser.findNodeByContentDesc("Transferir");
|
||||
if (finalTransferirBtn.isEmpty()) {
|
||||
finalTransferirBtn = xmlScreenParser.findButtonNode("Transferir", false);
|
||||
}
|
||||
if (finalTransferirBtn.isEmpty()) {
|
||||
m_error = "Button 'Transferir' not found on pay confirm screen: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::PayByCard] Tapping final 'Transferir'";
|
||||
AdbUtils::makeTap(deviceId, finalTransferirBtn.x(), finalTransferirBtn.y());
|
||||
QThread::msleep(3000);
|
||||
|
||||
// 5.5. Проверяем экран ввода PIN-кода
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isPinCodeScreen()) {
|
||||
qDebug() << "[Black::PayByCard] PIN code screen detected, entering PIN...";
|
||||
inputPinCode(deviceId, pinCode);
|
||||
QThread::msleep(3000);
|
||||
}
|
||||
|
||||
// 6. Ждём экран успеха (pay_success) — "Dinero enviado!"
|
||||
bool onSuccess = false;
|
||||
for (int attempt = 0; attempt < 15; ++attempt) {
|
||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
||||
if (xmlScreenParser.isPaySuccessScreen()) {
|
||||
onSuccess = true;
|
||||
break;
|
||||
}
|
||||
// Если PIN-код появился позже — вводим
|
||||
if (xmlScreenParser.isPinCodeScreen()) {
|
||||
qDebug() << "[Black::PayByCard] PIN code screen detected (retry), entering PIN...";
|
||||
inputPinCode(deviceId, pinCode);
|
||||
QThread::msleep(3000);
|
||||
continue;
|
||||
}
|
||||
qDebug() << "[Black::PayByCard] Waiting for success screen, attempt" << attempt + 1;
|
||||
QThread::msleep(2000);
|
||||
}
|
||||
|
||||
if (!onSuccess) {
|
||||
m_error = "Pay success screen not loaded: " + deviceId;
|
||||
qWarning() << m_error;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[Black::PayByCard] Payment successful!";
|
||||
|
||||
// Парсим данные с экрана успеха
|
||||
const QString bankTime = xmlScreenParser.parsePaySuccessDateTime();
|
||||
const QString coelsaId = xmlScreenParser.parsePaySuccessCoelsaId();
|
||||
qDebug() << "[Black::PayByCard] DateTime:" << bankTime << "Id Coelsa:" << coelsaId;
|
||||
|
||||
// Делаем скриншот экрана успеха как receipt
|
||||
const QByteArray receiptImage = AdbUtils::captureScreenshotBytes(deviceId);
|
||||
|
||||
// Сохраняем транзакцию
|
||||
TransactionInfo tx;
|
||||
tx.accountId = m_account.id;
|
||||
tx.amount = -m_amount; // исходящий перевод
|
||||
tx.fee = 0;
|
||||
tx.status = TransactionStatus::Complete;
|
||||
tx.type = TransactionType::Card;
|
||||
tx.name = recipientName;
|
||||
tx.description = "Transferencia a " + recipientName;
|
||||
tx.phone = m_cardNumber;
|
||||
tx.bankName = "black";
|
||||
tx.bankTime = bankTime;
|
||||
tx.bankTrExternalId = coelsaId;
|
||||
tx.timestamp = QDateTime::currentDateTimeUtc();
|
||||
tx.completeTime = QDateTime::currentDateTimeUtc();
|
||||
tx.receiptImage = receiptImage;
|
||||
|
||||
const int txId = TransactionDAO::insertTransaction(tx);
|
||||
if (txId != -1) {
|
||||
qDebug() << "[Black::PayByCard] Transaction saved to DB, id:" << txId;
|
||||
if (!receiptImage.isEmpty()) {
|
||||
TransactionDAO::updateReceiptImage(txId, receiptImage);
|
||||
}
|
||||
} else {
|
||||
qWarning() << "[Black::PayByCard] Failed to save transaction to DB";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
36
android/black/PayByCardScript.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "CommonScript.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
class PayByCardScript final : public CommonScript {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PayByCardScript(
|
||||
AccountInfo account,
|
||||
QString cardNumber,
|
||||
double amount,
|
||||
QObject *parent = nullptr
|
||||
);
|
||||
|
||||
~PayByCardScript() override;
|
||||
|
||||
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 Black
|
||||
@ -1,5 +1,6 @@
|
||||
#include "ScreenXmlParser.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QRegularExpression>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDomDocument>
|
||||
@ -306,4 +307,239 @@ QString ScreenXmlParser::parseCVUNumber() {
|
||||
return {};
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findVerMasAfterTuActividad() {
|
||||
// "Ver más" идёт сразу после "Tu actividad" на домашнем экране
|
||||
bool afterTuActividad = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Tu actividad") {
|
||||
afterTuActividad = true;
|
||||
continue;
|
||||
}
|
||||
if (afterTuActividad && node.contentDesc == QString::fromUtf8("Ver más") && node.clickable) {
|
||||
return node;
|
||||
}
|
||||
// Если встретили другую секцию — прекращаем поиск
|
||||
if (afterTuActividad && node.contentDesc == "Tarjetas") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isTransactionLoadingScreen() {
|
||||
// Экран загрузки: заголовок "Tu Actividad" есть, но транзакций нет
|
||||
// Может содержать "Aún no tienes actividad"
|
||||
bool hasTuActividad = false;
|
||||
bool hasTransferencia = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Tu Actividad") {
|
||||
hasTuActividad = true;
|
||||
}
|
||||
if (node.contentDesc.startsWith("Transferencia")) {
|
||||
hasTransferencia = true;
|
||||
}
|
||||
}
|
||||
return hasTuActividad && !hasTransferencia;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isTransactionListScreen() {
|
||||
// Экран транзакций определяется по заголовку "Tu Actividad" (с большой A)
|
||||
// + наличие транзакций (ImageView с "Transferencia")
|
||||
// На домашнем экране — "Tu actividad" (с маленькой a)
|
||||
bool hasTuActividad = false;
|
||||
bool hasTransferencia = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Tu Actividad") {
|
||||
hasTuActividad = true;
|
||||
}
|
||||
if (node.contentDesc.startsWith("Transferencia")) {
|
||||
hasTransferencia = true;
|
||||
}
|
||||
}
|
||||
return hasTuActividad && hasTransferencia;
|
||||
}
|
||||
|
||||
QList<TransactionInfo> ScreenXmlParser::parseTransactionItems() {
|
||||
// Транзакции — ImageView с content-desc формата:
|
||||
// "Transferencia\n21 de febrero de 2026 - 09:39\n$-1.857,\n00"
|
||||
// "Transferencia externa de NOELIA ISABEL LEZCANO\n21 de febrero de 2026 - 09:35\n$123,\n45"
|
||||
QList<TransactionInfo> result;
|
||||
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.className != "android.widget.ImageView") continue;
|
||||
if (!node.contentDesc.startsWith("Transferencia")) continue;
|
||||
|
||||
QStringList lines = node.contentDesc.split('\n');
|
||||
if (lines.size() < 3) continue;
|
||||
|
||||
TransactionInfo tx;
|
||||
|
||||
// Строка 1: описание, может содержать имя отправителя
|
||||
// "Transferencia" или "Transferencia externa de NOELIA ISABEL LEZCANO"
|
||||
const QString descLine = lines[0].trimmed();
|
||||
tx.description = descLine;
|
||||
if (descLine.contains("externa de ")) {
|
||||
tx.name = descLine.mid(descLine.indexOf("externa de ") + 11).trimmed();
|
||||
}
|
||||
|
||||
// Строка 2: дата "21 de febrero de 2026 - 09:39"
|
||||
tx.bankTime = lines[1].trimmed();
|
||||
|
||||
// Строки 3+: сумма "$-1.857,\n00" → объединяем
|
||||
QString amountStr;
|
||||
for (int i = 2; i < lines.size(); ++i) {
|
||||
amountStr += lines[i].trimmed();
|
||||
}
|
||||
// "$-1.857,00" → убираем "$", "." (тысячный разделитель), заменяем "," на "."
|
||||
amountStr.remove('$');
|
||||
amountStr.remove(' ');
|
||||
bool isNegative = amountStr.contains('-');
|
||||
amountStr.remove('-');
|
||||
amountStr.remove('.'); // тысячный разделитель
|
||||
amountStr.replace(',', '.');
|
||||
bool ok = false;
|
||||
tx.amount = amountStr.toDouble(&ok);
|
||||
if (ok && isNegative) tx.amount = -tx.amount;
|
||||
|
||||
tx.type = TransactionType::Card;
|
||||
|
||||
result.append(tx);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QDateTime ScreenXmlParser::parseSpanishDate(const QString &dateStr) {
|
||||
// Формат: "21 de febrero de 2026 - 09:39"
|
||||
static const QMap<QString, int> spanishMonths = {
|
||||
{"enero", 1}, {"febrero", 2}, {"marzo", 3}, {"abril", 4},
|
||||
{"mayo", 5}, {"junio", 6}, {"julio", 7}, {"agosto", 8},
|
||||
{"septiembre", 9}, {"octubre", 10}, {"noviembre", 11}, {"diciembre", 12}
|
||||
};
|
||||
|
||||
QRegularExpression re(R"((\d{1,2})\s+de\s+(\w+)\s+de\s+(\d{4})\s*-\s*(\d{2}):(\d{2}))");
|
||||
QRegularExpressionMatch match = re.match(dateStr);
|
||||
if (!match.hasMatch()) return {};
|
||||
|
||||
const int day = match.captured(1).toInt();
|
||||
const QString monthName = match.captured(2).toLower();
|
||||
const int year = match.captured(3).toInt();
|
||||
const int hour = match.captured(4).toInt();
|
||||
const int minute = match.captured(5).toInt();
|
||||
|
||||
const int month = spanishMonths.value(monthName, 0);
|
||||
if (month == 0) return {};
|
||||
|
||||
return QDateTime(QDate(year, month, day), QTime(hour, minute));
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isPayInputCardNumberScreen() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.hint == "Ingresar CBU, CVU o Alias") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isPayTransferConfirmScreen() {
|
||||
// Экран с именем получателя, Alias/CBU и кнопкой "Transferir"
|
||||
// Но без "Vas a transferir" (это уже финальный экран)
|
||||
bool hasTransferir = false;
|
||||
bool hasVasATransferir = false;
|
||||
bool hasAlias = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Transferir" && node.clickable) {
|
||||
hasTransferir = true;
|
||||
}
|
||||
if (node.contentDesc.startsWith("Vas a transferir")) {
|
||||
hasVasATransferir = true;
|
||||
}
|
||||
if (node.contentDesc.startsWith("Alias:")) {
|
||||
hasAlias = true;
|
||||
}
|
||||
}
|
||||
return hasTransferir && hasAlias && !hasVasATransferir;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isPayInputSumScreen() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc.contains(QString::fromUtf8("Cuánto vas a transferír"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isPayConfirmScreen() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc.startsWith("Vas a transferir")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScreenXmlParser::isPaySuccessScreen() {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Dinero enviado!") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parseRecipientNameFromConfirm() {
|
||||
// "Vas a transferir \na JOEL ARCHENTI"
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc.startsWith("Vas a transferir")) {
|
||||
QStringList lines = node.contentDesc.split('\n');
|
||||
if (lines.size() >= 2) {
|
||||
QString nameLine = lines[1].trimmed();
|
||||
// Убираем "a " в начале
|
||||
if (nameLine.startsWith("a ")) {
|
||||
nameLine = nameLine.mid(2);
|
||||
}
|
||||
return nameLine.trimmed();
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parsePaySuccessDateTime() {
|
||||
// Дата/время: "12/03/26 04:01" — содержит "/" и ":"
|
||||
for (const Node &node : m_nodes) {
|
||||
const QString desc = node.contentDesc.trimmed();
|
||||
if (desc.contains('/') && desc.contains(':') && desc.length() <= 20) {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString ScreenXmlParser::parsePaySuccessCoelsaId() {
|
||||
// "Id Coelsa" → следующий node содержит ID
|
||||
bool afterIdCoelsa = false;
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.contentDesc == "Id Coelsa") {
|
||||
afterIdCoelsa = true;
|
||||
continue;
|
||||
}
|
||||
if (afterIdCoelsa && !node.contentDesc.isEmpty()) {
|
||||
return node.contentDesc.trimmed();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Node ScreenXmlParser::findEditTextByHint(const QString &hint) {
|
||||
for (const Node &node : m_nodes) {
|
||||
if (node.className == "android.widget.EditText" && node.hint == hint) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Black
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <QDomElement>
|
||||
#include "android/xml/Node.h"
|
||||
#include "db/AccountInfo.h"
|
||||
#include "db/TransactionInfo.h"
|
||||
|
||||
namespace Black {
|
||||
|
||||
@ -64,6 +65,51 @@ public:
|
||||
// Парсит номер CVU (22-значный номер после content-desc="CVU")
|
||||
QString parseCVUNumber();
|
||||
|
||||
// Находит кнопку "Ver más" рядом с "Tu actividad" (для перехода на экран транзакций)
|
||||
Node findVerMasAfterTuActividad();
|
||||
|
||||
// Определяет экран загрузки транзакций (заголовок "Tu Actividad", но транзакций ещё нет)
|
||||
bool isTransactionLoadingScreen();
|
||||
|
||||
// Определяет экран списка транзакций (заголовок "Tu Actividad" + есть транзакции)
|
||||
bool isTransactionListScreen();
|
||||
|
||||
// Парсит все транзакции из content-desc ImageView элементов
|
||||
// Формат: "Transferencia\nDD de MES de YYYY - HH:MM\n$-1.857,\n00"
|
||||
QList<TransactionInfo> parseTransactionItems();
|
||||
|
||||
// Парсит дату на испанском: "21 de febrero de 2026 - 09:39" → QDateTime
|
||||
static QDateTime parseSpanishDate(const QString &dateStr);
|
||||
|
||||
// --- Экраны оплаты ---
|
||||
|
||||
// Экран ввода CBU/CVU/Alias (hint="Ingresar CBU, CVU o Alias")
|
||||
bool isPayInputCardNumberScreen();
|
||||
|
||||
// Экран подтверждения получателя (кнопка "Transferir" + имя получателя)
|
||||
bool isPayTransferConfirmScreen();
|
||||
|
||||
// Экран ввода суммы ("¿Cuánto vas a transferír" + EditText + "Continuar")
|
||||
bool isPayInputSumScreen();
|
||||
|
||||
// Экран финального подтверждения ("Vas a transferir" + "Transferir")
|
||||
bool isPayConfirmScreen();
|
||||
|
||||
// Экран успешного перевода ("Dinero enviado!")
|
||||
bool isPaySuccessScreen();
|
||||
|
||||
// Парсит имя получателя из "Vas a transferir \na ИМЯ"
|
||||
QString parseRecipientNameFromConfirm();
|
||||
|
||||
// Парсит дату/время с экрана успеха: "12/03/26 04:01"
|
||||
QString parsePaySuccessDateTime();
|
||||
|
||||
// Парсит Id Coelsa с экрана успеха
|
||||
QString parsePaySuccessCoelsaId();
|
||||
|
||||
// Находит EditText по hint
|
||||
Node findEditTextByHint(const QString &hint);
|
||||
|
||||
private:
|
||||
QList<Node> m_nodes;
|
||||
QDomElement m_xml;
|
||||
|
||||
@ -292,13 +292,9 @@ void CommonScript::updateTransactionData(
|
||||
|
||||
void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QString &appCode) {
|
||||
const ApplicationInfo app = ApplicationDAO::getApplication(deviceId, appCode);
|
||||
if (!app.bankProfileId.isEmpty()) {
|
||||
qDebug() << "[Ozon] bankProfileId already exists:" << app.bankProfileId;
|
||||
return;
|
||||
}
|
||||
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(app.currency.toUpper(), 643);
|
||||
const QStringList parts = app.fullName.split(' ', Qt::SkipEmptyParts);
|
||||
@ -316,9 +312,16 @@ void CommonScript::createBankProfileIfNeeded(const QString &deviceId, const QStr
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(deviceId);
|
||||
ns.setPayload(QJsonDocument(profileBody).toJson());
|
||||
ns.addExtra("app_id", app.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[Ozon] createBankProfileIfNeeded: postBankProfile done";
|
||||
|
||||
if (app.bankProfileId.isEmpty()) {
|
||||
ns.addExtra("app_id", app.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[Ozon] createBankProfileIfNeeded: postBankProfile done";
|
||||
} else {
|
||||
ns.addExtra("bank_profile_id", app.bankProfileId);
|
||||
ns.patchBankProfile();
|
||||
qDebug() << "[Ozon] createBankProfileIfNeeded: patchBankProfile done";
|
||||
}
|
||||
}
|
||||
|
||||
void CommonScript::stop() {
|
||||
|
||||
@ -174,7 +174,7 @@ void GetCardInfoScript::doStart() {
|
||||
|
||||
// ISO 4217 numeric currency codes
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(freshApp.currency.toUpper(), 643);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <QThread>
|
||||
|
||||
#include "adb/AdbUtils.h"
|
||||
#include "dao/AccountDAO.h"
|
||||
#include "dao/ApplicationDAO.h"
|
||||
#include "dao/DeviceDAO.h"
|
||||
#include "net/NetworkService.h"
|
||||
@ -114,32 +115,49 @@ void GetProfileInfoScript::doStart() {
|
||||
qWarning() << m_error;
|
||||
}
|
||||
|
||||
// Отправляем bank_profile на сервер если профиля ещё нет
|
||||
if (app.bankProfileId.isEmpty()) {
|
||||
const ApplicationInfo freshApp = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
// Отправляем bank_profile на сервер
|
||||
const ApplicationInfo freshApp = ApplicationDAO::getApplication(m_deviceId, m_appCode);
|
||||
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(freshApp.currency.toUpper(), 643);
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(freshApp.currency.toUpper(), 643);
|
||||
|
||||
const QStringList parts = fullName.split(' ', Qt::SkipEmptyParts);
|
||||
QJsonObject profileBody;
|
||||
profileBody["first_name"] = parts.value(0);
|
||||
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : "";
|
||||
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
||||
profileBody["bank_name"] = m_appCode;
|
||||
profileBody["phone_number"] = phone;
|
||||
profileBody["balance"] = QString::number(qRound64(freshApp.amount * 100));
|
||||
profileBody["state"] = (freshApp.status == "active") ? "enabled" : "disabled";
|
||||
profileBody["currency"] = currencyCode;
|
||||
const QStringList parts = fullName.split(' ', Qt::SkipEmptyParts);
|
||||
QJsonObject profileBody;
|
||||
profileBody["first_name"] = parts.value(0);
|
||||
profileBody["middle_name"] = parts.size() >= 3 ? parts.value(1) : "";
|
||||
profileBody["last_name"] = parts.size() >= 3 ? parts.value(2) : parts.value(1);
|
||||
profileBody["bank_name"] = m_appCode;
|
||||
profileBody["phone_number"] = phone;
|
||||
profileBody["balance"] = QString::number(qRound64(freshApp.amount * 100));
|
||||
profileBody["state"] = (freshApp.status == "active") ? "enabled" : "disabled";
|
||||
profileBody["currency"] = currencyCode;
|
||||
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(m_deviceId);
|
||||
ns.setPayload(QJsonDocument(profileBody).toJson());
|
||||
NetworkService ns;
|
||||
ns.setDeviceId(m_deviceId);
|
||||
ns.setPayload(QJsonDocument(profileBody).toJson());
|
||||
|
||||
if (freshApp.bankProfileId.isEmpty()) {
|
||||
ns.addExtra("app_id", freshApp.id);
|
||||
ns.postBankProfile();
|
||||
qDebug() << "[GetProfileInfo] postBankProfile done";
|
||||
} else {
|
||||
ns.addExtra("bank_profile_id", freshApp.bankProfileId);
|
||||
ns.patchBankProfile();
|
||||
qDebug() << "[GetProfileInfo] patchBankProfile done";
|
||||
}
|
||||
|
||||
// Отправляем данные аккаунтов на сервер если нет material_id
|
||||
const QList<AccountInfo> allAccounts = AccountDAO::getAccounts(m_deviceId, m_appCode);
|
||||
QList<QPair<AccountInfo, Node>> accountsToPost;
|
||||
for (const auto &acc : allAccounts) {
|
||||
if (acc.materialId.isEmpty()) {
|
||||
accountsToPost.append({acc, Node()});
|
||||
}
|
||||
}
|
||||
if (!accountsToPost.isEmpty()) {
|
||||
postAccountsData(accountsToPost);
|
||||
}
|
||||
|
||||
AdbUtils::tryToKillApplication(m_deviceId, app.package);
|
||||
|
||||
@ -143,7 +143,7 @@
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="12" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true"
|
||||
checked="false" clickaEble="false" enabled="true"
|
||||
focusable="false" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1756][1080,2229]" drawing-order="0" hint="">
|
||||
|
||||
BIN
assets/black/pay/pay_confirm.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
122
assets/black/pay/pay_confirm.xml
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,283][1080,1937]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Vas a transferir a JOEL ARCHENTI" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[280,322][800,501]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="$" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[378,815][406,883]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="500," checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[406,766][635,931]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="00" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[635,807][702,891]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="BANCO DE GALICIA Y BUENOS AIRES S.A.U." checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[161,1063][945,1118]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Alias:" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[293,1170][390,1225]" drawing-order="0" hint=""/>
|
||||
<node index="6" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc=" GRUTA.MADRID.ATRIO"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[390,1170][813,1225]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="7" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="CBU:" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[257,1278][344,1333]" drawing-order="0" hint=""/>
|
||||
<node index="8" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc=" 0070359630004039066690"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[344,1278][849,1333]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="9" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="$10.000,00 disponible"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[388,1674][692,1716]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="10" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Transferir" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[63,1743][1017,1874]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/pay/pay_input_card_number.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
134
assets/black/pay/pay_input_card_number.xml
Normal file
@ -0,0 +1,134 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" 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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,283][1080,1918]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[63,322][1017,832]" drawing-order="0" hint="">
|
||||
<node NAF="true" index="0" text="" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,401][1017,569]" drawing-order="0"
|
||||
hint="Ingresar CBU, CVU o Alias"/>
|
||||
<node index="1" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Continuar"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,648][1017,779]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Cuentas recientes"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[63,976][388,1031]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node NAF="true" index="2" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[938,990][1017,1043]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[63,1057][1017,1750]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[63,1057][1017,1750]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="RM ROCIO MICAELA MONTES BANCO NO INFORMADO"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,1057][1017,1215]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="GA Gabriel Alejandro del Roio BANCO NO INFORMADO"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,1215][1017,1372]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="AL Alexander Leonardo Nahuel Soto BANCO NO INFORMADO"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,1372][1017,1530]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="MS MICAELA SOLEDAD VARGAS BANCO NO INFORMADO"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,1530][1017,1687]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/pay/pay_input_sum.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
100
assets/black/pay/pay_input_sum.xml
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,283][1080,1447]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.ScrollView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="true" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,283][1080,1447]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="¿Cuánto vas a transferír a JOEL ARCHENTI?"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[191,322][889,501]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[63,661][1017,1447]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="0,00" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="true" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,819][1017,945]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="$10.000,00 disponible"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[292,1050][788,1118]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Continuar"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[63,1328][1017,1447]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/pay/pay_success.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
196
assets/black/pay/pay_success.xml
Normal file
@ -0,0 +1,196 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,2190]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,2190]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,2190]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,283]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás"
|
||||
checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0"
|
||||
hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,1924]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[66,315][255,504]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id=""
|
||||
class="android.widget.ImageView" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[240,0][1080,548]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Dinero enviado!"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[66,570][752,704]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Tu dinero fue transferido de manera exitosa. Recordá que puede tardar hasta 24 hs en impactar en la cuenta destino."
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[66,730][1014,911]" drawing-order="0"
|
||||
hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="JOEL ARCHENTI"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[63,1087][534,1176]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="$500,00"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[784,1087][1017,1176]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="6" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Black Wallet"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[63,1202][305,1263]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="7" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="12/03/26 04:01"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[719,1202][1017,1263]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="8" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Id Coelsa"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[63,1368][240,1428]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="9" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="1-30717458822-1773298911069rk-1"
|
||||
checkable="false" checked="false" clickable="false"
|
||||
enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[306,1368][1017,1428]"
|
||||
drawing-order="0" hint=""/>
|
||||
<node index="10" text="" resource-id=""
|
||||
class="android.widget.Button" package="app.blackwallet.ar"
|
||||
content-desc="Compartir " checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[116,1691][530,1835]" drawing-order="0" hint=""/>
|
||||
<node index="11" text="" resource-id=""
|
||||
class="android.widget.Button" package="app.blackwallet.ar"
|
||||
content-desc="Descargar" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false"
|
||||
bounds="[551,1691][965,1835]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node NAF="true" index="1" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true" focused="false"
|
||||
scrollable="false" long-clickable="false" password="false" selected="false"
|
||||
bounds="[456,2106][624,2274]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Inicio" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[88,2229][162,2350]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Enviar" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[251,2229][336,2350]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Recibir" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[729,2229][824,2350]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar" content-desc="Pagar" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[913,2229][992,2350]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/pay/pay_success_document.png
Normal file
|
After Width: | Height: | Size: 207 KiB |
72
assets/black/pay/pay_success_document.xml
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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.ImageView"
|
||||
package="app.blackwallet.ar" 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>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Cerrar" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/pay/pay_transfer_confirm.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
118
assets/black/pay/pay_transfer_confirm.xml
Normal file
@ -0,0 +1,118 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,136][1080,2337]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,1301][1080,2337]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="false"
|
||||
focused="false" scrollable="false" long-clickable="false"
|
||||
password="false" selected="false" bounds="[63,1354][1017,1954]"
|
||||
drawing-order="0" hint="">
|
||||
<node NAF="true" index="0" text="" resource-id=""
|
||||
class="android.view.View" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[954,1354][1017,1417]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="JOEL ARCHENTI"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[355,1417][725,1490]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Alias: "
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[275,1551][385,1608]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="GRUTA.MADRID.ATRIO"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[385,1551][805,1608]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="CBU: "
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[244,1650][343,1708]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="0070359630004039066690"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[343,1650][836,1708]" drawing-order="0" hint=""/>
|
||||
<node index="6" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="BANCO DE GALICIA Y BUENOS AIRES S.A.U."
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[143,1750][937,1808]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Transferir"
|
||||
checkable="false" checked="false" clickable="true" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[87,2090][993,2264]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Cerrar" checkable="false" checked="false"
|
||||
clickable="true" enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2400]"
|
||||
drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
93
assets/black/transactions_loading_screen.xml
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu Actividad" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[189,173][510,246]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,1221]" drawing-order="0" hint="">
|
||||
<node NAF="true" index="0" text="" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[53,394][1028,520]" drawing-order="0" hint="Buscar"/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,677][1080,1116]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,677][1080,1116]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Aún no tienes actividad Una vez que tengas actividad en tu cuenta la podrás ver reflejada acá."
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,677][1080,1116]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
BIN
assets/black/transactions_screen.png
Normal file
|
After Width: | Height: | Size: 300 KiB |
163
assets/black/transactions_screen.xml
Normal file
@ -0,0 +1,163 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<hierarchy rotation="0">
|
||||
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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.LinearLayout" package="app.blackwallet.ar"
|
||||
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="app.blackwallet.ar" 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="" class="android.widget.FrameLayout" package="app.blackwallet.ar"
|
||||
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,2400]" drawing-order="1" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View" package="app.blackwallet.ar"
|
||||
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.view.View" package="app.blackwallet.ar"
|
||||
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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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.view.View"
|
||||
package="app.blackwallet.ar" 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,283]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.Button"
|
||||
package="app.blackwallet.ar" content-desc="Atrás" checkable="false"
|
||||
checked="false" clickable="true" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[0,136][147,283]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" content-desc="Tu Actividad" checkable="false"
|
||||
checked="false" clickable="false" enabled="true" focusable="true"
|
||||
focused="false" scrollable="false" long-clickable="false" password="false"
|
||||
selected="false" bounds="[189,173][510,246]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
<node index="1" text="" resource-id="" class="android.widget.ScrollView"
|
||||
package="app.blackwallet.ar" content-desc="" checkable="false" checked="false"
|
||||
clickable="false" enabled="true" focusable="true" focused="false"
|
||||
scrollable="true" long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,0][1080,2400]" drawing-order="0" hint="">
|
||||
<node NAF="true" index="0" text="" resource-id=""
|
||||
class="android.widget.EditText" package="app.blackwallet.ar"
|
||||
content-desc="" checkable="false" checked="false" clickable="true"
|
||||
enabled="true" focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[53,394][1028,520]" drawing-order="0" hint="Buscar"/>
|
||||
<node index="1" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,625][1080,2400]" drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.view.View"
|
||||
package="app.blackwallet.ar" 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,625][1080,2400]"
|
||||
drawing-order="0" hint="">
|
||||
<node index="0" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de JOEL ARCHENTI 10 de marzo de 2026 - 16:23 $10.000, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,625][1080,814]" drawing-order="0" hint=""/>
|
||||
<node index="1" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia 21 de febrero de 2026 - 09:39 $-1.857, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,814][1080,950]" drawing-order="0" hint=""/>
|
||||
<node index="2" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia 21 de febrero de 2026 - 09:38 $-123, 45"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,950][1080,1087]" drawing-order="0" hint=""/>
|
||||
<node index="3" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de NOELIA ISABEL LEZCANO 21 de febrero de 2026 - 09:35 $123, 45"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1087][1080,1276]" drawing-order="0" hint=""/>
|
||||
<node index="4" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de NOELIA ISABEL LEZCANO 21 de febrero de 2026 - 09:34 $1.234, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1276][1080,1465]" drawing-order="0" hint=""/>
|
||||
<node index="5" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de NOELIA ISABEL LEZCANO 21 de febrero de 2026 - 09:34 $123, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1465][1080,1654]" drawing-order="0" hint=""/>
|
||||
<node index="6" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia 15 de febrero de 2026 - 07:07 $-56.030, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1654][1080,1790]" drawing-order="0" hint=""/>
|
||||
<node index="7" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia 14 de febrero de 2026 - 23:59 $-161.000, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1790][1080,1927]" drawing-order="0" hint=""/>
|
||||
<node index="8" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de Daniela Lorena Saucedo 14 de febrero de 2026 - 21:30 $10.000, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,1927][1080,2116]" drawing-order="0" hint=""/>
|
||||
<node index="9" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de Edgardo Sebastian Bravo 14 de febrero de 2026 - 21:29 $5.030, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,2116][1080,2305]" drawing-order="0" hint=""/>
|
||||
<node index="10" text="" resource-id="" class="android.widget.ImageView"
|
||||
package="app.blackwallet.ar"
|
||||
content-desc="Transferencia externa de JOAQUIN GABRIEL,LEONARDO 14 de febrero de 2026 - 21:28 $16.000, 00"
|
||||
checkable="false" checked="false" clickable="false" enabled="true"
|
||||
focusable="true" focused="false" scrollable="false"
|
||||
long-clickable="false" password="false" selected="false"
|
||||
bounds="[0,2305][1080,2400]" drawing-order="0" hint=""/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>
|
||||
@ -2,7 +2,7 @@
|
||||
list=ozon, black
|
||||
|
||||
[common]
|
||||
currencies=USD, KRW, AZN, RUB
|
||||
currencies=USD, ARS, RUB
|
||||
version=0.0.1
|
||||
|
||||
[db]
|
||||
@ -27,7 +27,7 @@ transactionUpdate=http://localhost:9999/api/v1/transaction/update
|
||||
|
||||
[black]
|
||||
android_package_name=app.blackwallet.ar
|
||||
currency=USD
|
||||
currency=ARS
|
||||
name=Black
|
||||
|
||||
[ozon]
|
||||
|
||||
34
main.cpp
@ -21,6 +21,7 @@
|
||||
#include "dao/SettingsDAO.h"
|
||||
#include "EventHandler.h"
|
||||
#include "net/NetworkService.h"
|
||||
#include "black/PayByCardScript.h"
|
||||
#include "ozon/PayByPhoneScript.h"
|
||||
#include "widget/loader/ErrorWindow.h"
|
||||
#include "widget/loader/LoaderWindow.h"
|
||||
@ -100,6 +101,33 @@ void startPayByPhoneTest() {
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void startBlackPayByCardTest() {
|
||||
QList<AccountInfo> accounts = AccountDAO::getAccountsByAppCode("black");
|
||||
if (accounts.isEmpty()) {
|
||||
qWarning() << "[BlackPayByCardTest] No black accounts found";
|
||||
return;
|
||||
}
|
||||
AccountInfo account = accounts.first();
|
||||
qDebug() << "[BlackPayByCardTest] Using account:" << account.id << account.deviceId << account.lastNumbers;
|
||||
|
||||
auto *thread = new QThread(nullptr);
|
||||
auto *worker = new Black::PayByCardScript(
|
||||
account,
|
||||
"0070359630004039066690",
|
||||
500,
|
||||
nullptr
|
||||
);
|
||||
worker->moveToThread(thread);
|
||||
QObject::connect(thread, &QThread::started, worker, &Black::PayByCardScript::start);
|
||||
QObject::connect(worker, &Black::PayByCardScript::finished, thread, &QThread::quit);
|
||||
QObject::connect(worker, &Black::PayByCardScript::finished, worker, &QObject::deleteLater);
|
||||
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
QObject::connect(worker, &Black::PayByCardScript::finishedWithResult, [](const QString &result) {
|
||||
qDebug() << "[BlackPayByCardTest] Result:" << result;
|
||||
});
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void startNetworkService(const QCoreApplication &app) {
|
||||
auto *paymentThread = new QThread;
|
||||
auto *networkService = new NetworkService;
|
||||
@ -229,7 +257,7 @@ int main(int argc, char *argv[]) {
|
||||
startNetworkService(app);
|
||||
startDeviceScreener(app);
|
||||
startEventHandler(app);
|
||||
// startPayByPhoneTest();
|
||||
// startBlackPayByCardTest();
|
||||
}, Qt::QueuedConnection);
|
||||
};
|
||||
|
||||
@ -260,7 +288,7 @@ int main(int argc, char *argv[]) {
|
||||
startNetworkService(app);
|
||||
startDeviceScreener(app);
|
||||
startEventHandler(app);
|
||||
// startPayByPhoneTest();
|
||||
// startBlackPayByCardTest();
|
||||
} else if (r == 0) {
|
||||
SettingsDAO::remove("api_key");
|
||||
showRegistration();
|
||||
@ -281,7 +309,7 @@ int main(int argc, char *argv[]) {
|
||||
startNetworkService(app);
|
||||
startDeviceScreener(app);
|
||||
startEventHandler(app);
|
||||
// startPayByPhoneTest();
|
||||
// startBlackPayByCardTest();
|
||||
} else if (result == 0) {
|
||||
SettingsDAO::remove("api_key");
|
||||
showRegistration();
|
||||
|
||||
@ -21,6 +21,8 @@
|
||||
#include "net/NetworkService.h"
|
||||
#include "birbank/GetLastDaysHistoryBirbankScript.h"
|
||||
#include "birbank/LoginAndCheckAccountsBirbankScript.h"
|
||||
#include "black/GetLastTransactionsScript.h"
|
||||
#include "black/LoginAndCheckAccountsScript.h"
|
||||
#include "ozon/GetLastTransactionsScript.h"
|
||||
#include "ozon/LoginAndCheckAccountsScript.h"
|
||||
#include "rshb/GetLastDaysHistoryScript.h"
|
||||
@ -29,6 +31,7 @@
|
||||
#include "toss/LoginAndCheckAccountsTossScript.h"
|
||||
#include "ziraat/GetLastDaysHistoryZiraatScript.h"
|
||||
#include "ziraat/LoginAndCheckAccountsZiraatScript.h"
|
||||
#include "black/PayByCardScript.h"
|
||||
#include "ozon/PayByCardScript.h"
|
||||
#include "ozon/PayByPhoneScript.h"
|
||||
#include "rshb/PayByPhoneScript.h"
|
||||
@ -254,14 +257,19 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
||||
}
|
||||
|
||||
if (newStatus != EventStatus::Error) {
|
||||
const AccountInfo account = AccountDAO::getAccountById(event.accountId);
|
||||
const QMap<QString, int> currencyCodes = {
|
||||
{"RUB", 643}, {"USD", 840}, {"KRW", 410}, {"AZN", 944}, {"ARS", 32}
|
||||
};
|
||||
const int currencyCode = currencyCodes.value(account.currency.toUpper(), 643);
|
||||
|
||||
QJsonValue taskData;
|
||||
if (event.type == EventType::FetchProfile) {
|
||||
const AccountInfo account = AccountDAO::getAccountById(event.accountId);
|
||||
EventDAO::updateEventAmount(event.id, account.amount);
|
||||
QJsonObject obj;
|
||||
obj["bank_account_id"] = QString();
|
||||
obj["amount"] = static_cast<int>(account.amount * 100);
|
||||
obj["currency"] = 643; // RUB
|
||||
obj["currency"] = currencyCode;
|
||||
taskData = obj;
|
||||
} else if (event.type == EventType::FetchTransactions) {
|
||||
QList<TransactionInfo> txList = TransactionDAO::getTransactionsWithinHours(event.accountId, 24);
|
||||
@ -270,7 +278,7 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
||||
QJsonObject txObj;
|
||||
txObj["bank_transaction_id"] = tx.bankTrExternalId.isEmpty() ? QJsonValue(QJsonValue::Null) : QJsonValue(tx.bankTrExternalId);
|
||||
txObj["amount"] = static_cast<int>(tx.amount * 100);
|
||||
txObj["currency"] = 643; // RUB
|
||||
txObj["currency"] = currencyCode;
|
||||
txObj["transaction_type"] = (tx.type == TransactionType::Phone) ? "top-up" : "bank";
|
||||
txObj["bank_participator_id"]= tx.phone;
|
||||
txObj["status"] = tx.status == TransactionStatus::Complete ? "completed" : (tx.status == TransactionStatus::Wait ? "progress" : "completed");
|
||||
@ -297,11 +305,11 @@ void EventHandler::updateEventThread(const QString &key, const EventInfo &event,
|
||||
} 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();
|
||||
const QString txType = taskJson["body"].toObject()["type"].toString();
|
||||
|
||||
QJsonObject obj;
|
||||
obj["amount"] = -static_cast<int>(event.amount * 100);
|
||||
obj["currency"] = 643;
|
||||
obj["currency"] = currencyCode;
|
||||
obj["transaction_type"] = txType.isEmpty() ? "top-up" : txType;
|
||||
obj["bank_participator_id"]= event.phone;
|
||||
obj["status"] = "completed";
|
||||
@ -389,6 +397,7 @@ void EventHandler::startThreadForTask(const AccountInfo &account, const EventInf
|
||||
else if (appCode == "rshb") setup(new Rshb::LoginAndCheckAccountsScript(deviceId, appCode));
|
||||
else if (appCode == "toss") setup(new LoginAndCheckAccountsTossScript(deviceId, appCode));
|
||||
else if (appCode == "ziraat") setup(new LoginAndCheckAccountsZiraatScript(deviceId, appCode));
|
||||
else if (appCode == "black") setup(new Black::LoginAndCheckAccountsScript(deviceId, appCode));
|
||||
else qWarning() << "[EventHandler] FETCH_PROFILE: unknown appCode:" << appCode;
|
||||
}
|
||||
|
||||
@ -398,6 +407,7 @@ void EventHandler::startThreadForTask(const AccountInfo &account, const EventInf
|
||||
else if (appCode == "rshb") setup(new Rshb::GetLastDaysHistoryScript(account));
|
||||
else if (appCode == "toss") setup(new GetLastDaysHistoryTossScript(account));
|
||||
else if (appCode == "ziraat") setup(new GetLastDaysHistoryZiraatScript(account));
|
||||
else if (appCode == "black") setup(new Black::GetLastTransactionsScript(deviceId, appCode));
|
||||
else qWarning() << "[EventHandler] FETCH_TRANSACTIONS: unknown appCode:" << appCode;
|
||||
}
|
||||
|
||||
@ -406,11 +416,12 @@ void EventHandler::startThreadForTask(const AccountInfo &account, const EventInf
|
||||
|
||||
// Определяем тип транзакции из JSON задачи
|
||||
const QJsonObject taskJson = QJsonDocument::fromJson(event.json.toUtf8()).object();
|
||||
const QString txType = taskJson["body"].toObject()["transaction_type"].toString();
|
||||
const QString txType = taskJson["body"].toObject()["type"].toString();
|
||||
|
||||
if (txType == "bank") {
|
||||
// Перевод по номеру карты
|
||||
if (appCode == "ozon") setup(new Ozon::PayByCardScript(account, event.phone, event.amount));
|
||||
if (appCode == "ozon") setup(new Ozon::PayByCardScript(account, event.phone, event.amount));
|
||||
else if (appCode == "black") setup(new Black::PayByCardScript(account, event.phone, event.amount));
|
||||
else qWarning() << "[EventHandler] CREATE_TRANSACTION bank: unknown appCode:" << appCode;
|
||||
} else {
|
||||
// Перевод по номеру телефона (top-up)
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "ozon/LoginAndCheckAccountsScript.h"
|
||||
#include "ozon/GetProfileInfoScript.h"
|
||||
#include "ozon/GetCardInfoScript.h"
|
||||
#include "black/GetLastTransactionsScript.h"
|
||||
#include "ozon/GetLastTransactionsScript.h"
|
||||
#include "toss/LoginAndCheckAccountsTossScript.h"
|
||||
#include "black/LoginAndCheckAccountsScript.h"
|
||||
@ -291,10 +292,9 @@ AccountSettingsWindow::AccountSettingsWindow(
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Проверить транзакции?"));
|
||||
msgBox.setText(
|
||||
"Запустится скрипт получения последних транзакций из " + m_applicationInfo.name +
|
||||
"Запустится скрипт получения транзакций из " + m_applicationInfo.name +
|
||||
". Окно с настройками закроется.");
|
||||
QPushButton *runBtn = msgBox.addButton(tr("За 24 часа"), QMessageBox::AcceptRole);
|
||||
QPushButton *last5Btn = msgBox.addButton(tr("Последние 5"), QMessageBox::AcceptRole);
|
||||
QPushButton *runBtn = msgBox.addButton(tr("Проверить"), QMessageBox::AcceptRole);
|
||||
QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||||
msgBox.setDefaultButton(cancelBtn);
|
||||
msgBox.setModal(true);
|
||||
@ -302,9 +302,6 @@ AccountSettingsWindow::AccountSettingsWindow(
|
||||
if (msgBox.clickedButton() == runBtn) {
|
||||
startGetLastTransactions(m_applicationInfo.code);
|
||||
close();
|
||||
} else if (msgBox.clickedButton() == last5Btn) {
|
||||
startGetLastTransactions(m_applicationInfo.code, 5);
|
||||
close();
|
||||
}
|
||||
});
|
||||
|
||||
@ -455,16 +452,25 @@ void AccountSettingsWindow::startGetCardInfo(const QString &appCode) {
|
||||
}
|
||||
|
||||
void AccountSettingsWindow::startGetLastTransactions(const QString &appCode, int maxCount) {
|
||||
if (appCode != "ozon") return;
|
||||
|
||||
QThread *thread = new QThread(nullptr);
|
||||
auto *worker = new Ozon::GetLastTransactionsScript(m_deviceId, appCode, maxCount, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Ozon::GetLastTransactionsScript::start);
|
||||
connect(worker, &Ozon::GetLastTransactionsScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Ozon::GetLastTransactionsScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
thread->start();
|
||||
if (appCode == "ozon") {
|
||||
QThread *thread = new QThread(nullptr);
|
||||
auto *worker = new Ozon::GetLastTransactionsScript(m_deviceId, appCode, maxCount, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Ozon::GetLastTransactionsScript::start);
|
||||
connect(worker, &Ozon::GetLastTransactionsScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Ozon::GetLastTransactionsScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
thread->start();
|
||||
} else if (appCode == "black") {
|
||||
QThread *thread = new QThread(nullptr);
|
||||
auto *worker = new Black::GetLastTransactionsScript(m_deviceId, appCode, nullptr);
|
||||
worker->moveToThread(thread);
|
||||
connect(thread, &QThread::started, worker, &Black::GetLastTransactionsScript::start);
|
||||
connect(worker, &Black::GetLastTransactionsScript::finished, thread, &QThread::quit);
|
||||
connect(worker, &Black::GetLastTransactionsScript::finished, worker, &QObject::deleteLater);
|
||||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||
thread->start();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountSettingsWindow::sendAppStatus(const QString &deviceId, const QString &code, const QString &status) {
|
||||
|
||||